Skip to content

Commit

Permalink
Merge pull request #359 from JannikWibker/pagination-skip-feature
Browse files Browse the repository at this point in the history
`paginate: skip` directive
  • Loading branch information
yhatt authored Jun 6, 2023
2 parents 1c00aed + 1f4df25 commit cdd063f
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 10 deletions.
65 changes: 59 additions & 6 deletions docs/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,37 +181,90 @@ It is useful when you want to create a slide deck from a plain Markdown. Even if

### Pagination

We support a pagination by the `paginate` local directive.
We support pagination by the `paginate` local directive.

```markdown
<!-- paginate: true -->

You would be able to see a page number of slide in the lower right.
```

#### Configuring pagination

There are 2 things happening on each slide:

- the page number is rendered _and_
- the page number is being incremented.

You can control both of these with the `paginate` directive:

| `paginate` | Page number | Increment |
| ---------- | ----------- | --------- |
| `true` | Show | Yes |
| `false` | Hide | Yes |
| `hold` | Show | No |
| `skip` | Hide | No |

#### Skip pagination on title slide

Simply you have to move a definition of `paginate` directive to an inside of a second page.
A common use case is excluding the title slide from pagination.
For this you simply have to define the `paginate` directive on the second page instead of the first.

```markdown
# Title slide

This page will not paginate by lack of `paginate` local directive.
This page will not have pagination by lack of the `paginate` directive.

---

<!-- paginate: true -->

It will paginate slide from a this page.
Pagination will render from this slide onwards (starting at 2).
```

Or you can use the spot directive.

```markdown
---
paginate: true
_paginate: false # or use `_paginate: skip`
---
```

#### `paginate: skip` and `paginate: hold`

To both exclude a page from pagination and hide the pagination at the same time use `skip`:

```markdown
<!-- _paginate: skip -->

# Slide to exclude

This page will not update the page number and also not show the pagination
```

Or also can use the spot directive.
You can exclude a page from pagination but keep the pagination visible using `hold`:

```markdown
---
paginate: true
_paginate: false
---

# Slide 1

[](./assets/image_01.png)

> Page 1 of 1

---

<!-- _paginate: hold -->

# Slide 2

[](./assets/image_02.png)

> Page 1 of 1
```

### Header and footer
Expand Down
38 changes: 36 additions & 2 deletions src/markdown/directives/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ function _apply(md, opts = {}) {
(state) => {
if (state.inlineMode) return

// compute the total number of skipped pages
let totalSkippedSlides = 0
for (const token of state.tokens) {
const { marpitDirectives } = token.meta || {}
if (
marpitDirectives &&
(marpitDirectives.paginate === 'hold' ||
marpitDirectives.paginate === 'skip')
) {
totalSkippedSlides++
}
}

// keep track of slides that were skipped using one of the following
// directives:
// `paginate: skip`, `_paginate: skip`,
// `paginate: hold`, or `_paginate: hold
let currentSkippedSlides = 0

for (const token of state.tokens) {
const { marpitDirectives, marpitSlide, marpitSlideTotal } =
token.meta || {}
Expand Down Expand Up @@ -85,8 +104,23 @@ function _apply(md, opts = {}) {
}

if (marpitDirectives.paginate) {
token.attrSet('data-marpit-pagination', marpitSlide + 1)
token.attrSet('data-marpit-pagination-total', marpitSlideTotal)
if (
marpitDirectives.paginate === 'hold' ||
marpitDirectives.paginate === 'skip'
) {
currentSkippedSlides++
}

if (marpitDirectives.paginate !== 'skip') {
token.attrSet(
'data-marpit-pagination',
marpitSlide - currentSkippedSlides + 1
)
token.attrSet(
'data-marpit-pagination-total',
marpitSlideTotal - totalSkippedSlides
)
}
}

if (marpitDirectives.header)
Expand Down
6 changes: 5 additions & 1 deletion src/markdown/directives/directives.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ export const locals = Object.assign(Object.create(null), {
color: (v) => ({ color: v }),
footer: (v) => (typeof v === 'string' ? { footer: v } : {}),
header: (v) => (typeof v === 'string' ? { header: v } : {}),
paginate: (v) => ({ paginate: (v || '').toLowerCase() === 'true' }),
paginate: (v) => ({
paginate: ['hold', 'skip'].includes(v)
? v
: (v || '').toLowerCase() === 'true',
}),
})

export default [...Object.keys(globals), ...Object.keys(locals)]
92 changes: 91 additions & 1 deletion test/markdown/directives/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,18 +219,108 @@ describe('Marpit directives apply plugin', () => {
# Slide 1
Pagination is not rendered
---
## Slide 2
Pagination is rendered (2 of 2)
`

const $ = load(mdForTest().render(paginateDirs))
const sections = $('section')

expect(sections.eq(0).data('marpit-pagination')).toBeUndefined()
expect(sections.eq(0).data('marpit-pagination-total')).toBeUndefined()
expect(sections.eq(1).data('marpit-pagination')).toBe(2)
expect(sections.eq(1).data('marpit-pagination-total')).toBe(2)
})
})

describe('Paginate with skipped slides', () => {
it('applies data-marpit-pagination attribute with a _paginate:hold slide', () => {
const paginateDirs = dedent`
---
paginate: true
_paginate:
---
# Slide 1
- Page is counted (1 of 2)
- Pagination is not rendered
---
<!--
_paginate: hold
-->
## Slide 2
- Page is not counted
- Pagination is rendered (1 of 2)
---
## Slide 3
- Page is counted
- Pagination is rendered (2 of 2)
`

const $ = load(mdForTest().render(paginateDirs))
const sections = $('section')

expect(sections.eq(0).data('marpit-pagination')).toBeUndefined()
expect(sections.eq(0).data('marpit-pagination-total')).toBeUndefined()
expect(sections.eq(1).data('marpit-pagination')).toBeTruthy()
expect(sections.eq(1).data('marpit-pagination')).toBe(1)
expect(sections.eq(1).data('marpit-pagination-total')).toBe(2)
expect(sections.eq(2).data('marpit-pagination')).toBe(2)
expect(sections.eq(2).data('marpit-pagination-total')).toBe(2)
})

it('applies data-marpit-pagination attribute with a _paginate:skip slide', () => {
const paginateDirs = dedent`
---
paginate: true
_paginate:
---
# Slide 1
- Page is counted (1 of 2)
- Pagination is not rendered
---
<!--
_paginate: skip
-->
## Slide 2
- Page is not counted
- Pagination is not rendered (1 of 2)
---
## Slide 3
- Page is counted
- Pagination is rendered (2 of 2)
`

const $ = load(mdForTest().render(paginateDirs))
const sections = $('section')

expect(sections.eq(0).data('marpit-pagination')).toBeUndefined()
expect(sections.eq(0).data('marpit-pagination-total')).toBeUndefined()
expect(sections.eq(1).data('marpit-pagination')).toBeUndefined()
expect(sections.eq(1).data('marpit-pagination-total')).toBeUndefined()
expect(sections.eq(2).data('marpit-pagination')).toBe(2)
expect(sections.eq(2).data('marpit-pagination-total')).toBe(2)
})
})
})
Expand Down

0 comments on commit cdd063f

Please sign in to comment.