使用Pandoc生成Beamer幻灯片时\onslide命令的使用难题
I totally get your frustration—Pandoc's one-size-fits-all approach to pauses in Beamer can be really annoying. Let's break down why each command causes problems and how to fix it with a targeted solution.
The Root of the Problem
- Default
\pauseafter list items: Beamer treats each\pauseas a new overlay step. So after your last list item, that extra\pausecreates an empty overlay (aka an extra blank slide) at the end of your list. - Switching to
\onslide<+->: While this fixes the extra slide issue for lists, using it universally messes up non-list content like math blocks because it forces content to appear incrementally even when you don't want it to.
The Solution: Context-Aware Pause Handling with a Lua Filter
The best way to fix this is to use a Pandoc Lua filter that adjusts the behavior only for incremental lists, leaving regular pauses intact for other content. This way:
- Incremental list items appear one by one without an extra slide at the end.
- Math blocks and regular slides still work as expected with standard
\pausecommands.
Here's the Lua filter (save it as beamer-incremental-fix.lua):
function BulletList(list) -- Check if the list is incremental (marked with .incremental class) if list.classes and list.classes:includes("incremental") then -- Modify each item to use \item<+-> instead of adding \pause for _, item in ipairs(list.content) do -- Wrap the item content in a RawBlock to add the overlay spec local modified_item = pandoc.RawBlock("latex", "\\item<+-> ") -- Append the original item content to the modified item table.insert(item.content, 1, modified_item) end -- Remove the incremental class so Pandoc doesn't add \pause list.classes = list.classes:filter(function(c) return c ~= "incremental" end) return list end -- Return unmodified if not incremental return list end
How to Use It
When generating your Beamer slides, include the filter in your Pandoc command:
pandoc your-slides.md -t beamer -o your-slides.pdf --lua-filter=beamer-incremental-fix.lua
How It Works
- The filter detects any incremental list (marked with
.incrementalin your Markdown, e.g.,:::incremental\n- Item 1\n- Item 2\n:::or using the--incrementalflag globally). - For each item in the list, it adds the
<+->overlay spec directly to the\itemcommand, which makes the item appear on the next overlay step and stay visible for all subsequent steps. - It removes the incremental class so Pandoc doesn't add the default
\pauseafter each item, eliminating the extra slide.
Alternative: Modify the Beamer Template
If you prefer not to use a Lua filter, you can adjust your Beamer template to change how incremental lists are handled. Here's what to do:
- Generate the default Pandoc Beamer template:
pandoc -D beamer > my-beamer-template.tex - Open the template and find the section where incremental lists are configured. Look for lines like:
$if(incremental)$ \usepackage{enumitem} \setlist[itemize]{label=\usebeamerfont*{itemize item}\usebeamercolor[fg]{itemize item}\usebeamertemplate{itemize item}, before=\pause, after=\pause} $endif$ - Replace that with:
$if(incremental)$ \usepackage{enumitem} \setlist[itemize]{label=\usebeamerfont*{itemize item}\usebeamercolor[fg]{itemize item}\usebeamertemplate{itemize item}, item=\item<+->} $endif$ - Use the modified template when generating slides:
pandoc your-slides.md -t beamer -o your-slides.pdf --template=my-beamer-template.tex
This achieves the same effect as the Lua filter by setting each list item to use <+-> instead of adding \pause before/after items.
Final Notes
- For manual pauses outside of lists (e.g., between paragraphs or before a math block), keep using
\pauseas you normally would—it won't cause issues here. - If you use the
--incrementalflag globally, both the filter and template modification will apply to all lists, so you don't need to mark each list with.incremental.
内容的提问来源于stack exchange,提问作者Eponymous

