tabletop-commander/md/help articles/How to use ttcMD.md
2024-08-21 17:35:44 -06:00

416 lines
17 KiB
Markdown

---
title: How to use ttcMD
author: Emmaline Autumn
date: March 14th, 2024
updated: August 21st, 2024
---
# Table of Contents
- [Table of Contents](#table-of-contents)
- [What even is ttcMD?](#what-even-is-ttcmd)
- [Enhanced Standard Elements](#enhanced-standard-elements)
- [Links](#links)
- [Tables](#tables)
- [Custom Elements](#custom-elements)
- [Pop-outs](#pop-outs)
- [Block-level Elements](#block-level-elements)
- [Accordions](#accordions)
- [Card](#card)
- [Block](#block)
- [Grid](#grid)
- [Query Elements](#query-elements)
- [Resolver](#resolver)
- [On-demand Resolver](#on-demand-resolver)
- [Query Block Template](#query-block-template)
- [Query Block](#query-block)
---
This help article contains a lot of examples of how to use the syntax of ttcMD and what they look like when put into practice. It's very information dense and also a bit chaotic with all of the examples, so please feel free to use the table of contents to find the specific section you are looking for.
## What even is ttcMD?
ttcMD is a flavor of markdown that has been specifically designed to use with [ttcQuery](/help/ttcQuery.md). It has all of the basic syntax of [markdown](https://www.markdownguide.org/cheat-sheet/), but also includes Tables, basic Fenced Code Blocks and a slew of custom elements and styling annotations.
One thing to note, however, is that ttcMD is *not* standard markdown. It does not generate valid markup for just about any element, and as such it will not be released in any scope wider than inside TTC itself. One could more accurately call it a layout language than actual markdown.
---
## Enhanced Standard Elements
This section will cover all of the enhancements that are added for basic markdown elements
---
### Links
You can use the typical link syntax `[link name](/link/location)` but there are a few presets that allow you to style them to look a bit nicer.
**Primary Button:**
Prefix the link name with `~~button` to create a button.
`[~~button link name](#links)` produces:
[~~button link name](#links)
**Call to Action:**
Prefix the link name with `~~cta` to create a modestly styled button/call to action.
`[~~cta link name](#links)` produces:
[~~cta link name](#links)
---
### Tables
Generally tables will only be as wide as their content needs. To make a table take up the full width, you can use this syntax:
[][][]
With a header:
```
| Table | Header | Row |
| <---- | ------ | --> |
| Table | Body | Row 1 |
| Table | Body | Row 2 |
| Table | Body | Row 3 |
```
Without a header:
```
| <---- | ------ | --> |
| Table | Body | Row 1 |
| Table | Body | Row 2 |
| Table | Body | Row 3 |
```
As you can see, it makes use of the default separator line and uses `<` and `>` to denote that it should be full width. Note that the length of the dashes does not matter, all that matters is that the separator line starts with `| <-` and ends with `-> |`.
[[!2
Additionally, you can specify if a column is meant to be centered by using `^` inside the separator. For example, `| <--- | -^- | ---> |` will make the second column of all table rows centered. Its positioning within the column doesn't matter.
]]
/[]
There is also an additional feature of adding a table footer by using a second separator. This second separator does not have any affect on the width or centering of the footer columns.
**Examples:**
[][][]
Normal table:
| Table | Header | Row |
| ---- | ------ | -- |
| Table | Body | Row 1 |
| Table | Body | Row 2 |
| Table | Body | Row 3 |
Full width:
| <---- | ----- | --> |
| Table | Body | Row 1 |
| Table | Body | Row 2 |
| Table | Body | Row 3 |
Full width with a centered body column
| Table | Header | Row |
| <---- | ---^-- | --> |
| Table | Body | Row 1 |
| Table | Body | Row 2 |
| Table | Body | Row 3 |
/[]
---
## Custom Elements
This section will cover the specific elements custom built for Tabletop Commander.
---
### Pop-outs
Pop-outs, or popovers, are the little cards that "pop out" when you hover over an item.
The syntax is thus: `^[pop-out title]<<pop-out content>>`. The pop-out title will be rendered inline, just like a link, and the content will be included in the pop-out itself. Content can also include inline markdown elements as well, so you can format the content within as well.
Example:
This syntax `^[This is my favorite image]<<*Goofy!* ![goofy](https:///example.com/image.png)>>` will produce this element: ^[This is my favorite image]<<*Goofy!* ![goofy](https://yt3.ggpht.com/a/AATXAJwbIW0TwEhqdT2ZPeSB1AtdtWD2ZXam80oijg=s900-c-k-c0xffffffff-no-rj-mo)>>
Note: currently, only inline elements are available, so formatting is limited
---
## Block-level Elements
Block-level elements have a slightly different syntax than the single-line and inline elements we've seen so far. In order to use block-level elements, they *must* be formatted correctly, including the empty lines. As a general rule, you cannot nest block-level elements within themselves, but you can nest different block-level elements within it.
---
### Accordions
Accordions are when you can click an item to expand it to show additional information.
Syntax:
[][][]
```
[accordion title]
whatever markdown you desire, including non-accordion block elements
[/accordion]
```
[accordion this is what an accordion looks like]
This is the body of the accordion.
As you can see, I can do normal markdown in here.
I can include a [link](#accordions), or *italic* and **bold** text.
[[
I can even include a card, like this one
]]
[/accordion]
[[!
[accordion Accordions look great stacked!]
Conveniently group data together in stacked accordions
[/accordion]
[accordion It's great for saving a lot of space]
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt, nesciunt repellat ipsa unde, reiciendis nostrum molestiae necessitatibus tempore ea neque quae nihil veritatis autem recusandae nam eaque facilis rerum quos nisi quam temporibus! Quasi nostrum iste praesentium consequatur a itaque. Eaque temporibus aliquam ex tempore rem iste at in itaque?
Sint iure nam maiores dolorem dolor officia omnis eos. Odio, corporis sunt totam accusamus, ut necessitatibus molestias molestiae error numquam suscipit quas obcaecati aspernatur qui atque optio unde minima hic autem saepe, nihil debitis cumque vel. Placeat magnam nesciunt sequi suscipit provident dolore commodi corrupti, porro facere assumenda, distinctio magni?
Suscipit illum temporibus sequi! Nulla excepturi hic tempore nihil deleniti. Hic tempora debitis iure inventore, dolores facilis, sequi dolorem veritatis corrupti dignissimos voluptate consequuntur quaerat quidem totam, odio odit quisquam harum? Consequuntur, doloribus. Necessitatibus rem quidem, saepe eum nobis, tenetur nihil iusto debitis incidunt repudiandae molestiae, corrupti rerum deleniti. Numquam.
Recusandae iusto distinctio cupiditate quam in aliquid cum ipsa et cumque adipisci voluptatum fuga expedita voluptate assumenda error hic, doloribus beatae libero animi ratione aut modi? Ex reprehenderit facere explicabo quo iusto ad minima nihil. Minus magni quidem architecto at fugiat quo, ab ipsa tenetur facilis, optio iusto deleniti illo.
Eaque dicta iusto reiciendis natus qui excepturi nesciunt asperiores totam nam, reprehenderit perspiciatis amet beatae libero. Laudantium labore aliquam eveniet ab minima ut sunt laboriosam consequuntur alias impedit magnam voluptatem ea at, soluta nisi tenetur rem officia rerum facilis perferendis voluptas nulla incidunt. Sequi, facere vero doloremque saepe magni consequatur!
Veritatis quod eveniet expedita quae explicabo, nobis enim reiciendis repellat maiores accusantium id doloribus magni dolorem quis qui illum perferendis repudiandae nisi aut maxime doloremque nulla quam fuga aspernatur? Unde sapiente nisi hic, voluptatibus facilis rem omnis saepe asperiores numquam vitae perferendis eligendi nihil temporibus! Commodi voluptatibus eos perspiciatis quaerat?
Natus impedit quasi voluptates libero vel dicta totam vitae expedita nulla, saepe doloremque veniam, beatae molestiae quod! Dolores, doloribus est! Iste asperiores fuga, ab esse, aliquid enim laborum delectus rem doloribus earum voluptates? Quibusdam dolorum esse voluptatem quas nisi aspernatur? Accusamus est totam recusandae rerum nisi accusantium dignissimos reprehenderit sapiente!
Debitis ratione molestiae veniam iure quibusdam quae, eos voluptate adipisci! Tempore blanditiis illum optio ea debitis praesentium, iure pariatur neque nisi facere, unde velit eos expedita dolores fugiat! Accusamus iusto amet perferendis adipisci natus iure sunt assumenda aut, esse tempore provident, repudiandae officiis dolor deserunt cumque aspernatur unde voluptatum suscipit!
Asperiores maiores expedita qui officia laudantium eos molestiae iusto obcaecati, odio numquam cumque dolores laborum consequatur voluptatem dolore voluptatum corrupti repudiandae doloribus quisquam? Ratione maxime aut molestiae rem suscipit, ab animi corrupti ullam deleniti aliquam, doloremque nemo ducimus quisquam laboriosam nobis debitis! Corporis maxime atque cum nulla consequatur asperiores facere!
Veniam necessitatibus molestiae explicabo nam vel ipsam non sapiente tempora quo nesciunt ullam, accusamus illo! Voluptatem tempore, quos magnam vitae similique deleniti mollitia. Totam, eligendi corrupti. Commodi ullam tenetur, quo ipsum, quam reiciendis eaque assumenda voluptates consequatur, aliquam perferendis praesentium beatae esse dignissimos iste quidem voluptatibus molestiae qui culpa exercitationem?
[/accordion]
[accordion And can be very useful for secret items in games]
Let's just pretend that this accordion holds a poker hand instead of a random picture.
You'll never believe me when I tell you that this legitimately is one of my favorite images of all time.
![goofy](https://yt3.ggpht.com/a/AATXAJwbIW0TwEhqdT2ZPeSB1AtdtWD2ZXam80oijg=s900-c-k-c0xffffffff-no-rj-mo)
[/accordion]
]]
/[]
---
### Card
Cards are just neat boxes. They can hold any markdown within them, but not other cards (it looks bad).
[][][]
```
[[
Card text!
This is a real wild thing! Look, an accordion!
[accordion Hello, am accordion!]
super secret! I'll never tell!
[/accordion]
]]
```
[[
Card text!
This is a real wild thing! Look, an accordion!
[accordion Hello, am accordion!]
Never gonna give you up,\n
Never gonna let you down,\n
Never gonna run around\n
And desert you.
Never gonna make you cry,\n
Never gonna say good-bye,\n
Never gonna tell a lie\n
And hurt you.
[/accordion]
]]
[[2
Additionally, you can specify a number after the opening brackets (`[[2 ... ]]`) to specify how many grid columns the card should cover, just like this card!
]]
/[]
---
### Block
[][][]
An unstyled version of the card is the Block block. This is for grouping items in a grid that should be in the same cell. Same syntax, but you simply add an exclamation point after the opening brackets
```
[[!
Any markup :D
]]
```
[[!
Normally all of these paragraphs would end up in their own cell. However, since I put them in a block, they will be kept together.
And it's not just paragraphs that you can group together, you can use any other ttcMD element, like this picture!
![goofy](https://yt3.ggpht.com/a/AATXAJwbIW0TwEhqdT2ZPeSB1AtdtWD2ZXam80oijg=s900-c-k-c0xffffffff-no-rj-mo)
]]
[[!2
Additionally, you can specify a number after the opening brackets (`[[!2 ... ]]`) to specify how many grid columns the block should cover, just like this block!
]]
/[]
---
### Grid
Grid blocks give you access to basic grid layouts. You define the number of columns in the grid by using a number of matching brackets. On smaller screens or containers, grids are ignored, turned into a single column.
[][][]
[[
```
[][][]
This will make three columns, just like how this is laid out right now.
Each element will get its own cell in the grid.
So each of these paragraphs will end up in a separate column.
/[]
```
]]
[[
```
[][]
This will make two columns
[[
Each column can use a different element
]]
/[]
```
]]
[[
This card will end up in the third column...
]]
[[
... but since there isn't enough for this one, it will automatically get moved to the next row.
]]
/[]
---
## Query Elements
The following elements are used in combination with ttcQuery. These are definitely more advanced. If you understand generally what "dot notation" is in programming, then it will be a lot easier, but don't let that deter you. Once you understand what it is, you can come back to this and be able to create really cool layouts!
Query elements (aside for the on-demand resolver) are calculated before parsing the markdown. Will that matter to you? Probably not, but could be necessary as you think about how you are writing your query elements.
---
### Resolver
The resolver is the basic element that allows you to get data, but it has a lot of functionality to it. It has not been fully implemented yet
Syntax: `??<<List -> QueryValue>>`
If you've read the ttcQuery docs, you'll know that the `List` type means that you can input any number of `QueryValues` in this element. When the resolver runs, it runs each `QueryValue` from left to right. The last `QueryValue` to run is what gets rendered, but you have access to previous values through their index by using the `$#` variables.
As `QueryValues` are capable of arithmetic, you can quite easily do simple math inline, though it's unfortunately not quite as simple as just writing an equation. Each `QueryValue` can only do one arithmetic operation. This is to prevent performance issues with parsing arbitrary calculations. So, if you wanted to get the average of the values of 1, 2, 3 and 4, the query would look like this: `??<<1+2,3+4,$0+$1,$2/4>>` which will result in the value ??<<1+2,3+4,$0+$1,$2/4>>. Arithmetic will fail if a value provided is not a number and will render a message in the markdown.
If the resolver results in a list of items, it will list all of them together, separated by commas.
Let's say you want to get the the result of rolling a dice field. You would simply write `??<<_.path.to.dice,$0.roll>>` and get the result of the dice roll like this: ??<<_.path.to.dice,$0.roll>>. This will roll the dice when the markdown is rendered, which means it only happens once. If you want to reroll the dice, you either need to reload the markdown by closing the viewer and reopening it, or you need to use an On-demand Resolver.
---
### On-demand Resolver
This works very similarly to the normal resolver, but when it renders it will have a button that you can press. When you press it, it recalculates its value. This is very useful for dice and decks of cards. It has not been fully implemented yet
Here's the syntax: `??[Text](Template)<<List::QueryValue>>`. Template is a basic string that has access to all values of the resolver using the `$#` variables. If template is left blank, the value that the resolver finally reaches will be rendered. In lieu of a template, you can also have it render the display of a field if it has one. Text is the text that will be rendered in the button. If not provided, the button will simply same "Resolve."
[][]
[[
To use the dice as an example again, here's how you would do that: `??[Roll 2d6](Rolling $0, you got: $1)<<_.path.to.dice,$0.roll>>`
??[Roll 2d6](Rolling $0, you got: $1)<<_.path.to.dice,$0.roll>>
]]
[[
For drawing a card and having it show the card's display: `??[]()<<_.path.to.deck,$0.draw,$1.display>>`
]]
/[]
---
### Query Block Template
The Query Block Template is the keystone of the query elements. It allows you to query for an object and use that object as the root for rendering a block of markdown. It has not been fully implemented yet.
[][][]
Syntax:
```
??<<QueryValue>>[[
Any markdown.
]]
```
/[]
While in a Query Block Template, all resolvers will use the queried value as the root `_` variable. If the original query returns multiple values, it will render the markdown for each result. This is what makes it so useful. When you want to render your 40k army list, you can do so with very little markdown.
---
### Query Block
Similar to the Query Block Template, the query block collects the values of the query and passes it to the markdown inside of it. However, instead of rendering the whole block, it instead renders the markdown a single time. It has not been fully implemented yet
Unlike the Query Block Template, it does not change the `_` variable to the queried value. For resolvers to work with the queried data, you need to access it with the `$$` variable. `$$` will be iterated over and will act similar to the Query Block Template, but on a per-line basis, meaning that if a line contains the `$$` variable, it will render that line of markdown for each result of the query. This is primarily useful for something like a List or a Table.
Syntax:
```
Still working on the syntax, it's difficult coming up with all of this on the fly when it needs to be unique and easily parsed
```