Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* gaido v1.0.0 (c) 2016~ nodegin */
- !function() {
- var container = document.querySelector('#gaido');
- var script = document.querySelector('script[type="text/gaido"]').innerHTML;
- script = script.split('\n').slice(1, -1);
- var getIndentLength = function(line) {
- matches = line.match(/^\s+/);
- return matches ? matches[0].length : 0;
- };
- var raise = function(message, i) {
- throw new Error(message + (i ? ' at line ' + (i + 1) : ''));
- };
- if (script.length < 2) {
- raise('Invalid gaido script');
- }
- var trimIndent = new RegExp('^\\s{' + getIndentLength(script[0]) + '}');
- script = script.map(function(line) {
- return line.replace(trimIndent, '');
- });
- var questions = {};
- var current = null;
- var lastIndent = 0;
- var currentIndent = 0;
- var levels = [];
- var indentSpaces = getIndentLength(script[1]);
- if (indentSpaces < 1 || indentSpaces % 2 !== 0) {
- raise('Unexpected indentation at line 2');
- }
- script.forEach(function(line, _i) {
- var _choice = null;
- if (_choice = line.match(/^\d+?\:$/)) {
- current = parseInt(_choice);
- if (questions[current]) {
- raise('Duplicate key for Question #' + current);
- } else {
- questions[current] = {};
- }
- } else {
- currentIndent = getIndentLength(line);
- if (currentIndent % indentSpaces !== 0) {
- raise('Unexpected indentation', _i);
- }
- /* Parse choice */
- if (currentIndent > lastIndent) {
- // enter level
- levels.push(line);
- } else if (currentIndent < lastIndent) {
- // exit levels
- for (var i = 0; i < lastIndent / currentIndent; i++)
- levels.pop();
- levels.push(line);
- } else if (currentIndent === lastIndent) {
- // update level
- levels.pop();
- levels.push(line);
- }
- var levMessage = line.match(/message:\s"(.+?)"$/);
- var levChoices = line.match(/choices:$/);
- if (levMessage) {
- questions[current].message = levMessage[1];
- } else if (levChoices) {
- questions[current].choices = [];
- } else if (currentIndent >= lastIndent) {
- // entered from last level (>) or in same level (===)
- var lastLevel = levels[levels.length - 2];
- if (lastLevel.indexOf('choices') > -1) {
- // entered from choices, add new choice
- var matches = line.match(/^\s+?"(.+?)"\s=>\s(\d+)$/);
- if (!matches) {
- raise('Syntax error', _i);
- }
- questions[current].choices.push({
- next: +matches[2],
- text: matches[1]
- });
- }
- }
- lastIndent = currentIndent;
- }
- });
- // start building ui
- var fragment = document.createDocumentFragment();
- var currentArticle = null;
- var firstArticle = null;
- var articles = {};
- for (var q in questions) {
- var qstn = questions[q];
- var article = document.createElement('article');
- article.qid = q;
- articles[q] = article;
- var section = document.createElement('section');
- // display message
- var msgWrap = document.createElement('div');
- msgWrap.innerHTML = qstn.message;
- msgWrap.className = 'message-container';
- section.appendChild(msgWrap);
- // build buttons
- if (qstn.choices) {
- var buttonsWrap = document.createElement('div');
- buttonsWrap.className = 'buttons-container';
- qstn.choices.forEach(function(c) {
- var button = document.createElement('button');
- button.onclick = function() {
- currentArticle.style.display = 'none';
- currentArticle = articles[c.next];
- history.pushState(c.next, document.title, location.pathname);
- currentArticle.style.display = 'block';
- };
- button.appendChild(document.createTextNode(c.text));
- buttonsWrap.appendChild(button);
- });
- section.appendChild(buttonsWrap);
- }
- article.appendChild(section);
- article.style.display = 'none';
- fragment.appendChild(article);
- // show first
- if (null === currentArticle) {
- currentArticle = firstArticle = article;
- }
- }
- window.onpopstate = function(e) {
- var qid = e.state;
- if (null === qid) {
- qid = firstArticle.qid;
- }
- currentArticle.style.display = 'none';
- currentArticle = articles[qid];
- currentArticle.style.display = 'block';
- };
- container.appendChild(fragment);
- currentArticle.style.display = 'block';
- }();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement