Skip to content

Commit

Permalink
Merge pull request #175 from marp-team/paginate-with-total
Browse files Browse the repository at this point in the history
Allow customization the content of pagination
  • Loading branch information
yhatt authored Jul 11, 2019
2 parents a5bf729 + e594408 commit 55d87f6
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 47 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

### Added

- Allow loose YAML parsing for custom directives ([#173](https://github.com/marp-team/marpit/pull/173))
- Loose YAML parsing for custom directives ([#173](https://github.com/marp-team/marpit/pull/173))

### Changed

- Allow customization the content of pagination ([#175](https://github.com/marp-team/marpit/pull/175))

## v1.2.0 - 2019-06-17

Expand Down
19 changes: 19 additions & 0 deletions docs/theme-css.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ section::after {

Please refer to [the default style of `section::after` in a scaffold theme](https://github.com/marp-team/marpit/blob/master/src/theme/scaffold.js) as well.

#### Customize content

Marpit has a default content: `attr(data-marpit-pagination)`, indicates the current page number. Theme CSS can add other strings and attributes to the shown page number.

<!-- prettier-ignore-start -->

```css
/* Add "Page" prefix and total page number */
section::after {
content: 'Page ' attr(data-marpit-pagination) ' / ' attr(data-marpit-pagination-total);
}
```

<!-- prettier-ignore-end -->

`attr(data-marpit-pagination-total)` means the total page number of rendered slides. Thus, the above example would show as like as `Page 1 / 3`.

!> Theme CSS must contain `attr(data-marpit-pagination)` in `content` declaration because user expects to show the page number by `paginate: true` directive. Marpit will ignore the whole of `content` declaration if the reference to that attribute is not contained.

### Header and footer

`header` and `footer` element have a possible to be rendered by [`header` / `footer` local directives](/directives#header-and-footer). _Marpit has no default style for these elements._
Expand Down
5 changes: 5 additions & 0 deletions src/markdown/background_image/advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,14 @@ function advancedBackground(md) {
class: open.attrGet('class'),
style: style.toString(),
'data-marpit-advanced-background': 'pseudo',

// For pagination styling
'data-marpit-pagination': open.attrGet(
'data-marpit-pagination'
),
'data-marpit-pagination-total': open.attrGet(
'data-marpit-pagination-total'
),
})
)
)
Expand Down
7 changes: 5 additions & 2 deletions src/markdown/directives/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ function apply(md, opts = {}) {
if (state.inlineMode) return

for (const token of state.tokens) {
const { marpitDirectives, marpitSlide } = token.meta || {}
const { marpitDirectives, marpitSlide, marpitSlideTotal } =
token.meta || {}

if (marpitDirectives) {
const style = new InlineStyle(token.attrGet('style'))
Expand Down Expand Up @@ -83,8 +84,10 @@ function apply(md, opts = {}) {
style.set('background-size', marpitDirectives.backgroundSize)
}

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

if (marpitDirectives.header)
token.meta.marpitHeader = marpitDirectives.header
Expand Down
62 changes: 31 additions & 31 deletions src/markdown/slide.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,40 @@ function slide(md, opts = {}) {
md.core.ruler.push('marpit_slide', state => {
if (state.inlineMode) return

state.tokens = split(state.tokens, t => t.type === 'hr', true).reduce(
(arr, slideTokens, idx) => {
const firstHr =
slideTokens[0] && slideTokens[0].type === 'hr'
? slideTokens[0]
: undefined
const splittedTokens = split(state.tokens, t => t.type === 'hr', true)
const { length: marpitSlideTotal } = splittedTokens

const mapTarget = firstHr || slideTokens.find(t => t.map)
state.tokens = splittedTokens.reduce((arr, slideTokens, marpitSlide) => {
const firstHr =
slideTokens[0] && slideTokens[0].type === 'hr'
? slideTokens[0]
: undefined

return [
...arr,
...wrapTokens(
state.Token,
'marpit_slide',
{
...(opts.attributes || {}),
tag: 'section',
id: anchorCallback(idx),
open: {
block: true,
meta: { marpitSlide: idx, marpitSlideElement: 1 },
map: mapTarget ? mapTarget.map : [0, 1],
},
close: {
block: true,
meta: { marpitSlide: idx, marpitSlideElement: -1 },
},
const mapTarget = firstHr || slideTokens.find(t => t.map)

return [
...arr,
...wrapTokens(
state.Token,
'marpit_slide',
{
...(opts.attributes || {}),
tag: 'section',
id: anchorCallback(marpitSlide),
open: {
block: true,
meta: { marpitSlide, marpitSlideTotal, marpitSlideElement: 1 },
map: mapTarget ? mapTarget.map : [0, 1],
},
close: {
block: true,
meta: { marpitSlide, marpitSlideTotal, marpitSlideElement: -1 },
},
slideTokens.slice(firstHr ? 1 : 0)
),
]
},
[]
)
},
slideTokens.slice(firstHr ? 1 : 0)
),
]
}, [])
})
}

Expand Down
4 changes: 2 additions & 2 deletions src/postcss/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const plugin = postcss.plugin('marpit-postcss-pagination', () => css => {
)
)
)
rule.walkDecls(/^content$/, decl => {
if (decl.value !== 'attr(data-marpit-pagination)')
rule.walkDecls('content', decl => {
if (!decl.value.includes('attr(data-marpit-pagination)'))
decl.replaceWith(`${decl.raw('before')}/* ${decl.toString()}; */`)
})
})
Expand Down
10 changes: 4 additions & 6 deletions test/markdown/background_image.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ describe('Marpit background image plugin', () => {
)
)

it('assigns data-marpit-pagination attribute to pseudo layer', () => {
it('assigns pagination attributes to pseudo layer', () => {
const foreignObjects = $('svg > foreignObject')
expect(foreignObjects).toHaveLength(3)

Expand All @@ -414,11 +414,9 @@ describe('Marpit background image plugin', () => {
true
)

expect(
pseudoFO
.find('> section.pseudo.layer')
.is('[data-marpit-pagination="1"]')
).toBe(true)
const pseudoLayer = pseudoFO.find('> section.pseudo.layer')
expect(pseudoLayer.is('[data-marpit-pagination="1"]')).toBe(true)
expect(pseudoLayer.is('[data-marpit-pagination-total="1"]')).toBe(true)
})
})

Expand Down
2 changes: 2 additions & 0 deletions test/markdown/directives/apply.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ describe('Marpit directives apply plugin', () => {
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-total')).toBe(2)
})
})
})
Expand Down
19 changes: 14 additions & 5 deletions test/postcss/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,20 @@ describe('Marpit PostCSS pagination plugin', () => {
]))

it('keeps the content declaration of section::after for pagination', () =>
expect(
run('section::after { content: attr(data-marpit-pagination); }')
).resolves.toBe(
'section::after { content: attr(data-marpit-pagination); }'
))
Promise.all([
expect(
run('section::after { content: attr(data-marpit-pagination); }')
).resolves.toBe(
'section::after { content: attr(data-marpit-pagination); }'
),
expect(
run(
'section::after { content: attr(data-marpit-pagination) "/" attr(data-marpit-pagination-total); }'
)
).resolves.toBe(
'section::after { content: attr(data-marpit-pagination) "/" attr(data-marpit-pagination-total); }'
),
]))

it('keeps the content declaration of section::after with combinators', () =>
Promise.all([
Expand Down

0 comments on commit 55d87f6

Please sign in to comment.