///|
/// Title pages end at the first blank line. Unknown keys are preserved.
fn title_pair(text : String) -> (String, String)? {
  match text.find(":") {
    Some(i) => {
      let key = stripped(text[:i].to_owned())
      if key == "" ||
        !key
        .to_array()
        .all(fn(c) {
          (c >= 'A' && c <= 'Z') ||
          (c >= 'a' && c <= 'z') ||
          c == ' ' ||
          c == '-'
        }) {
        return None
      }
      Some((key.to_lower(), stripped(text[i + 1:].to_owned())))
    }
    None => None
  }
}

///|
fn parse_title(lines : Array[SourceLine], elements : Array[Element]) -> Int {
  let first = title_pair(lines[0].content())
  let recognized = match first {
    Some((key, _)) =>
      [
        "title", "credit", "author", "authors", "source", "draft date", "date", "contact",
        "copyright", "notes",
      ].contains(key)
    None => false
  }
  if !recognized {
    return 0
  }
  let mut i = 0
  let mut key = ""
  while i < lines.length() {
    let line = lines[i]
    let raw = line.content()
    if stripped(raw) == "" {
      break
    }
    if raw.has_prefix("   ") || raw.has_prefix("\t") {
      elements.push(element(line, TitleField, stripped(raw), detail=key))
    } else {
      match title_pair(raw) {
        Some((k, value)) => {
          key = k
          elements.push(element(line, TitleField, value, detail=key))
        }
        None => break
      }
    }
    i += 1
  }
  i
}

///|
/// Ordered values retain repeated keys and continuation lines.
pub fn title_values(doc : Document, key : String) -> Array[String] {
  doc.elements
  .filter(fn(e) { e.kind == TitleField && e.detail == key.to_lower() })
  .map(fn(e) { e.text })
}