Website Summary Files Commits Branches @commit @diff @stats
path: root / homework / 81319 / golang2html_code_fold / parser.y
diff options
context:
space:
mode:
Commitceb31e1ce115a7c9a6f0cc365beeb1214b246622 (patch)
Author
 Georgi Stefanov <geosteffanov@gmail.com>
2018-11-03 22:13:19 +0200
Committer
 Martin Dobrev <martindobrev0@gmail.com>
2018-11-03 22:13:19 +0200
Files6341efed7f3f5a0208279ac0207d138503fa5e2a /homework/81319/golang2html_code_fold/parser.y
IPL-ceb31e1ce115a7c9a6f0cc365beeb1214b246622.tar
IPL-ceb31e1ce115a7c9a6f0cc365beeb1214b246622.tar.gz
IPL-ceb31e1ce115a7c9a6f0cc365beeb1214b246622.zip
Parent9557d0cb5a1b3aa9466ddc504be004b5449ce9f2 (diff)
Add foldable blocks in Golang 2 highlighter (#33)
* initial commit * Add implementation using concatenation * Added block collapsing * Finish block collapsing * Fix nested blocks and + -> - when collapsing * Remove unnecessary files. * Add readme
1 files changed, 243 insertions, 0 deletions
-rw-r--r--homework/81319/golang2html_code_fold/parser.y243
diff --git a/homework/81319/golang2html_code_fold/parser.y b/homework/81319/golang2html_code_fold/parser.y
new file mode 100644
index 0000000..fcd4834
--- /dev/null
+++ b/homework/81319/golang2html_code_fold/parser.y
@@ -0,0 +1,243 @@
+%{
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+int yylex();
+int yyerror(const char* error);
+#define YYDEBUG 1
+
+char* concatenate(char* first, char* second) {
+ int firstlen = strlen(first);
+ int secondlen = strlen(second);
+ char* result;
+ result = malloc(firstlen + secondlen + 1);
+ strcpy(result, first);
+ strcat(result, second);
+
+ return result;
+}
+
+void printStyles() {
+ puts(
+ " <style>"
+ " .identifier {"
+ " color: brown;"
+ " }"
+ " .keyword {"
+ " color: #1fbfe2;"
+ " }"
+ " .number {"
+ " color: blue;"
+ " }"
+ " .string {"
+ " color: green;"
+ " }"
+ " .operator {"
+ " color: #db184c;"
+ " font-style: bold;"
+ " }"
+ " .collapsible {"
+ " background-color: #777;"
+ " color: white;"
+ " cursor: pointer;"
+ " padding: 2px;"
+ " width: 2%;"
+ " border: none;"
+ " text-align: center;"
+ " outline: none;"
+ " font-size: 15px;"
+ " }"
+
+ " .active, .collapsible:hover {"
+ " background-color: #555;"
+ " }"
+
+
+ " </style>"
+ );
+}
+
+void printCollapsableScript() {
+ puts(
+ "<script>"
+ "var coll = document.getElementsByClassName(\"collapsible\");\n"
+ "var i;\n"
+ "\n"
+ "for (i = 0; i < coll.length; i++) {\n"
+ "coll[i].addEventListener(\"click\", function() {\n"
+ "this.classList.toggle(\"active\");\n"
+ "var content = this.nextElementSibling;\n"
+ "if (content.style.display === \"block\") {\n"
+ "content.style.display = \"none\";\n"
+ "this.innerHTML=\"+\""
+ "} else {\n"
+ "content.style.display = \"block\";\n"
+ "this.innerHTML=\"-\""
+ "}\n"
+ "});\n"
+ "}\n"
+ "</script>"
+ );
+}
+
+char* stylize(char* text, char* style) {
+ char* result = concatenate("<span class=\"", style);
+ result = concatenate(result, "\">");
+ result = concatenate(result, text);
+ result = concatenate(result, "</span>");
+
+ return result;
+}
+
+char* collapsableBlock(char* text) {
+ char* result = concatenate("<button class=\"collapsible\">+</button>", "<div class=\"content\">");
+ result = concatenate(result, text);
+ result = concatenate(result, "</div>");
+
+ return result;
+}
+
+void printNumber(char* text) {
+ char* style = stylize(text, "number");
+ printf("%s", style);
+}
+
+
+void printIdentifier(char* text) {
+ char* style = stylize(text, "identifier");
+ printf("%s", style);
+}
+
+void printKeyword(char* text) {
+ char* style = stylize(text, "keyword");
+ printf("%s", style);
+}
+
+void printString(char* text) {
+ char* style = stylize(text, "string");
+ printf("%s", style);
+}
+
+void printOperator(char* text) {
+ char* style = stylize(text, "operator");
+ printf("%s", style);
+}
+
+void printMisc(char* text) {
+ printf("%s", text);
+}
+
+void printUnrecognized(char* text) {
+ printf("Unrecognized token: %s", text);
+}
+
+void printBraces(char* text) {
+ printf("%s", text);
+}
+
+%}
+
+%start input
+
+
+%token NUMBER
+%token KEYWORD
+%token STRING
+%token STRING_DQ
+%token IDENTIFIER
+%token OPERATOR
+%token MISC
+%token UNRECOGNIZED
+%token LCURLY
+%token RCURLY
+
+%union {
+ char* strval;
+}
+
+%type <strval> input expr_list expr token_sequence token NUMBER KEYWORD STRING STRING_DQ IDENTIFIER OPERATOR MISC UNRECOGNIZED LCURLY RCURLY
+
+
+%%
+
+input: /* empty */ { printf("empty\n"); }
+ | expr_list { printf("%s", $$); }
+ ;
+
+expr_list: expr expr_list { $$ = concatenate($1, $2); }
+ | expr { $$ = $1; }
+ ;
+
+expr: token_sequence
+ | LCURLY expr_list RCURLY {
+ char* collapsable = collapsableBlock($2);
+ $$ = concatenate("{", collapsable);
+ $$ = concatenate($$, "}");
+ }
+ | LCURLY RCURLY { $$ = concatenate("{", "}"); }
+ ;
+
+
+token_sequence: token_sequence token { $$ = concatenate($1, $2); }
+ | token { $$ = $1; }
+ ;
+
+token: NUMBER { $$ = stylize($1, "number"); }
+ | KEYWORD { $$ = stylize($1, "keyword"); }
+ | STRING { $$ = stylize($1, "string"); }
+ | STRING_DQ { $$ = stylize($1, "string"); }
+ | IDENTIFIER { $$ = stylize($1, "identifier"); }
+ | OPERATOR { $$ = stylize($1, "operator"); }
+ | MISC { $$ = $1; }
+ | UNRECOGNIZED { $$ = $1 }
+ ;
+
+%%
+
+int yyerror(const char* error)
+{
+ extern int current_line;
+ fprintf(stderr, "input:%d: error: %s\n", current_line, error);
+ return 0;
+}
+
+
+void printHtmlHeader() {
+ puts(
+ "<head>"
+ " <title>hello_world.go</title>"
+ );
+ printStyles();
+ puts(
+ "</head>"
+ );
+}
+
+
+
+void printBody() {
+ puts(
+ "<body bgcolor=\"#e2cdb7\">"
+ " <pre class=\"code\">"
+ );
+ yyparse();
+ puts("</pre></body>");
+}
+
+void printHTML() {
+ puts(
+ "<!doctype>"
+ "<html>"
+ );
+ printHtmlHeader();
+ printBody();
+ printCollapsableScript();
+ puts("</html>");
+}
+
+
+int main(int argc, const char* argv[])
+{
+ printHTML();
+ return 0;
+}