Skip to main content

Ivan Teoh

Something personal yet public

170-exercise65b.js

(Source)

function splitParagraph(paragraph) {
    var paragraphs = [];

    function spliting(first, last, typeString) {
        while (true)  {
            start = paragraph.indexOf(first, 0);
            if (start == -1) {
                break;
            }
            end = paragraph.indexOf(last, start + 1);
            if (end == -1) {
                break;
            }
            // content does not have "*"
            content = paragraph.slice(start, end + 1).slice(1, -1);
            paragraph = paragraph.slice(0,
                            paragraph.charAt(start) == " "? start - 1 :start)
                            .concat(paragraph.slice(end + 1));
            paragraphs.push({'content': content, 'type': typeString});
        }
    }

    // emphasised part
    spliting("*", "*", "emphasised");

    // footnote
    spliting("{", "}", "footnote");

    // normal text
    paragraphs.push({'content': paragraph, 'type': 'normal'});
    return paragraphs;
}

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}

function map(func, array) {
  var result = [];
  forEach(array, function (element) {
    result.push(func(element));
  });
  return result;
}

function tag(name, content, attributes) {
  return {name: name, attributes: attributes, content: content};
}

function link(target, text) {
  return tag("a", [text], {href: target});
}

function footnote(number) {
  return tag("sup", [link("#footnote" + number,
                          String(number))]);
}

function renderFragment(fragment) {
    var content;
    switch (fragment.type) {
        case "emphasised":
            content = tag("em", [fragment.content]);
            break;
        case "footnote":
            content = footnote(fragment.content);
            break;
        //case "normal":
        default:
            content = fragment.content;
            break;
    }
    return content;
}

// {'content': 'A hermit spent ten years writing a program.', 'type': 'p'}
// {'content': 'two and then *square* it again, the {result} is already
// inaccurate!', 'type': 'p'}
function renderParagraph(paragraph) {
    // [{'content': 'square', 'type': 'emphasised'},
    //  {'content': 'result', 'type': 'footnote'},
    //  {'content': 'two and then it again, the is already inaccurate!',
    //   'type': 'normal'}]
    fragments = splitParagraph(paragraph.content);
    return tag(paragraph.type, map(renderFragment, fragments));
}

console.log(renderParagraph({'content': 'two and then *square* it again, the ' +
'{result} is already inaccurate!', 'type': 'p'}));