| author | wenzelm | 
| Fri, 11 Nov 2022 23:04:55 +0100 | |
| changeset 76508 | ecb9e6d29698 | 
| child 76510 | b0ad975cd25b | 
| permissions | -rw-r--r-- | 
| 
76508
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
1  | 
/* Title: Pure/Tools/prismjs.scala  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
2  | 
Author: Makarius  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
4  | 
Support for the Prism.js syntax highlighter -- via external Node.js process.  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*/  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
7  | 
package isabelle  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
8  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
9  | 
import scala.collection.mutable  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
10  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
11  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
12  | 
object Prismjs {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
13  | 
/* component resources */  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
14  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
15  | 
  val HOME: Path = Path.explode("$ISABELLE_PRISMJS_HOME")
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
16  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
17  | 
  lazy val available_languages: List[String] = {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
18  | 
    val components_path = HOME + Path.explode("components.json")
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
19  | 
val components_json = JSON.parse(File.read(components_path))  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
20  | 
    JSON.value(components_json, "languages") match {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
21  | 
case Some(JSON.Object(langs)) =>  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
22  | 
        (for ((lang, JSON.Object(info)) <- langs.iterator if lang != "meta") yield {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
23  | 
val alias =  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
            JSON.Value.List.unapply(info.getOrElse("alias", Nil), JSON.Value.String.unapply)
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
25  | 
.getOrElse(Nil)  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
26  | 
lang :: alias  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
27  | 
}).toList.flatten.sorted  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
28  | 
      case _ => error("Failed to determine languages from " + components_path)
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
29  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
30  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
31  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
32  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
33  | 
/* JavaScript prelude */  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
34  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
35  | 
def prelude(lang: JS.Source): JS.Source =  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
36  | 
cat_lines(List(  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
37  | 
Nodejs.require_fs,  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
38  | 
      Nodejs.require_path("prismjs", HOME),
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
39  | 
      Nodejs.require_path("prismjs_load", HOME + Path.explode("components"), dir = true),
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
40  | 
      JS.function("prismjs_load", lang),
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
41  | 
"""  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
42  | 
function prismjs_content(t) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
43  | 
  if (Array.isArray(t)) { return t.map(prismjs_content).join() }
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
44  | 
  else if (t instanceof prismjs.Token) { return prismjs_content(t.content) }
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
45  | 
  else { return t }
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
46  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
47  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
48  | 
function prismjs_tokenize(text, lang) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
49  | 
  return prismjs.tokenize(text, prismjs.languages[lang]).map(function (t) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
50  | 
    if (t instanceof prismjs.Token) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
51  | 
      return {"kind": t.type, "content": prismjs_content(t)}
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
52  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
53  | 
    else { return {"kind": "", "content": t} }
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
54  | 
})  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
55  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
56  | 
"""))  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
57  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
58  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
59  | 
/* tokenize */  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
60  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
61  | 
sealed case class Token(  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
62  | 
kind: String,  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
63  | 
content: String,  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
64  | 
range: Text.Range = Text.Range.zero)  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
65  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
66  | 
  def tokenize(text: String, language: String): List[Token] = {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
67  | 
    if (!available_languages.contains(language)) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
68  | 
      error("Unknown language " + quote(language))
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
69  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
70  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
71  | 
val json =  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
72  | 
      Isabelle_System.with_tmp_file("input", ext = "json") { input =>
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
73  | 
        Isabelle_System.with_tmp_file("output", ext = "json") { output =>
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
74  | 
File.write(input, text)  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
75  | 
val lang = JS.value(language)  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
76  | 
Nodejs.execute(  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
77  | 
prelude(lang) + "\n" +  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
78  | 
Nodejs.write_file(output,  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
79  | 
              JS.json_print(JS.function("prismjs_tokenize", Nodejs.read_file(input), lang))))
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
80  | 
JSON.parse(File.read(output))  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
81  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
82  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
83  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
84  | 
def parse_token(t: JSON.T): Token =  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
85  | 
      (for {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
86  | 
kind <- JSON.string(t, "kind")  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
87  | 
content <- JSON.string(t, "content")  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
88  | 
      } yield Token(kind, content)).getOrElse(error("Malformed JSON token: " + t))
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
89  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
90  | 
val tokens0 =  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
91  | 
JSON.Value.List.unapply(json, t => Some(parse_token(t)))  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
92  | 
        .getOrElse(error("Malformed JSON: array expected"))
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
93  | 
|
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
94  | 
var stop = 0  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
95  | 
val tokens = new mutable.ListBuffer[Token]  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
96  | 
    for (tok <- tokens0) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
97  | 
val start = stop  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
98  | 
stop += tok.content.length  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
99  | 
      if (tok.kind.nonEmpty) {
 | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
100  | 
tokens += tok.copy(range = Text.Range(start, stop))  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
101  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
102  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
103  | 
tokens.toList  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
104  | 
}  | 
| 
 
ecb9e6d29698
support for the Prism.js syntax highlighter -- via external Node.js process;
 
wenzelm 
parents:  
diff
changeset
 | 
105  | 
}  |