const fs = require('fs')
    , path = require('path')
    , linkRe = /(?:\{([^\{]+)\})/g
    , termRe = /^:(.+):/
    , patternLineRe = /^\t([\.\*]+)$/
    , mainSectionDividerRe = /^(\-)+$/
    , periodRe = /\(p(\d+)\)/
    , emptyLineRe = /^\s*$/

const findSections = dividerRe => lines => {
  return lines.reduce((sections, line) => {
    if (dividerRe.test(line)) return sections.concat([[ line ]])
    last(sections).push(line)
    return sections
  }, [[]])
}

const findMainSections = findSections(mainSectionDividerRe)
    , findContentSections = findSections(termRe)

module.exports.parse = lines => {
  const terms = findTerms(lines)
  // return 'ok'
  return terms
}

function findTerms(lines) {
  const contentLines = findMainSections(lines)[1]
  return findContentSections(contentLines).map(parseTerm)
}

function parseTerm(lines) {
  return lines.reduce((term, line) => {
    addTerm(term, line)
    addPeriod(term, line)
    addDescription(term, line)
    addLinks(term, line)
    addPatternLine(term, line)
    addPatternDimensions(term)
    return term
  }, {})
}

function addTerm(term, line) {
  const matches = termRe.exec(line)
  if (!matches) return
  term.term = matches[1]
}

function addPeriod(term, line) {
  const matches = periodRe.exec(line)
  if (!matches) return
  term.period = parseInt(matches[1])
}

function addDescription(term, line) {
  const isEmptyLine = emptyLineRe.test(line)
      , isPatternLine = patternLineRe.test(line)

  if (isEmptyLine || isPatternLine) return
  term.description = (term.description || '') + line
}

function addLinks(term, line) {
  const links = findLinks(line)
  if (!links.length) return
  term.links = (term.links || []).concat(links)
}

function findLinks(line) {
  let matches
  const links = []
  while ((matches = linkRe.exec(line)) != null) links.push(matches[1])
  return links
}

function addPatternLine(term, line) {
  const matches = patternLineRe.exec(line)
  if (!matches) return
  term.pattern = (term.pattern || []).concat(toPatternLine(matches))
}

function addPatternDimensions(term) {
  if (!term.pattern) return
  term.width = term.pattern[0].length
  term.height = term.pattern.length
}

function toPatternLine(matches) {
  return [ matches[1].split('').map( toBinary ) ]
}

function toBinary(char) {
  return { '.': 0, '*': 1 }[char]
}

function last(array) {
  return array[array.length - 1]
}

@@ -617,20 +617,23 @@
 nst 
-term
+section
 s = find
 Term
@@ -624,28 +624,35 @@
 tions = find
-Term
+MainSection
 s(lines)%0A  /
@@ -653,19 +653,16 @@
 s)%0A 
- //
  return 
 'ok'
@@ -661,105 +661,136 @@
 urn 
-'ok'%0A  return terms%0A%7D%0A%0Afunction findTerms(lines) %7B%0A  const contentLines = findMainSection
+%7B%0A    introduction: sections%5B0%5D%0A  , terms: findTerms(sections%5B1%5D)%0A  , bibliography: sections%5B2%5D%0A  %7D%0A%7D%0A%0Afunction findTerm
 s(lines)
 %5B1%5D%0A
@@ -785,19 +785,18 @@
 s(lines)
-%5B1%5D
+ %7B
 %0A  retur
@@ -821,16 +821,9 @@
 ons(
-contentL
+l
 ines
@@ -1051,39 +1051,8 @@
 ne)%0A
-    addPatternDimensions(term)%0A
     
@@ -1551,20 +1551,275 @@
 %7C '') + 
-line
+cleanDescriptionLine(line) + ' '%0A%7D%0A%0Afunction cleanDescriptionLine(line) %7B%0A  return line%0A    .replace(/%5C%7B/g, '')%0A    .replace(/%5C%7D/g, '')%0A    .replace(periodRe, '')%0A    .replace(termRe, '')%0A    .replace(/  +/g, ' ')%0A    .replace(/%5E /, '')%0A    .replace(/ $/, '')
 %0A%7D%0A%0Afunc
@@ -2283,77 +2283,8 @@
 s))%0A
-%7D%0A%0Afunction addPatternDimensions(term) %7B%0A  if (!term.pattern) return%0A
   te
@@ -2353,16 +2353,40 @@
 .length%0A
+  term.isPattern = true%0A
 %7D%0A%0Afunct

Clean description lines + include all sections