Advanced styling

The show rule

Advanced styling comes with another rule. The _`show` rule_.

Now please compare the source code and the output.

#show "Be careful": strong[Play]

This is a very powerful thing, sometimes even too powerful.
Be careful with it.

#show "it is holding me hostage": text(green)[I'm fine]

Wait, what? I told you "Be careful!", not "Play!".

Help, it is holding me hostage.
Rendered image

Now a bit more serious

Show rule is a powerful thing that takes a _selector_
and what to apply to it. After that it will apply to
all elements it can find.

It may be extremely useful like that:

#show emph: set text(blue)

Now if I want to _emphasize_ something,
it will be both _emphasized_ and _blue_.
Isn't that cool?
Rendered image

About syntax

Sometimes show rules may be confusing. They may seem very diverse, but in fact they all are quite the same! So

// actually, this is the same as
// redify = text.with(red)
// `with` creates a new function with this argument already set
#let redify(string) = text(red, string)

// and this is the same as
// framify = rect.with(stroke: orange)
#let framify(object) = rect(object, stroke: orange)

// set default color of text blue for all following text
#show: set text(blue)

Blue text.

// wrap everything into a frame
#show: framify

Framed text.

// it's the same, just creating new function that calls framify
#show: a => framify(a)

Double-framed.

// apply function to `the`
#show "the": redify
// set text color for all the headings
#show heading: set text(purple)

= Conclusion

All these rules do basically the same!
Rendered image

Blocks

One of the most important usages is that you can set up all spacing using blocks. Like every element with text contains text that can be set up, every block element contains blocks:

Text before
= Heading
Text after

#show heading: set block(spacing: 0.5em)

Text before
= Heading
Text after
Rendered image

Selector

So show rule can accept _selectors_.

There are lots of different selector types,
for example

- element functions
- strings
- regular expressions
- field filters

Let's see example of the latter:

#show heading.where(level: 1): set align(center)

= Title
== Small title

Of course, you can set align by hand,
no need to use show rules
(but they are very handy!):

#align(center)[== Centered small title]
Rendered image

Custom formatting

Let's try now writing custom functions.
It is very easy, see yourself:

// "it" is a heading, we take it and output things in braces
#show heading: it => {
  // center it
  set align(center)
  // set size and weight
  set text(12pt, weight: "regular")
  // see more about blocks and boxes
  // in corresponding chapter
  block(smallcaps(it.body))
}

= Smallcaps heading
Rendered image

Setting spacing

TODO: explain block spacing for common elements

Formatting to get an "article look"

#set page(
  // Header is that small thing on top
  header: align(
    right + horizon,
    [Some header there]
  ),
  height: 12cm
)

#align(center, text(17pt)[
  *Important title*
])

#grid(
  columns: (1fr, 1fr),
  align(center)[
    Some author \
    Some Institute \
    #link("mailto:some@mail.edu")
  ],
  align(center)[
    Another author \
    Another Institute \
    #link("mailto:another@mail.edu")
  ]
)

Now let's split text into two columns:

#show: rest => columns(2, rest)

#show heading.where(
  level: 1
): it => block(width: 100%)[
  #set align(center)
  #set text(12pt, weight: "regular")
  #smallcaps(it.body)
]

#show heading.where(
  level: 2
): it => text(
  size: 11pt,
  weight: "regular",
  style: "italic",
  it.body + [.],
)

// Now let's fill it with words:

= Heading
== Small heading
#lorem(10)
== Second subchapter
#lorem(10)
= Second heading
#lorem(40)

== Second subchapter
#lorem(40)
Rendered image