src/Pure/Thy/html.scala
author wenzelm
Sun, 25 Nov 2012 19:49:24 +0100
changeset 50201 c26369c9eda6
parent 49650 9fad6480300d
child 50707 5b2bf7611662
permissions -rw-r--r--
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Thy/html.scala
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     3
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     4
Basic HTML output.
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     5
*/
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     6
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     7
package isabelle
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
     8
34000
1fecda948697 more robust treatment of line breaks -- Java "split" has off semantics;
wenzelm
parents: 33984
diff changeset
     9
import scala.collection.mutable.ListBuffer
1fecda948697 more robust treatment of line breaks -- Java "split" has off semantics;
wenzelm
parents: 33984
diff changeset
    10
1fecda948697 more robust treatment of line breaks -- Java "split" has off semantics;
wenzelm
parents: 33984
diff changeset
    11
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    12
object HTML
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    13
{
37200
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    14
  // encode text
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    15
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    16
  def encode(text: String): String =
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    17
  {
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    18
    val s = new StringBuilder
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    19
    for (c <- text.iterator) c match {
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    20
      case '<' => s ++= "&lt;"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    21
      case '>' => s ++= "&gt;"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    22
      case '&' => s ++= "&amp;"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    23
      case '"' => s ++= "&quot;"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    24
      case '\'' => s ++= "&#39;"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    25
      case '\n' => s ++= "<br/>"
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    26
      case _ => s += c
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    27
    }
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    28
    s.toString
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    29
  }
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    30
0f3edc64356a added HTML.encode (in Scala), similar to HTML.output in ML;
wenzelm
parents: 36016
diff changeset
    31
49613
2f6986e2ef06 removed obsolete org.w3c.dom operations;
wenzelm
parents: 46865
diff changeset
    32
  /// FIXME unused stuff
2f6986e2ef06 removed obsolete org.w3c.dom operations;
wenzelm
parents: 46865
diff changeset
    33
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    34
  // common elements and attributes
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    35
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    36
  val BODY = "body"
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    37
  val DIV = "div"
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    38
  val SPAN = "span"
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    39
  val BR = "br"
34000
1fecda948697 more robust treatment of line breaks -- Java "split" has off semantics;
wenzelm
parents: 33984
diff changeset
    40
  val PRE = "pre"
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    41
  val CLASS = "class"
43490
5e6f76cacb93 more uniform treatment of recode_set/recode_map;
wenzelm
parents: 43489
diff changeset
    42
  val STYLE = "style"
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    43
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    44
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    45
  // document markup
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
    46
38573
d163f0f28e8c tuned signatures;
wenzelm
parents: 38444
diff changeset
    47
  def span(cls: String, body: XML.Body): XML.Elem =
38230
ed147003de4b simplified type XML.Tree: embed Markup directly, avoid slightly odd triple;
wenzelm
parents: 37200
diff changeset
    48
    XML.Elem(Markup(SPAN, List((CLASS, cls))), body)
34002
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    49
43490
5e6f76cacb93 more uniform treatment of recode_set/recode_map;
wenzelm
parents: 43489
diff changeset
    50
  def user_font(font: String, txt: String): XML.Elem =
5e6f76cacb93 more uniform treatment of recode_set/recode_map;
wenzelm
parents: 43489
diff changeset
    51
    XML.Elem(Markup(SPAN, List((STYLE, "font-family: " + font))), List(XML.Text(txt)))
5e6f76cacb93 more uniform treatment of recode_set/recode_map;
wenzelm
parents: 43489
diff changeset
    52
34002
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    53
  def hidden(txt: String): XML.Elem =
50201
c26369c9eda6 Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents: 49650
diff changeset
    54
    span(Markup.HIDDEN, List(XML.Text(txt)))
34002
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    55
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    56
  def sub(txt: String): XML.Elem = XML.elem("sub", List(XML.Text(txt)))
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    57
  def sup(txt: String): XML.Elem = XML.elem("sup", List(XML.Text(txt)))
43459
wenzelm
parents: 43458
diff changeset
    58
  def bold(txt: String): XML.Elem = span("bold", List(XML.Text(txt)))
34002
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    59
49613
2f6986e2ef06 removed obsolete org.w3c.dom operations;
wenzelm
parents: 46865
diff changeset
    60
  def spans(input: XML.Tree): XML.Body =
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    61
  {
38573
d163f0f28e8c tuned signatures;
wenzelm
parents: 38444
diff changeset
    62
    def html_spans(tree: XML.Tree): XML.Body =
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    63
      tree match {
49650
9fad6480300d support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents: 49613
diff changeset
    64
        case XML.Wrapped_Elem(markup, _, ts) =>
9fad6480300d support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents: 49613
diff changeset
    65
          List(span(markup.name, ts.flatMap(html_spans)))
9fad6480300d support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents: 49613
diff changeset
    66
        case XML.Elem(markup, ts) =>
9fad6480300d support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents: 49613
diff changeset
    67
          List(span(markup.name, ts.flatMap(html_spans)))
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    68
        case XML.Text(txt) =>
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    69
          val ts = new ListBuffer[XML.Tree]
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    70
          val t = new StringBuilder
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    71
          def flush() {
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    72
            if (!t.isEmpty) {
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    73
              ts += XML.Text(t.toString)
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    74
              t.clear
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    75
            }
34000
1fecda948697 more robust treatment of line breaks -- Java "split" has off semantics;
wenzelm
parents: 33984
diff changeset
    76
          }
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    77
          def add(elem: XML.Tree) {
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    78
            flush()
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    79
            ts += elem
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    80
          }
43675
8252d51d70e2 simplified Symbol.iterator: produce strings, which are mostly preallocated;
wenzelm
parents: 43661
diff changeset
    81
          val syms = Symbol.iterator(txt)
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    82
          while (syms.hasNext) {
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    83
            val s1 = syms.next
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    84
            def s2() = if (syms.hasNext) syms.next else ""
43455
4b4b93672f15 some unicode chars for special control symbols;
wenzelm
parents: 38573
diff changeset
    85
            if (s1 == "\n") add(XML.elem(BR))
44238
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    86
            else if (s1 == Symbol.sub_decoded || s1 == Symbol.isub_decoded)
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    87
              { add(hidden(s1)); add(sub(s2())) }
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    88
            else if (s1 == Symbol.sup_decoded || s1 == Symbol.isup_decoded)
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    89
              { add(hidden(s1)); add(sup(s2())) }
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    90
            else if (s1 == Symbol.bsub_decoded) t ++= s1  // FIXME
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    91
            else if (s1 == Symbol.esub_decoded) t ++= s1  // FIXME
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    92
            else if (s1 == Symbol.bsup_decoded) t ++= s1  // FIXME
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    93
            else if (s1 == Symbol.esup_decoded) t ++= s1  // FIXME
36120feb70ed some convenience actions/shortcuts for control symbols;
wenzelm
parents: 43695
diff changeset
    94
            else if (s1 == Symbol.bold_decoded) { add(hidden(s1)); add(bold(s2())) }
43695
5130dfe1b7be simplified Symbol based on lazy Symbol.Interpretation -- reduced odd "functorial style";
wenzelm
parents: 43675
diff changeset
    95
            else if (Symbol.fonts.isDefinedAt(s1)) { add(user_font(Symbol.fonts(s1), s1)) }
43455
4b4b93672f15 some unicode chars for special control symbols;
wenzelm
parents: 38573
diff changeset
    96
            else t ++= s1
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    97
          }
34002
cbeeef3aebb3 basic treatment of special control symbols;
wenzelm
parents: 34000
diff changeset
    98
          flush()
38444
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
    99
          ts.toList
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
   100
      }
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
   101
    html_spans(input)
796904799f4d HTML.spans: explicit flag for preservation of original data (which would be turned into org.w3c.dom user data in XML.document_node);
wenzelm
parents: 38231
diff changeset
   102
  }
33984
c54498f88a77 Basic HTML output.
wenzelm
parents:
diff changeset
   103
}