src/Pure/Isar/document_structure.scala
author wenzelm
Thu, 04 Aug 2016 11:32:21 +0200
changeset 63605 c7916060f55e
parent 63604 d8de4f8b95eb
child 63606 fc3a23763617
permissions -rw-r--r--
tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Isar/document_structure.scala
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     3
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     4
Overall document structure.
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     5
*/
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     6
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     7
package isabelle
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     8
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
     9
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    10
import scala.collection.mutable
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    11
import scala.annotation.tailrec
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    12
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    13
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    14
object Document_Structure
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    15
{
63605
wenzelm
parents: 63604
diff changeset
    16
  /* general structure */
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    17
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    18
  sealed abstract class Document { def length: Int }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    19
  case class Block(name: String, text: String, body: List[Document]) extends Document
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    20
  { val length: Int = (0 /: body)(_ + _.length) }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    21
  case class Atom(command: Command) extends Document
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    22
  { def length: Int = command.length }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    23
63605
wenzelm
parents: 63604
diff changeset
    24
wenzelm
parents: 63604
diff changeset
    25
  /* section headings etc. */
wenzelm
parents: 63604
diff changeset
    26
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    27
  def heading_level(keywords: Keyword.Keywords, command: Command): Option[Int] =
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    28
  {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    29
    val name = command.span.name
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    30
    name match {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    31
      case Thy_Header.CHAPTER => Some(0)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    32
      case Thy_Header.SECTION => Some(1)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    33
      case Thy_Header.SUBSECTION => Some(2)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    34
      case Thy_Header.SUBSUBSECTION => Some(3)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    35
      case Thy_Header.PARAGRAPH => Some(4)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    36
      case Thy_Header.SUBPARAGRAPH => Some(5)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    37
      case _ =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    38
        keywords.kinds.get(name) match {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    39
          case Some(kind) if Keyword.theory(kind) && !Keyword.theory_end(kind) => Some(6)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    40
          case _ => None
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    41
        }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    42
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    43
  }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    44
63605
wenzelm
parents: 63604
diff changeset
    45
  def parse_sections(
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    46
    syntax: Outer_Syntax,
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    47
    node_name: Document.Node.Name,
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    48
    text: CharSequence): List[Document] =
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    49
  {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    50
    /* stack operations */
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    51
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    52
    def buffer(): mutable.ListBuffer[Document] =
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    53
      new mutable.ListBuffer[Document]
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    54
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    55
    var stack: List[(Int, Command, mutable.ListBuffer[Document])] =
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    56
      List((0, Command.empty, buffer()))
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    57
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    58
    @tailrec def close(level: Int => Boolean)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    59
    {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    60
      stack match {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    61
        case (lev, command, body) :: (_, _, body2) :: rest if level(lev) =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    62
          body2 += Block(command.span.name, command.source, body.toList)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    63
          stack = stack.tail
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    64
          close(level)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    65
        case _ =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    66
      }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    67
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    68
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    69
    def result(): List[Document] =
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    70
    {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    71
      close(_ => true)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    72
      stack.head._3.toList
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    73
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    74
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    75
    def add(command: Command)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    76
    {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    77
      heading_level(syntax.keywords, command) match {
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    78
        case Some(i) =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    79
          close(_ > i)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    80
          stack = (i + 1, command, buffer()) :: stack
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    81
        case None =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    82
      }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    83
      stack.head._3 += Atom(command)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    84
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    85
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    86
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    87
    /* result structure */
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    88
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    89
    val spans = syntax.parse_spans(text)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    90
    spans.foreach(span => add(Command(Document_ID.none, node_name, Command.no_blobs, span)))
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    91
    result()
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    92
  }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    93
}