Skip to content

Commit

Permalink
Merge pull request #94 from marp-team/size-global-directive
Browse files Browse the repository at this point in the history
Get back size global directive and 4:3 slide
  • Loading branch information
yhatt authored Jun 24, 2019
2 parents 6c976ae + 26f6065 commit 4909fd4
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Added

- `size` global directive and `@size` theme metadata to get easier way for using 4:3 deck in built-in theme ([#91](https://github.com/marp-team/marp-core/issues/91), [#94](https://github.com/marp-team/marp-core/pull/94))

## v0.10.2 - 2019-06-21

### Fixed
Expand Down
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,27 @@ We provide bulit-in official themes for Marp. See more details in [themes].

[themes]: ./themes/

### `size` global directive

Do you want a traditional 4:3 slide size? We've added the support of `size` global directive only for Marp Core (And keeping [backward compatibility of syntax with the old Marp app](https://github.com/yhatt/marp/blob/master/example.md#size) too).

Our extended theming system can use `960`x`720` slide in built-in themes easier: `size: 4:3`.

```markdown
---
theme: gaia
size: 4:3
---

# A traditional 4:3 slide
```

If you want to use more size presets in your theme, you have to define `@size` metadata(s) in theme CSS. [Learn in the document of theme metadata for Marp Core][metadata].

Theme author does not have to worry an unintended design being used with unexpected slide size because user only can use pre-defined presets by author.

[metadata]: ./themes#metadata-for-additional-features

### Emoji support

Emoji shortcode (like `:smile:`) and Unicode emoji 😄 will convert into the SVG vector image provided by [twemoji](https://github.com/twitter/twemoji) <img src="https://twemoji.maxcdn.com/2/svg/1f604.svg" alt="😄" width="16" height="16" />. It could render emoji with high resolution.
Expand Down Expand Up @@ -123,7 +144,7 @@ $$

### Auto-scaling features

Auto-scaling is available only if enabled [Marpit's `inlineSVG` mode](https://github.com/marp-team/marpit#inline-svg-slide-experimental) and defined `@auto-scaling` meta data in an using theme CSS. In addition, you have to run [`Marp.ready()`](#marpready) on browser context.
Auto-scaling is available only if enabled [Marpit's `inlineSVG` mode](https://github.com/marp-team/marpit#inline-svg-slide-experimental) and defined [`@auto-scaling` metadata][metadata] in an using theme CSS. In addition, you have to run [`Marp.ready()`](#marpready) on browser context.

```css
/*
Expand Down Expand Up @@ -177,7 +198,9 @@ Several themes also can scale-down the viewing size of the code block to fit a s

These features means that the contents on a slide are not cropped, and not shown unnecessary scrollbars in code.

> :information_source: `@auto-scaling code` is a keyword of the `@auto-scaling` meta to enable code block scaling. `uncover` theme has disabled code block scaling because we use elastic style that has not compatible with it.
> :information_source: `@auto-scaling code` is a keyword of the `@auto-scaling` meta to enable code block scaling.
>
> `uncover` theme has disabled code block scaling because we use elastic style that has not compatible with it.
## Constructor options

Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
collectCoverageFrom: ['src/**/*.{j,t}s'],
coveragePathIgnorePatterns: ['/node_modules/', '.*\\.d\\.ts'],
coverageThreshold: { global: { lines: 95 } },
setupFiles: ['jest-plugin-context/setup'],
testEnvironment: 'node',
testRegex: '(/(test|__tests__)/(?!_).*|(\\.|/)(test|spec))\\.[jt]s$',
transform: {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@
"devDependencies": {
"@types/cheerio": "^0.22.11",
"@types/jest": "^24.0.15",
"@types/jest-plugin-context": "^2.9.2",
"autoprefixer": "^9.6.0",
"cheerio": "^1.0.0-rc.3",
"codecov": "^3.5.0",
"cssnano": "^4.1.9",
"github-markdown-css": "^3.0.1",
"jest": "^24.8.0",
"jest-junit": "^6.4.0",
"jest-plugin-context": "^2.9.0",
"markdown-it": "^8.4.2",
"node-sass-package-importer": "^5.3.2",
"npm-run-all": "^4.1.5",
Expand Down
10 changes: 8 additions & 2 deletions src/marp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as emojiPlugin from './emoji/emoji'
import * as fittingPlugin from './fitting/fitting'
import * as htmlPlugin from './html/html'
import * as mathPlugin from './math/math'
import * as sizePlugin from './size/size'
import defaultTheme from '../themes/default.scss'
import gaiaTheme from '../themes/gaia.scss'
import uncoverTheme from '../themes/uncover.scss'
Expand Down Expand Up @@ -59,10 +60,14 @@ export class Marp extends Marpit {
},
})

// Enable table
this.markdown.enable(['table', 'linkify'])

// Add themes
// Theme support
this.themeSet.metaType = Object.freeze({
'auto-scaling': String,
size: Array,
})

this.themeSet.default = this.themeSet.add(defaultTheme)
this.themeSet.add(gaiaTheme)
this.themeSet.add(uncoverTheme)
Expand All @@ -75,6 +80,7 @@ export class Marp extends Marpit {
.use(emojiPlugin.markdown)
.use(mathPlugin.markdown, flag => (this.renderedMath = flag))
.use(fittingPlugin.markdown)
.use(sizePlugin.markdown)
}

highlighter(code: string, lang: string): string {
Expand Down
90 changes: 90 additions & 0 deletions src/size/size.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import marpitPlugin from '@marp-team/marpit/lib/markdown/marpit_plugin'
import { Theme } from '@marp-team/marpit'
import { Marp } from '../marp'

interface DefinedSize {
width: string
height: string
}

interface RestorableThemes {
default: Theme | undefined
themes: Set<Theme>
}

export const markdown = marpitPlugin(md => {
const marp: Marp = md.marpit
const { render } = marp

const definedSizes = (theme: Theme): ReadonlyMap<string, DefinedSize> => {
const sizes = (marp.themeSet.getThemeMeta(theme, 'size') as string[]) || []
const map = new Map<string, DefinedSize>()

for (const value of sizes) {
const args = value.split(/\s+/)

if (args.length === 3) {
map.set(args[0], { width: args[1], height: args[2] })
} else if (args.length === 2 && args[1] === 'false') {
map.delete(args[0])
}
}

return map
}

const forRestore: RestorableThemes = {
themes: new Set<Theme>(),
default: undefined,
}

// `size` global directive
marp.customDirectives.global.size = size =>
typeof size === 'string' ? { size } : {}

// Override render method to restore original theme set
marp.render = (...args) => {
try {
return render.apply<Marp, any[], any>(marp, args)
} finally {
forRestore.themes.forEach(theme => marp.themeSet.addTheme(theme))

if (forRestore.default) marp.themeSet.default = forRestore.default
}
}

md.core.ruler.after('marpit_directives_global_parse', 'marp_size', state => {
if (state.inlineMode) return

forRestore.themes.clear()
forRestore.default = undefined

const { theme, size } = (marp as any).lastGlobalDirectives
if (!size) return

const themeInstance = marp.themeSet.get(theme, true) as Theme
const customSize = definedSizes(themeInstance).get(size)

if (customSize) {
const { width, height } = customSize
const css = `${themeInstance.css}\nsection{width:${width};height:${height};}`

const overrideTheme = Object.assign(new (Theme as any)(), {
...themeInstance,
...customSize,
css,
})

forRestore.themes.add(themeInstance)

if (themeInstance === marp.themeSet.default) {
forRestore.default = themeInstance
marp.themeSet.default = overrideTheme
}

if (marp.themeSet.has(overrideTheme.name)) {
marp.themeSet.addTheme(overrideTheme)
}
}
})
})
1 change: 0 additions & 1 deletion test/_helpers/context.ts

This file was deleted.

1 change: 0 additions & 1 deletion test/browser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/** @jest-environment jsdom */
import browser from '../src/browser'
import context from './_helpers/context'
import fittingObserver from '../src/fitting/observer'

const polyfill = jest.fn()
Expand Down
1 change: 0 additions & 1 deletion test/fitting/observer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/** @jest-environment jsdom */
import context from '../_helpers/context'
import Marp from '../../src/marp'
import fittingObserver from '../../src/fitting/observer'

Expand Down
42 changes: 31 additions & 11 deletions test/marp.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Marpit } from '@marp-team/marpit'
import cheerio from 'cheerio'
import MarkdownIt from 'markdown-it'
import postcss from 'postcss'
import context from './_helpers/context'
import { EmojiOptions } from '../src/emoji/emoji'
import browser from '../src/browser'
import { Marp, MarpOptions } from '../src/marp'
Expand All @@ -15,6 +13,12 @@ afterEach(() => jest.restoreAllMocks())
describe('Marp', () => {
const marp = (opts?: MarpOptions): Marp => new Marp(opts)

const loadCheerio = (html: string) =>
cheerio.load(html, {
lowerCaseAttributeNames: false,
lowerCaseTags: false,
})

it('extends Marpit', () => expect(marp()).toBeInstanceOf(Marpit))

describe('markdown option', () => {
Expand Down Expand Up @@ -313,10 +317,8 @@ describe('Marp', () => {
})

context('when math typesetting syntax is not using', () => {
const ret = marp().render('plain text')

it('does not inject KaTeX css', () =>
expect(ret.css).not.toContain('.katex'))
expect(marp().render('plain text').css).not.toContain('.katex'))
})

context('with katexOption', () => {
Expand Down Expand Up @@ -413,12 +415,6 @@ describe('Marp', () => {
})

describe('Element fitting', () => {
const loadCheerio = (html: string) =>
cheerio.load(html, {
lowerCaseAttributeNames: false,
lowerCaseTags: false,
})

it('prepends CSS about fitting', () => {
const { css } = marp().render('')

Expand Down Expand Up @@ -569,6 +565,30 @@ describe('Marp', () => {
})
})

describe('size global directive', () => {
it('defines size custom global directive', () =>
expect(marp().customDirectives.global.size).toBeTruthy())

context('with size directive as 4:3', () => {
const size = expect.objectContaining({ width: '960', height: '720' })

it('renders inline SVG with 960x720 size', () => {
const instance = marp()
const md = (t: string) => `<!-- theme: ${t} -->\n<!-- size: 4:3 -->`

const { html } = instance.render('<!-- size: 4:3 -->')
expect(loadCheerio(html)('foreignObject').attr()).toStrictEqual(size)

for (const theme of instance.themeSet.themes()) {
const { html: themeHtml } = instance.render(md(theme.name))
const $ = loadCheerio(themeHtml)

expect($('foreignObject').attr()).toStrictEqual(size)
}
})
})
})

describe('themeSet property', () => {
const { themeSet } = new Marp()

Expand Down
Loading

0 comments on commit 4909fd4

Please sign in to comment.