Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beamer alertblock and exampleblock usage #7278

Closed
MrSauna opened this issue May 13, 2021 · 16 comments
Closed

Beamer alertblock and exampleblock usage #7278

MrSauna opened this issue May 13, 2021 · 16 comments

Comments

@MrSauna
Copy link

MrSauna commented May 13, 2021

This is an enchantment request.

pandoc 2.13

I want an easy way to use beamer's alertblock and exampleblock.

I'm using pandoc \w pandoc -t beamer slides.md -o slides.pdf

The special blocks can be used with latex like

\begin{exampleblock}{example}
text in example
\end{exampleblock}

\begin{alertblock}{alert}
text in alert
\end{alertblock}

resulting in
image

I'm suggesting either syntax like

::: exampleblock
#### block title

text in block
:::

or

#### block title {.example}

text in block

or similar to ease the use of these special formatted blocks.

@cagix
Copy link
Contributor

cagix commented May 13, 2021

i'd love to see this in pandoc, too.

maybe this could be provided in a more general way:

::: xxx
...
:::

could be translated into \begin{xxx} ... \end{xxx}.


however, you can achive this using a simple lua filter:

function Div(el)
    if  el.classes[1] and  el.classes[1] == "xxx" then
        return {pandoc.RawBlock("latex", "\\begin{xxx}")} .. el.content .. {pandoc.RawBlock("latex", "\\end{xxx}")}
    end
end

have a look at https://github.com/cagix/pandoc-lecture/blob/master/filters/tex.lua :)

@mb21
Copy link
Collaborator

mb21 commented May 13, 2021

Sounds a bit like #2106 ?

@cagix
Copy link
Contributor

cagix commented May 13, 2021

yeah, this topic comes up again and again :)

@cagix
Copy link
Contributor

cagix commented May 13, 2021

I can't find the discussion right now. But there was a longer discussion on this very topic earlier. The problem was IIRC that you could run into LaTeX problems if you simply translated all divs and spans into corresponding LaTeX environments or commands and the respective definitions were not available. Pandoc can't guarantee that, though. If I remember correctly, this is exactly the reason why the request was rejected earlier.

@MrSauna
Copy link
Author

MrSauna commented May 13, 2021

I'm a novice pandoc user so I don't know how to proceed but I have two points

pandoc manual:

CUSTOM STYLES
Custom styles can be used in the docx and ICML formats.

which is used in the example like

::: {custom-style="Poetry"}
| A Bird came down the Walk---
| He did not know I saw---
:::

which could be used for this purpose BUT

I feel like alertblock and exampleblock are fundamental to beamer so they should get special handling for example with the

::: alertblock
#### Alert
alert text
:::

... syntax

@cagix
Copy link
Contributor

cagix commented May 13, 2021

@MrSauna You could paste the snippet above into a text file and replace the "xxx" with "alertblock". Add an option to your call to pandoc: -L <yourfile> ... This should do the trick :)

@MrSauna
Copy link
Author

MrSauna commented May 13, 2021

with divfilter.lua

function Div(el)
    if  el.classes[1] and  el.classes[1] == "alertblock" then
        return {pandoc.RawBlock("latex", "\\begin{alertblock}")} .. el.content .. {pandoc.RawBlock("latex", "\\end{alertblock}")}
    end
end

the script breaks with

::: alertblock
### alerttitle
alert text
:::

with the output

Error producing PDF.
! LaTeX Error: \begin{block} on input line 109 ended by \end{alertblock}.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.109 \end{frame}

it doesn't like inner beamer blocks apparently and

::: alertblock
alert text
:::

without the third level title its not really interesting because the title holds the colored part of the block

@MrSauna
Copy link
Author

MrSauna commented May 13, 2021

Oh right it's a two argument begin command
\begin{alertblock}{<the actual title>}
so this whole problem is a bit more complicated

@cagix
Copy link
Contributor

cagix commented May 13, 2021

right, sorry, overlooked this in your original comment. so you could work with something like

::: {.alertblock title="my title"} 
... 
:::

the filter would need to select the attributes too, i.e. something like (not tested):

function Div(el)
    if  el.classes[1] and  el.classes[1] == "alertblock" then
        return {pandoc.RawBlock("latex", "\\begin{alertblock}{" .. el.attributes["title"] .. "}")} .. el.content .. {pandoc.RawBlock("latex", "\\end{alertblock}")}
    end
end

@MrSauna
Copy link
Author

MrSauna commented May 13, 2021

right, sorry, overlooked this in your original comment. so you could work with something like

::: {.alertblock title="my title"} 
... 
:::

the filter would need to select the attributes too, i.e. something like (not tested):

function Div(el)
    if  el.classes[1] and  el.classes[1] == "alertblock" then
        return {pandoc.RawBlock("latex", "\\begin{alertblock}{" .. el.attributes["title"] .. "}")} .. el.content .. {pandoc.RawBlock("latex", "\\end{alertblock}")}
    end
end

Thats worse than writing latex in my opinion. It requires non trivial non standard syntax and a filter. Kinda beats the whole purpose :)

@cagix
Copy link
Contributor

cagix commented May 13, 2021

well, thats pandoc-markdown syntax :)

you could achieve something similar by using designated header levels, which are usually not used in beamer slides. but then you would tie those header levels to certain blocks, e.g. h3 to alert blocks and h4 to example blocks ... thats also non standard syntax (maybe more readable) and you'd need a simple filter as well ...

@tarleb
Copy link
Collaborator

tarleb commented May 13, 2021

More verbose filter, less verbose syntax:

function Div (div)
  if div.classes[1] == 'section' and div.classes[2] == 'alertblock' then
    div.content[1] = pandoc.Plain(
      {pandoc.RawInline('tex', '\\begin{alertblock}{')} ..
      div.content[1].content ..   -- heading content
      {pandoc.RawInline('tex', '}')}
    )
    div.content:insert(pandoc.RawBlock('tex', '\\end{alertblock}'))
    return div
  end
end

function Pandoc (doc)
  doc.blocks = pandoc.utils.make_sections(false, 1, doc.blocks)
  return doc
end

return {
  {Pandoc = Pandoc},
  {Div = Div},
}

Use with

### Watch out {.alertblock}

Everything in this section ends up in the alertblock.

@MrSauna
Copy link
Author

MrSauna commented May 13, 2021

That flattens sections with source like this

---
theme: Warsaw
title: testing123
---

# first section

## first slide

lkasjdf

### testalert {.alertblock}

text in alert

## second slide

second slide test


# second section

## first slide of second section

sample text

looks like this with filter
image

sections should look like this (without filter)

image

@jgm
Copy link
Owner

jgm commented May 13, 2021

I think supporting a syntax like

#### block title {.example}

text in block

#### block title {.alert}

text in block

would make sense. After all, we already support "blocks," with headings > slide level, so why not add support for the specific kinds of blocks beamer has? It should be quite easy.

@jgm
Copy link
Owner

jgm commented May 13, 2021

This is an enchantment request.

Sorry, we are not wizards!

@tarleb
Copy link
Collaborator

tarleb commented May 14, 2021

The filter was missing a "re-flattening" step, here's the updated code:

function render_alertblock (div)
  if div.classes[1] == 'section' and div.classes[2] == 'alertblock' then
    div.content[1] = pandoc.Plain(
      {pandoc.RawInline('tex', '\\begin{alertblock}{')} ..
      div.content[1].content ..   -- heading content
      {pandoc.RawInline('tex', '}')}
    )
    div.content:insert(pandoc.RawBlock('tex', '\\end{alertblock}'))
    return div
  end
end

function Pandoc (doc)
  doc.blocks = pandoc.utils.make_sections(false, 1, doc.blocks)
  return doc
end

--- Remove remaining section divs
local function flatten_sections (div)
  if div.classes[1] ~= 'section' then
    return nil
  end
  local header = div.content[1]
  if not header or header.t ~= 'Header' then
    return div.content
  else
    header.identifier = div.identifier
    header.attributes.number = nil
    div.content[1] = header
    return div.content
  end
end

return {
  {Pandoc = Pandoc},
  {Div = render_alertblock},
  {Div = flatten_sections}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants