diff --git a/README.md b/README.md index 3bd82bdd..0530c51a 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,15 @@ $ docker run -d -p 3000:3000 \ Type | Notes ---------------- | ----- Slide | Add double `horizontal rule` from the Confluence editor. Or you can use four dashses(----) twice. -Vertical Slice | Add single `horizontal rule` +[Vertical Slice](https://revealjs.com/#/2) | Add single `horizontal rule` Links | Use any link style which Confluence support Image | Use any image style wich Confluence support including attachment +[Background Image](https://revealjs.com/#/10/1) | Make the last image as a background if you reset an image size to original Table | Use Confluence table as usual -Fragments | Ends a sentence with `⏎`(unicode return symbol) -Theming | Use a query parameter `?theme=black` -Transition Style | Use a query parameter `?transition=slide` +[Fragments](https://revealjs.com/#/fragments) | Ends a sentence with `⏎`(unicode return symbol) +[Code Highlight](https://revealjs.com/#/13) | Use Confluence code block | +[Theming](https://revealjs.com/#/themes) | Use a query parameter `?theme=black` +[Transition Style](https://revealjs.com/#/transitions) | Use a query parameter `?transition=slide` ## Plugins diff --git a/src/plugin.ts b/src/plugin.ts index 64060125..8701c336 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,9 +1,9 @@ import * as cheerio from 'cheerio'; -import { convertImageSrcSet, host, sanitizeImageSrc, parseParams } from './util'; +import { Section, convertImageSrcSet, host, sanitizeImageSrc, parseParams } from './util'; -export function mermaid(section) { - const $ = cheerio.load(section); +export function mermaid(section: Section): Section { + const $ = cheerio.load(section.body); const mermaids = $('.mermaid'); if (mermaids.length === 0) return section; mermaids.each((i, el) => { @@ -11,15 +11,16 @@ export function mermaid(section) { mermaid.css('background-color', 'white'); mermaid.css('font-size', '18px'); }); - return $.html(); + section.body = $.html(); + return section; } export function attached(req) { - return (section) => { - const $ = cheerio.load(section); + return (section: Section): Section => { + const $ = cheerio.load(section.body); const imgs = $('img'); if (imgs.length === 0) return section; - imgs.map((i, el) => { + imgs.map((_i, el) => { const img = $(el); if (img.data('linked-resource-type') !== 'attachment') return section; const imageSrc = img.data('image-src'); @@ -29,13 +30,28 @@ export function attached(req) { img.attr('srcset', convertImageSrcSet(req.baseUrl, imageSrcSet)); } }); - return $.html(); + section.body = $.html(); + return section; }; } +export function backgroundImage(section: Section): Section { + const $ = cheerio.load(section.body); + const imgs = $('img'); + imgs.map((_i, el) => { + const img = $(el); + const originalSize = !img.attr('height') && !img.attr('width'); + if (!originalSize) return; + section.background = img.data('image-src'); + img.remove(); + }); + section.body = $.html(); + return section; +} + export function emoticon(req) { - return (section) => { - const $ = cheerio.load(section); + return (section: Section): Section => { + const $ = cheerio.load(section.body); const imgs = $('img.emoticon'); if (imgs.length === 0) return section; imgs.map((i, el) => { @@ -47,13 +63,14 @@ export function emoticon(req) { img.css('margin', '5px'); img.css('vertical-align', 'bottom'); }); - return $.html(); + section.body = $.html(); + return section; }; } export function gliffy(req) { - return (section) => { - const $ = cheerio.load(section); + return (section: Section): Section => { + const $ = cheerio.load(section.body); const imgs = $('img'); if (imgs.length === 0) return section; imgs.map((i, el) => { @@ -66,12 +83,13 @@ export function gliffy(req) { img.attr('srcset', convertImageSrcSet(req.baseUrl, imageSrcSet)); } }); - return $.html(); + section.body = $.html(); + return section; }; } -export function link(section) { - const $ = cheerio.load(section); +export function link(section: Section): Section { + const $ = cheerio.load(section.body); const aList = $('a'); if (aList.length === 0) return section; aList.each((i, el) => { @@ -79,7 +97,8 @@ export function link(section) { el.attribs.href = host + el.attribs.href; } }); - return $.html(); + section.body = $.html(); + return section; } const LANGS = { @@ -116,21 +135,23 @@ function codeFor59(pre) { pre.parent().html(`
${code}
`) } -export function code(section) { - const $ = cheerio.load(section, {xmlMode: true}); +export function code(section: Section): Section { + const $ = cheerio.load(section.body, {xmlMode: true}); // for confluence-5.8 const script = $('.code.panel.pdl script[type=syntaxhighlighter]'); if (script.length !== 0) { codeFor58(script); - return $.html(); + section.body = $.html(); + return section; } // for confluence-5.9 const pre = $('.codeContent.panelContent.pdl pre'); if (pre.length !== 0) { codeFor59(pre); - return $.html(); + section.body = $.html(); + return section; } return section; } @@ -184,9 +205,10 @@ function fragmentTags($, tagName) { }); } -export function fragment(section) { - const $ = cheerio.load(section); +export function fragment(section: Section): Section { + const $ = cheerio.load(section.body); fragmentLi($); fragmentTags($, 'p'); - return $.html(); + section.body = $.html(); + return section; } diff --git a/src/routes/index.ts b/src/routes/index.ts index 0761b8d0..feb330b2 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -3,8 +3,8 @@ import Confluency from 'confluency'; import * as querystring from 'querystring'; import * as _ from 'lodash'; -import { host, splitPinnedPages } from '../util'; -import { attached, mermaid, gliffy, link, code, fragment, emoticon } from '../plugin'; +import { Section, host, splitPinnedPages } from '../util'; +import { attached, backgroundImage, mermaid, gliffy, link, code, fragment, emoticon } from '../plugin'; const context = process.env.CONTEXT; const username = process.env.USERNAME; @@ -50,21 +50,23 @@ router.get('/page/:id', (req, res, next) => { recentlyViewed.push({id: req.params.id, title: page.title}); recentlyViewed = _.uniqBy(recentlyViewed, 'id'); - const contents = page.body.view.value.replace(/ \//g, '/'); - let sections = contents.split('

').map(section => { - if (section.indexOf('
') === -1) return section; - return {sections: section.split('
')}; + const contents: string = page.body.view.value.replace(/ \//g, '/'); + let sections: Section[] = contents.split('

').map(body => { + if (body.indexOf('
') === -1) return { body }; + return { body: '', sections: body.split('
').map(s => ({ body: s }))}; }); - function map(section) { - return [ + function map(section: Section) { + const middlewares: ((s: Section) => Section)[] = [ attached(req), + backgroundImage, emoticon(req), gliffy(req), mermaid, link, code, - fragment, - ].reduce((section, middleware) => middleware(section), section); + fragment + ]; + return middlewares.reduce((section, middleware) => middleware(section), section); } sections = sections.map(section => { if (!section.sections) return map(section); diff --git a/src/spec/index.spec.ts b/src/spec/index.spec.ts index fafb1d82..daf1b698 100644 --- a/src/spec/index.spec.ts +++ b/src/spec/index.spec.ts @@ -2,7 +2,7 @@ import { convertImageSrcSet, sanitizeImageSrc, setHost, splitPinnedPages, parseP import { fragment } from '../plugin'; function html(inner) { - return '' + inner + ''; + return { body: '' + inner + '' }; } describe('miniseminar', () => { @@ -35,40 +35,36 @@ describe('miniseminar', () => { theme: 'Confluence' }); }); - describe('fragements', () => { + describe('fragments', () => { it('should convert ⏎ in the
  • ', () => { - const a = ''; - expect(fragment(a)) - .toEqual(html( - '' - )); + const body = ''; + expect(fragment({ body })).toEqual(html( + '' + )); }); it('should convert ⏎ in the

    ', () => { - const a = '

    first⏎

    second⏎

    third⏎

    '; - expect(fragment(a)) - .toEqual(html( - '

    first

    second

    third

    ' - )); + const body = '

    first⏎

    second⏎

    third⏎

    '; + expect(fragment({ body })).toEqual(html( + '

    first

    second

    third

    ' + )); }); it('should convert ⏎ with around an image', () => { - expect(fragment( - `

    `)) - .toEqual(html( - `

    `)); + const body = `

    `; + expect(fragment({ body })).toEqual(html( + `

    ` + )); }); it('should split by
  • s', () => { - const a = ''; - expect(fragment(a)) - .toEqual(html( - '' - )); + const body = ''; + expect(fragment({ body })).toEqual(html( + '' + )); }); it('should convert nested
  • s', () => { - const a = ''; - expect(fragment(a)) - .toEqual(html( - '' - )); + const body = ''; + expect(fragment({ body })).toEqual(html( + '' + )); }); }) }); diff --git a/src/util.ts b/src/util.ts index 73af60e4..f9635bfb 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,5 +1,11 @@ import * as _ from 'lodash'; +export interface Section { + body: string; + sections?: Section[]; + background?: string; +} + export let host = process.env.HOST; let context = process.env.CONTEXT; diff --git a/views/page.pug b/views/page.pug index 8c54466a..e49ad424 100644 --- a/views/page.pug +++ b/views/page.pug @@ -14,11 +14,11 @@ html .slides each section in sections unless section.sections - section!=section + section(data-background=section.background)!=section.body else section each subSection in section.sections - section!=subSection + section(data-background=subSection.background)!=subSection.body script(src=`/lib/js/head.min.js`) script(src=`/js/reveal.js`)