From 2d08fa9013b8401bd910d327ffbc82b735508c97 Mon Sep 17 00:00:00 2001 From: Golmote Date: Sat, 10 Oct 2015 21:32:45 +0200 Subject: [PATCH] Add support for Icon --- components.js | 4 + components/prism-icon.js | 17 ++ components/prism-icon.min.js | 1 + examples/prism-icon.html | 186 ++++++++++++++++++ .../icon/builtin-keyword_feature.test | 91 +++++++++ tests/languages/icon/comment_feature.test | 13 ++ tests/languages/icon/directive_feature.test | 21 ++ tests/languages/icon/function_feature.test | 15 ++ tests/languages/icon/keyword_feature.test | 67 +++++++ tests/languages/icon/number_feature.test | 33 ++++ tests/languages/icon/operator_feature.test | 69 +++++++ tests/languages/icon/string_feature.test | 22 +++ 12 files changed, 539 insertions(+) create mode 100644 components/prism-icon.js create mode 100644 components/prism-icon.min.js create mode 100644 examples/prism-icon.html create mode 100644 tests/languages/icon/builtin-keyword_feature.test create mode 100644 tests/languages/icon/comment_feature.test create mode 100644 tests/languages/icon/directive_feature.test create mode 100644 tests/languages/icon/function_feature.test create mode 100644 tests/languages/icon/keyword_feature.test create mode 100644 tests/languages/icon/number_feature.test create mode 100644 tests/languages/icon/operator_feature.test create mode 100644 tests/languages/icon/string_feature.test diff --git a/components.js b/components.js index c33e015fe5..d28585a374 100644 --- a/components.js +++ b/components.js @@ -223,6 +223,10 @@ var components = { "title": "HTTP", "owner": "danielgtaylor" }, + "icon": { + "title": "Icon", + "owner": "Golmote" + }, "inform7": { "title": "Inform 7", "owner": "Golmote" diff --git a/components/prism-icon.js b/components/prism-icon.js new file mode 100644 index 0000000000..96e5ac45f0 --- /dev/null +++ b/components/prism-icon.js @@ -0,0 +1,17 @@ +Prism.languages.icon = { + 'comment': /#.*/, + 'string': /(["'])(?:(?!\1)[^\\\r\n]|\\.|_(?:\r?\n|\r))*\1/, + 'number': /\b(?:\d+r[a-z\d]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b|\.\d+\b/i, + 'builtin-keyword': { + pattern: /&(?:allocated|ascii|clock|collections|cset|current|date|dateline|digits|dump|e|error(?:number|text|value)?|errout|fail|features|file|host|input|lcase|letters|level|line|main|null|output|phi|pi|pos|progname|random|regions|source|storage|subject|time|trace|ucase|version)\b/, + alias: 'variable' + }, + 'directive': { + pattern: /\$\w+/, + alias: 'builtin' + }, + 'keyword': /\b(?:break|by|case|create|default|do|else|end|every|fail|global|if|initial|invocable|link|local|next|not|of|procedure|record|repeat|return|static|suspend|then|to|until|while)\b/, + 'function': /(?!\d)\w+(?=\s*[({]|\s*!\s*\[)/, + 'operator': /[+-]:(?!=)|(?:[\/?@^%&]|\+\+?|--?|==?=?|~==?=?|\*\*?|\|\|\|?|<(?:->?|>?=?)(?::=)?|:(?:=:?)?|[!.\\|~]/, + 'punctuation': /[\[\](){},;]/ +}; \ No newline at end of file diff --git a/components/prism-icon.min.js b/components/prism-icon.min.js new file mode 100644 index 0000000000..4c55b55630 --- /dev/null +++ b/components/prism-icon.min.js @@ -0,0 +1 @@ +Prism.languages.icon={comment:/#.*/,string:/(["'])(?:(?!\1)[^\\\r\n]|\\.|_(?:\r?\n|\r))*\1/,number:/\b(?:\d+r[a-z\d]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)\b|\.\d+\b/i,"builtin-keyword":{pattern:/&(?:allocated|ascii|clock|collections|cset|current|date|dateline|digits|dump|e|error(?:number|text|value)?|errout|fail|features|file|host|input|lcase|letters|level|line|main|null|output|phi|pi|pos|progname|random|regions|source|storage|subject|time|trace|ucase|version)\b/,alias:"variable"},directive:{pattern:/\$\w+/,alias:"builtin"},keyword:/\b(?:break|by|case|create|default|do|else|end|every|fail|global|if|initial|invocable|link|local|next|not|of|procedure|record|repeat|return|static|suspend|then|to|until|while)\b/,"function":/(?!\d)\w+(?=\s*[({]|\s*!\s*\[)/,operator:/[+-]:(?!=)|(?:[\/?@^%&]|\+\+?|--?|==?=?|~==?=?|\*\*?|\|\|\|?|<(?:->?|>?=?)(?::=)?|:(?:=:?)?|[!.\\|~]/,punctuation:/[\[\](){},;]/}; \ No newline at end of file diff --git a/examples/prism-icon.html b/examples/prism-icon.html new file mode 100644 index 0000000000..8fb01af54c --- /dev/null +++ b/examples/prism-icon.html @@ -0,0 +1,186 @@ +

Icon

+

To use this language, use the class "language-icon".

+ +

Comments

+
#
+# Foobar
+ +

Strings and csets

+
""
+"Foo\"bar"
+''
+'a\'bcdefg'
+ +

Numbers

+
42
+3.14159
+5.2E+8
+16rface
+2r1101
+ +

Full example

+
# Author: Robert J. Alexander
+global GameObject, Tree, Learn
+record Question(question, yes, no)
+procedure main()
+   GameObject := "animal"
+   Tree := Question("Does it live in water", "goldfish", "canary")
+   Get()                                  # Recall prior knowledge
+   Game()                                 # Play a game
+   return
+end
+#  Game() -- Conducts a game.
+#
+procedure Game()
+   while Confirm("Are you thinking of ", Article(GameObject), " ",
+      GameObject) do Ask(Tree)
+   write("Thanks for a great game.")
+   if \Learn &Confirm("Want to save knowledge learned this session")
+   then Save()
+   return
+end
+#  Confirm() -- Handles yes/no questions and answers.
+#
+procedure Confirm(q[])
+   local answer, s
+   static ok
+   initial {
+      ok := table()
+      every ok["y" | "yes" | "yeah" | "uh huh"] := "yes"
+      every ok["n" | "no"  | "nope" | "uh uh" ] := "no"
+      }
+   while /answer do {
+      every writes(!q)
+      write("?")
+      case s := read() | exit(1) of {
+         #  Commands recognized at a yes/no prompt.
+         #
+         "save":    Save()
+         "get":     Get()
+         "list":    List()
+         "dump":    Output(Tree)
+         default:   {
+            (answer := \ok[map(s, &ucase, &lcase)]) |
+               write("This is a \"yes\" or \"no\" question.")
+            }
+         }
+      }
+   return answer == "yes"
+end
+#  Ask() -- Navigates through the barrage of questions leading to a
+#  guess.
+#
+procedure Ask(node)
+   local guess, question
+   case type(node) of {
+      "string":        {
+         if not Confirm("It must be ", Article(node), " ", node, ", right") then {
+            Learn := "yes"
+            write("What were you thinking of?")
+            guess := read() | exit(1)
+            write("What question would distinguish ", Article(guess), " ",
+               guess, " from ", Article(node), " ", node, "?")
+            question := read() | exit(1)
+            if question[-1] == "?" then question[-1] := ""
+            question[1] := map(question[1], &lcase, &ucase)
+            if Confirm("For ", Article(guess), " ", guess, ", what would the answer be")
+            then return Question(question, guess, node)
+         else return Question(question, node, guess)
+         }
+      }
+      "Question":  {
+         if Confirm(node.question) then node.yes := Ask(node.yes)
+         else node.no := Ask(node.no)
+         }
+      }
+end
+#  Article() -- Come up with the appropriate indefinite article.
+#
+procedure Article(word)
+   return if any('aeiouAEIOU', word) then "an" else "a"
+end
+#  Save() -- Store our acquired knowledge in a disk file name
+#  based on the GameObject.
+#
+procedure Save()
+   local f
+   f := open(GameObject || "s", "w")
+   Output(Tree, f)
+   close(f)
+   return
+end
+#  Output() -- Recursive procedure used to output the knowledge tree.
+#
+procedure Output(node, f, sense)
+   static indent
+   initial indent := 0
+   /f := &output
+   /sense := " "
+   case type(node) of {
+      "string":        write(f, repl(" ", indent), sense, "A: ", node)
+      "Question":  {
+         write(f, repl(" ", indent), sense, "Q: ", node.question)
+         indent +:= 1
+         Output(node.yes, f, "y")
+         Output(node.no, f, "n")
+         indent -:= 1
+         }
+      }
+   return
+end
+#  Get() -- Read in a knowledge base from a file.
+#
+procedure Get()
+   local f
+   f := open(GameObject || "s", "r") | fail
+   Tree := Input(f)
+   close(f)
+   return
+end
+#  Input() -- Recursive procedure used to input the knowledge tree.
+#
+procedure Input(f)
+   local nodetype, s
+   read(f) ? (tab(upto(~' \t')) & =("y" | "n" | "") &
+      nodetype := move(1) & move(2) & s := tab(0))
+   return if nodetype == "Q" then Question(s, Input(f), Input(f)) else s
+end
+#  List() -- Lists the objects in the knowledge base.
+#
+$define Length           78
+procedure List()
+   local lst, line, item
+   lst := Show(Tree, [ ])
+   line := ""
+   every item := !sort(lst) do {
+      if *line + *item > Length then {
+         write(trim(line))
+         line := ""
+         }
+      line ||:= item || ", "
+      }
+   write(line[1:-2])
+   return
+end
+#
+#  Show() -- Recursive procedure used to navigate the knowledge tree.
+#
+procedure Show(node, lst)
+   if type(node) == "Question" then {
+      lst := Show(node.yes, lst)
+      lst := Show(node.no, lst)
+      }
+   else put(lst, node)
+   return lst
+end
+ +

Known failures

+

There are certain edge cases where Prism will fail. + There are always such cases in every regex-based syntax highlighter. + However, Prism dares to be open and honest about them. + If a failure is listed here, it doesn’t mean it will never be fixed. This is more of a “known bugs” list, just with a certain type of bug. +

+ +

Comment-like substrings and csets containing a hash

+
"foo # bar";
+'abc#def'
diff --git a/tests/languages/icon/builtin-keyword_feature.test b/tests/languages/icon/builtin-keyword_feature.test new file mode 100644 index 0000000000..1d25764242 --- /dev/null +++ b/tests/languages/icon/builtin-keyword_feature.test @@ -0,0 +1,91 @@ +&allocated +&ascii +&clock +&collections +&cset +¤t +&date +&dateline +&digits +&dump +&e +&error +&errornumber +&errortext +&errorvalue +&errout +&fail +&features +&file +&host +&input +&lcase +&letters +&level +&line +&main +&null +&output +&phi +&pi +&pos +&progname +&random +®ions +&source +&storage +&subject +&time +&trace +&ucase +&version + +---------------------------------------------------- + +[ + ["builtin-keyword", "&allocated"], + ["builtin-keyword", "&ascii"], + ["builtin-keyword", "&clock"], + ["builtin-keyword", "&collections"], + ["builtin-keyword", "&cset"], + ["builtin-keyword", "¤t"], + ["builtin-keyword", "&date"], + ["builtin-keyword", "&dateline"], + ["builtin-keyword", "&digits"], + ["builtin-keyword", "&dump"], + ["builtin-keyword", "&e"], + ["builtin-keyword", "&error"], + ["builtin-keyword", "&errornumber"], + ["builtin-keyword", "&errortext"], + ["builtin-keyword", "&errorvalue"], + ["builtin-keyword", "&errout"], + ["builtin-keyword", "&fail"], + ["builtin-keyword", "&features"], + ["builtin-keyword", "&file"], + ["builtin-keyword", "&host"], + ["builtin-keyword", "&input"], + ["builtin-keyword", "&lcase"], + ["builtin-keyword", "&letters"], + ["builtin-keyword", "&level"], + ["builtin-keyword", "&line"], + ["builtin-keyword", "&main"], + ["builtin-keyword", "&null"], + ["builtin-keyword", "&output"], + ["builtin-keyword", "&phi"], + ["builtin-keyword", "&pi"], + ["builtin-keyword", "&pos"], + ["builtin-keyword", "&progname"], + ["builtin-keyword", "&random"], + ["builtin-keyword", "®ions"], + ["builtin-keyword", "&source"], + ["builtin-keyword", "&storage"], + ["builtin-keyword", "&subject"], + ["builtin-keyword", "&time"], + ["builtin-keyword", "&trace"], + ["builtin-keyword", "&ucase"], + ["builtin-keyword", "&version"] +] + +---------------------------------------------------- + +Checks for builtin keywords. \ No newline at end of file diff --git a/tests/languages/icon/comment_feature.test b/tests/languages/icon/comment_feature.test new file mode 100644 index 0000000000..09493ab581 --- /dev/null +++ b/tests/languages/icon/comment_feature.test @@ -0,0 +1,13 @@ +# +# Foobar + +---------------------------------------------------- + +[ + ["comment", "#"], + ["comment", "# Foobar"] +] + +---------------------------------------------------- + +Checks for comments. \ No newline at end of file diff --git a/tests/languages/icon/directive_feature.test b/tests/languages/icon/directive_feature.test new file mode 100644 index 0000000000..ede5ebc85d --- /dev/null +++ b/tests/languages/icon/directive_feature.test @@ -0,0 +1,21 @@ +$include +$line +$define +$undef +$ifdef +$ifndef + +---------------------------------------------------- + +[ + ["directive", "$include"], + ["directive", "$line"], + ["directive", "$define"], + ["directive", "$undef"], + ["directive", "$ifdef"], + ["directive", "$ifndef"] +] + +---------------------------------------------------- + +Checks for preprocessor directives. \ No newline at end of file diff --git a/tests/languages/icon/function_feature.test b/tests/languages/icon/function_feature.test new file mode 100644 index 0000000000..715452f5f5 --- /dev/null +++ b/tests/languages/icon/function_feature.test @@ -0,0 +1,15 @@ +foo() +Foobar_42{} +Foo_Bar ! [] + +---------------------------------------------------- + +[ + ["function", "foo"], ["punctuation", "("], ["punctuation", ")"], + ["function", "Foobar_42"], ["punctuation", "{"], ["punctuation", "}"], + ["function", "Foo_Bar"], ["operator", "!"], ["punctuation", "["], ["punctuation", "]"] +] + +---------------------------------------------------- + +Checks for functions. \ No newline at end of file diff --git a/tests/languages/icon/keyword_feature.test b/tests/languages/icon/keyword_feature.test new file mode 100644 index 0000000000..0816911020 --- /dev/null +++ b/tests/languages/icon/keyword_feature.test @@ -0,0 +1,67 @@ +break +by +case +create +default +do +else +end +every +fail +global +if +initial +invocable +link +local +next +not +of +procedure +record +repeat +return +static +suspend +then +to +until +while + +---------------------------------------------------- + +[ + ["keyword", "break"], + ["keyword", "by"], + ["keyword", "case"], + ["keyword", "create"], + ["keyword", "default"], + ["keyword", "do"], + ["keyword", "else"], + ["keyword", "end"], + ["keyword", "every"], + ["keyword", "fail"], + ["keyword", "global"], + ["keyword", "if"], + ["keyword", "initial"], + ["keyword", "invocable"], + ["keyword", "link"], + ["keyword", "local"], + ["keyword", "next"], + ["keyword", "not"], + ["keyword", "of"], + ["keyword", "procedure"], + ["keyword", "record"], + ["keyword", "repeat"], + ["keyword", "return"], + ["keyword", "static"], + ["keyword", "suspend"], + ["keyword", "then"], + ["keyword", "to"], + ["keyword", "until"], + ["keyword", "while"] +] + +---------------------------------------------------- + +Checks for keywords. \ No newline at end of file diff --git a/tests/languages/icon/number_feature.test b/tests/languages/icon/number_feature.test new file mode 100644 index 0000000000..fc8efc8453 --- /dev/null +++ b/tests/languages/icon/number_feature.test @@ -0,0 +1,33 @@ +0 +.42 +42 +3.14159 +2e8 +3.2E-7 +47E+19 + +2r11 +8R751 +16rbadface +36razerty + +---------------------------------------------------- + +[ + ["number", "0"], + ["number", ".42"], + ["number", "42"], + ["number", "3.14159"], + ["number", "2e8"], + ["number", "3.2E-7"], + ["number", "47E+19"], + + ["number", "2r11"], + ["number", "8R751"], + ["number", "16rbadface"], + ["number", "36razerty"] +] + +---------------------------------------------------- + +Checks for numbers. \ No newline at end of file diff --git a/tests/languages/icon/operator_feature.test b/tests/languages/icon/operator_feature.test new file mode 100644 index 0000000000..a2e29ffad2 --- /dev/null +++ b/tests/languages/icon/operator_feature.test @@ -0,0 +1,69 @@ +! +% %:= +& &:= +* *:= ** **:= ++ ++ +:= ++:= +- -:= -- --:= +. +/ /:= +:= :=: +< <- <-> <:= +<< <<:= +<<= <<=:= +<= <=:= += =:= +== ==:= +=== ===:= +> >:= +>= >=:= +>> >>:= +>>= >>=:= +? ?:= +@ @:= +\ +^ ^:= +| || ||:= +||| |||:= +~ ~= ~=:= +~== ~==:= +~=== ~===:= +: +: -: + +---------------------------------------------------- + +[ + ["operator", "!"], + ["operator", "%"], ["operator", "%:="], + ["operator", "&"], ["operator", "&:="], + ["operator", "*"], ["operator", "*:="], ["operator", "**"], ["operator", "**:="], + ["operator", "+"], ["operator", "++"], ["operator", "+:="], ["operator", "++:="], + ["operator", "-"], ["operator", "-:="], ["operator", "--"], ["operator", "--:="], + ["operator", "."], + ["operator", "/"], ["operator", "/:="], + ["operator", ":="], ["operator", ":=:"], + ["operator", "<"], ["operator", "<-"], ["operator", "<->"], ["operator", "<:="], + ["operator", "<<"], ["operator", "<<:="], + ["operator", "<<="], ["operator", "<<=:="], + ["operator", "<="], ["operator", "<=:="], + ["operator", "="], ["operator", "=:="], + ["operator", "=="], ["operator", "==:="], + ["operator", "==="], ["operator", "===:="], + ["operator", ">"], ["operator", ">:="], + ["operator", ">="], ["operator", ">=:="], + ["operator", ">>"], ["operator", ">>:="], + ["operator", ">>="], ["operator", ">>=:="], + ["operator", "?"], ["operator", "?:="], + ["operator", "@"], ["operator", "@:="], + ["operator", "\\"], + ["operator", "^"], ["operator", "^:="], + ["operator", "|"], ["operator", "||"], ["operator", "||:="], + ["operator", "|||"], ["operator", "|||:="], + ["operator", "~"], ["operator", "~="], ["operator", "~=:="], + ["operator", "~=="], ["operator", "~==:="], + ["operator", "~==="], ["operator", "~===:="], + ["operator", ":"], ["operator", "+:"], ["operator", "-:"] +] + +---------------------------------------------------- + +Checks for operators. \ No newline at end of file diff --git a/tests/languages/icon/string_feature.test b/tests/languages/icon/string_feature.test new file mode 100644 index 0000000000..78bc0349ac --- /dev/null +++ b/tests/languages/icon/string_feature.test @@ -0,0 +1,22 @@ +"" +"Fo\"obar" +"Foo_ +bar_ +baz" + +'' +'a\'zerty' + +---------------------------------------------------- + +[ + ["string", "\"\""], + ["string", "\"Fo\\\"obar\""], + ["string", "\"Foo_\r\nbar_\r\nbaz\""], + ["string", "''"], + ["string", "'a\\'zerty'"] +] + +---------------------------------------------------- + +Checks for strings and csets. \ No newline at end of file