src/Pure/Isar/document_structure.scala
author wenzelm
Thu, 06 Jun 2024 12:42:42 +0200
changeset 80267 ea908185a597
parent 78912 ff4496b25197
permissions -rw-r--r--
more operations;
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
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    14
object Document_Structure {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
    15
  /** general structure **/
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    16
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    17
  sealed abstract class Document { def length: Int }
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    18
  case class Block(name: String, text: String, body: List[Document]) extends Document {
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    19
    val length: Int = body.foldLeft(0)(_ + _.length)
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    20
  }
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
    21
  case class Atom(length: Int) extends Document
63605
wenzelm
parents: 63604
diff changeset
    22
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    23
  def is_theory_command(command: Command): Boolean =
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    24
    command.span.is_keyword_kind(kind => Keyword.theory(kind) && !Keyword.theory_end(kind))
63605
wenzelm
parents: 63604
diff changeset
    25
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    26
  def is_document_command(command: Command): Boolean =
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    27
    command.span.is_keyword_kind(Keyword.document)
70148
73a34cb9e67e tuned signature: more operations;
wenzelm
parents: 69869
diff changeset
    28
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    29
  def is_diag_command(command: Command): Boolean =
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    30
    command.span.is_keyword_kind(Keyword.diag)
71165
03afc8252225 support for output messages;
wenzelm
parents: 70148
diff changeset
    31
69869
f2c3512df446 tuned signature;
wenzelm
parents: 69860
diff changeset
    32
  def is_heading_command(command: Command): Boolean =
f2c3512df446 tuned signature;
wenzelm
parents: 69860
diff changeset
    33
    proper_heading_level(command).isDefined
f2c3512df446 tuned signature;
wenzelm
parents: 69860
diff changeset
    34
69860
b58a575d211e tuned signature;
wenzelm
parents: 69859
diff changeset
    35
  def proper_heading_level(command: Command): Option[Int] =
69859
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    36
    command.span.name match {
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    37
      case Thy_Header.CHAPTER => Some(0)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    38
      case Thy_Header.SECTION => Some(1)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    39
      case Thy_Header.SUBSECTION => Some(2)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    40
      case Thy_Header.SUBSUBSECTION => Some(3)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    41
      case Thy_Header.PARAGRAPH => Some(4)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    42
      case Thy_Header.SUBPARAGRAPH => Some(5)
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    43
      case _ => None
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    44
    }
69860
b58a575d211e tuned signature;
wenzelm
parents: 69859
diff changeset
    45
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    46
  def heading_level(command: Command): Option[Int] =
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    47
    proper_heading_level(command) orElse (if (is_theory_command(command)) Some(6) else None)
69859
e18ba60a1cf8 clarified signature -- allow more re-use;
wenzelm
parents: 68845
diff changeset
    48
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
    49
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    50
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
    51
  /** context blocks **/
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    52
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    53
  def parse_blocks(
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    54
    syntax: Outer_Syntax,
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    55
    node_name: Document.Node.Name,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    56
    text: CharSequence
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    57
  ): List[Document] = {
63607
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    58
    def is_plain_theory(command: Command): Boolean =
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
    59
      is_theory_command(command) && !command.span.is_begin && !command.span.is_end
63607
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    60
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    61
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    62
    /* stack operations */
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    63
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    64
    def buffer(): mutable.ListBuffer[Document] = new mutable.ListBuffer[Document]
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    65
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    66
    var stack: List[(Command, mutable.ListBuffer[Document])] =
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    67
      List((Command.empty, buffer()))
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    68
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72814
diff changeset
    69
    def open(command: Command): Unit = { stack = (command, buffer()) :: stack }
63607
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    70
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    71
    def close(): Boolean =
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    72
      stack match {
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    73
        case (command, body) :: (_, body2) :: _ =>
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    74
          body2 += Block(command.span.name, command.source, body.toList)
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    75
          stack = stack.tail
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    76
          true
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    77
        case _ =>
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    78
          false
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    79
      }
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    80
73340
0ffcad1f6130 tuned --- fewer warnings;
wenzelm
parents: 72814
diff changeset
    81
    def flush(): Unit = if (is_plain_theory(stack.head._1)) close()
63607
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    82
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    83
    def result(): List[Document] = {
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    84
      while (close()) { }
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    85
      stack.head._2.toList
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    86
    }
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    87
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
    88
    def add(command: Command): Unit = {
63607
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    89
      if (command.span.is_begin || is_plain_theory(command)) { flush(); open(command) }
7246254d558f clarified handling of plain theory commands;
wenzelm
parents: 63606
diff changeset
    90
      else if (command.span.is_end) { flush(); close() }
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    91
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
    92
      stack.head._2 += Atom(command.source.length)
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    93
    }
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    94
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    95
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    96
    /* result structure */
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    97
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
    98
    val spans = syntax.parse_spans(text)
76914
1bc50ffad6d2 tuned signature;
wenzelm
parents: 75393
diff changeset
    99
    spans.foreach(span => add(Command(Document_ID.none, node_name, Command.Blobs_Info.empty, span)))
63606
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
   100
    result()
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
   101
  }
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
   102
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
   103
fc3a23763617 support for context block structure in Sidekick;
wenzelm
parents: 63605
diff changeset
   104
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   105
  /** section headings **/
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   106
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   107
  trait Item {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   108
    def name: String = ""
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   109
    def source: String = ""
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   110
    def heading_level: Option[Int] = None
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   111
  }
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   112
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   113
  object No_Item extends Item
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   114
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   115
  class Sections {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   116
    private def buffer(): mutable.ListBuffer[Document] = new mutable.ListBuffer[Document]
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   117
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   118
    private var stack: List[(Int, Item, mutable.ListBuffer[Document])] =
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   119
      List((0, No_Item, buffer()))
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   120
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   121
    @tailrec private def close(level: Int => Boolean): Unit = {
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   122
      stack match {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   123
        case (lev, item, body) :: (_, _, body2) :: _ if level(lev) =>
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   124
          body2 += Block(item.name, item.source, body.toList)
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   125
          stack = stack.tail
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   126
          close(level)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   127
        case _ =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   128
      }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   129
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   130
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   131
    def result(): List[Document] = {
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   132
      close(_ => true)
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   133
      stack.head._3.toList
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   134
    }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   135
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   136
    def add(item: Item): Unit = {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   137
      item.heading_level match {
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   138
        case Some(i) =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   139
          close(_ > i)
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   140
          stack = (i + 1, item, buffer()) :: stack
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   141
        case None =>
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   142
      }
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   143
      stack.head._3 += Atom(item.source.length)
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   144
    }
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   145
  }
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   146
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   147
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   148
  /* outer syntax sections */
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   149
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   150
  private class Command_Item(command: Command) extends Item {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   151
    override def name: String = command.span.name
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   152
    override def source: String = command.source
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   153
    override def heading_level: Option[Int] = Document_Structure.heading_level(command)
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   154
  }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   155
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   156
  def parse_sections(
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   157
    syntax: Outer_Syntax,
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   158
    node_name: Document.Node.Name,
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   159
    text: CharSequence
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   160
  ): List[Document] = {
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   161
    val sections = new Sections
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   162
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   163
    for { span <- syntax.parse_spans(text) } {
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   164
      sections.add(
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   165
        new Command_Item(Command(Document_ID.none, node_name, Command.Blobs_Info.empty, span)))
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   166
    }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   167
    sections.result()
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   168
  }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   169
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   170
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   171
  /* ML sections */
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   172
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   173
  private class ML_Item(token: ML_Lex.Token, level: Option[Int]) extends Item {
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   174
    override def source: String = token.source
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   175
    override def heading_level: Option[Int] = level
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   176
  }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   177
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   178
  def parse_ml_sections(SML: Boolean, text: CharSequence): List[Document] = {
78912
ff4496b25197 clarified signature: Command_Span.Kind already contains keyword_kind, so parsing document structure no longer requires Keyword.Keywords;
wenzelm
parents: 76914
diff changeset
   179
    val sections = new Sections
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   180
    val nl = new ML_Item(ML_Lex.Token(ML_Lex.Kind.SPACE, "\n"), None)
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   181
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   182
    var context: Scan.Line_Context = Scan.Finished
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   183
    for (line <- Library.separated_chunks(_ == '\n', text)) {
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   184
      val (toks, next_context) = ML_Lex.tokenize_line(SML, line, context)
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   185
      val level =
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   186
        toks.filterNot(_.is_space) match {
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   187
          case List(tok) if tok.is_comment =>
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   188
            val s = tok.source
75393
87ebf5a50283 clarified formatting, for the sake of scala3;
wenzelm
parents: 73359
diff changeset
   189
            if (Codepoint.iterator(s).exists(c => Character.isLetter(c) || Character.isDigit(c))) {
63666
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   190
              if (s.startsWith("(**** ") && s.endsWith(" ****)")) Some(0)
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   191
              else if (s.startsWith("(*** ") && s.endsWith(" ***)")) Some(1)
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   192
              else if (s.startsWith("(** ") && s.endsWith(" **)")) Some(2)
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   193
              else if (s.startsWith("(* ") && s.endsWith(" *)")) Some(3)
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   194
              else None
ff6caffcaed4 suppress ASCII art;
wenzelm
parents: 63610
diff changeset
   195
            }
63610
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   196
            else None
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   197
          case _ => None
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   198
        }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   199
      if (level.isDefined && context == Scan.Finished && next_context == Scan.Finished)
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   200
        toks.foreach(tok => sections.add(new ML_Item(tok, if (tok.is_comment) level else None)))
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   201
      else
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   202
        toks.foreach(tok => sections.add(new ML_Item(tok, None)))
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   203
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   204
      sections.add(nl)
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   205
      context = next_context
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   206
    }
4b40b8196dc7 Sidekick parser for isabelle-ml and sml mode;
wenzelm
parents: 63607
diff changeset
   207
    sections.result()
63604
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   208
  }
d8de4f8b95eb clarified modules;
wenzelm
parents:
diff changeset
   209
}