Skip to content

Commit

Permalink
feat: add support of background image
Browse files Browse the repository at this point in the history
  • Loading branch information
heycalmdown committed Aug 29, 2018
1 parent 044bf1b commit 680f0db
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 66 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 46 additions & 24 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
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) => {
const mermaid = $(el);
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');
Expand All @@ -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) => {
Expand All @@ -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) => {
Expand All @@ -66,20 +83,22 @@ 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) => {
if (el.attribs.href[0] === '/') {
el.attribs.href = host + el.attribs.href;
}
});
return $.html();
section.body = $.html();
return section;
}

const LANGS = {
Expand Down Expand Up @@ -116,21 +135,23 @@ function codeFor59(pre) {
pre.parent().html(`<pre><code data-trim data-noescape class="${c}" style="${s}">${code}</code></pre>`)
}

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;
}
Expand Down Expand Up @@ -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;
}
22 changes: 12 additions & 10 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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('<hr/><hr/>').map(section => {
if (section.indexOf('<hr/>') === -1) return section;
return {sections: section.split('<hr/>')};
const contents: string = page.body.view.value.replace(/ \//g, '/');
let sections: Section[] = contents.split('<hr/><hr/>').map(body => {
if (body.indexOf('<hr/>') === -1) return { body };
return { body: '', sections: body.split('<hr/>').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);
Expand Down
48 changes: 22 additions & 26 deletions src/spec/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { convertImageSrcSet, sanitizeImageSrc, setHost, splitPinnedPages, parseP
import { fragment } from '../plugin';

function html(inner) {
return '<html><head></head><body>' + inner + '</body></html>';
return { body: '<html><head></head><body>' + inner + '</body></html>' };
}

describe('miniseminar', () => {
Expand Down Expand Up @@ -35,40 +35,36 @@ describe('miniseminar', () => {
theme: 'Confluence'
});
});
describe('fragements', () => {
describe('fragments', () => {
it('should convert ⏎ in the <li>', () => {
const a = '<ul><li>first⏎</li><li>second⏎</li><li>third⏎</li></ul>';
expect(fragment(a))
.toEqual(html(
'<ul><li class="fragment">first</li><li class="fragment">second</li><li class="fragment">third</li></ul>'
));
const body = '<ul><li>first⏎</li><li>second⏎</li><li>third⏎</li></ul>';
expect(fragment({ body })).toEqual(html(
'<ul><li class="fragment">first</li><li class="fragment">second</li><li class="fragment">third</li></ul>'
));
});
it('should convert ⏎ in the <p>', () => {
const a = '<p>first⏎</p><p>second⏎</p><p>third⏎</p>';
expect(fragment(a))
.toEqual(html(
'<p class="fragment">first</p><p class="fragment">second</p><p class="fragment">third</p>'
));
const body = '<p>first⏎</p><p>second⏎</p><p>third⏎</p>';
expect(fragment({ body })).toEqual(html(
'<p class="fragment">first</p><p class="fragment">second</p><p class="fragment">third</p>'
));
});
it('should convert ⏎ with around an image', () => {
expect(fragment(
`<p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-external-resource" height="250" src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82" data-image-src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82"></span>&#x23CE;</p>`))
.toEqual(html(
`<p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size fragment"><img class="confluence-embedded-image confluence-external-resource" height="250" src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82" data-image-src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82"></span></p>`));
const body = `<p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-external-resource" height="250" src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82" data-image-src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82"></span>&#x23CE;</p>`;
expect(fragment({ body })).toEqual(html(
`<p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size fragment"><img class="confluence-embedded-image confluence-external-resource" height="250" src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82" data-image-src="http://cfile25.uf.tistory.com/image/23028948558D5D6844CB82"></span></p>`
));
});
it('should split by <li>s', () => {
const a = '<ul><li>A⏎</li><li>B⏎</li><li><strong>C with style</strong>, C as plain⏎</li></ul>';
expect(fragment(a))
.toEqual(html(
'<ul><li class="fragment">A</li><li class="fragment">B</li><li class="fragment"><strong>C with style</strong>, C as plain</li></ul>'
));
const body = '<ul><li>A⏎</li><li>B⏎</li><li><strong>C with style</strong>, C as plain⏎</li></ul>';
expect(fragment({ body })).toEqual(html(
'<ul><li class="fragment">A</li><li class="fragment">B</li><li class="fragment"><strong>C with style</strong>, C as plain</li></ul>'
));
});
it('should convert nested <li>s', () => {
const a = '<ul><li><strong>ha</strong>ha⏎<ul><li>he<strong>he</strong>⏎</li></ul></li></ul>';
expect(fragment(a))
.toEqual(html(
'<ul><li class="fragment"><strong>ha</strong>ha<ul><li class="fragment">he<strong>he</strong></li></ul></li></ul>'
));
const body = '<ul><li><strong>ha</strong>ha⏎<ul><li>he<strong>he</strong>⏎</li></ul></li></ul>';
expect(fragment({ body })).toEqual(html(
'<ul><li class="fragment"><strong>ha</strong>ha<ul><li class="fragment">he<strong>he</strong></li></ul></li></ul>'
));
});
})
});
6 changes: 6 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
4 changes: 2 additions & 2 deletions views/page.pug
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down

0 comments on commit 680f0db

Please sign in to comment.