Skip to content

Instantly share code, notes, and snippets.

@cormojs
Last active November 22, 2021 06:47
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cormojs/96f320187c6433ec33a15a0960f8d385 to your computer and use it in GitHub Desktop.
Save cormojs/96f320187c6433ec33a15a0960f8d385 to your computer and use it in GitHub Desktop.
Convert a Confluence page's content to slides using Reveal.js
// ==UserScript==
// @name Confluence Page to Reveal Slides
// @namespace http://github.com/cormojs
// @version 1.0
// @description Convert a Confluence page's content to slides using Reveal.js
// @author cormojs
// @match https://*/confluence/pages/viewpage.action*
// @require https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reveal.js
// @grant none
// @downloadURL https://gist.github.com/cormojs/96f320187c6433ec33a15a0960f8d385/raw/confluence-to-reveal.user.js
// ==/UserScript==
/*global $*/
/*global jQuery*/
/*global Reveal*/
(function() {
'use strict';
$(document).ready(function() {
// カスタム要素を定義してその中にreveal.jsを閉じ込める
customElements.define('my-slides', class extends HTMLElement {
connectedCallback() {
// create Node object for reveal.js
const wikiSlideContent = constructSlideConent(queryWikiContent());
// attach shadow dom
this.attachShadow({ mode: "open"}).appendChild(wikiSlideContent);
// load slides
const reveal = new Reveal(wikiSlideContent, { embedded: true });
reveal.initialize();
}
});
// ボタンを押したら定義したカスタム要素を作成する
const mainContent = document.querySelector("#main-content");
mainContent
.parentNode
.insertBefore(
createStartButton(mainContent.parentNode, document.createElement("my-slides")),
mainContent
);
});
function createStartButton(parent, elemToInsert) {
return $("<button>")
.text("スライドをスタート")
.on("click", () => {
parent.insertBefore(
elemToInsert,
parent.querySelector("*")
)
})
.get(0)
}
// h1~h4をスライド1枚の始まりと見て、1枚毎の Node の配列が入った配列を返す
// また、先頭にはタイトルページを挿入する
function partitionWikiContent(elems) {
return elems.reduce((arr, elem) => {
if ($(elem).is("h1") || $(elem).is("h2") || $(elem).is("h3") || $(elem).is("h4")) {
return arr.concat([[elem]]);
} else {
arr[arr.length - 1] = arr[arr.length - 1].concat(elem);
return arr;
}
}, [[createTitle("#title-text", ".author a")]])
// いらないページを排除
.filter(arr => arr.length != 0)
.filter(elems => elems.length > 0 && !$(elems[0]).is("text"));
}
function queryWikiContent() {
return document.querySelector("#main-content .wiki-content")
?? document.querySelector("#main-content.wiki-content");
}
function constructSlideConent(elem) {
return $("<div>")
.addClass("reveal")
.append(
$("<div>")
.addClass("slides")
.append(
...partitionWikiContent($(elem).contents().toArray())
.map(elems => $("<section>").append(...elems).get(0))
)
)
.append(
$("<link>").attr({ rel: "stylesheet", href: "https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reveal.css"})
)
.append(
$("<link>").attr({ rel: "stylesheet", href: "https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/theme/white.css" })
)
.append(
$("<script>").attr({ type: "text/javascript", src: "https://cdn.jsdelivr.net/npm/reveal.js@4.1.0/dist/reveal.js" })
)
.css({ "height": "100vh", "width": "100%" })
.get(0);
}
function createTitle(title, author) {
const elem = document.createElement("div");
elem.innerHTML = `
<h1>${document.querySelector(title).textContent}</h1>
<p>${document.querySelector(author).textContent}<p>
`;
return elem;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment