Browse Source

Implement linei break UI button and tooltip information

Lucas de Souza 3 years ago
parent
commit
ece240759a
9 changed files with 576 additions and 266 deletions
  1. 36 32
      .eslintrc.json
  2. 6 0
      css/ivprog-visual-1.0.css
  3. 4 4
      grammar/pt/ivprog.g4
  4. 2 0
      i18n/ui.csv
  5. 1 0
      img/new_line.svg
  6. 97 0
      img/no_new_line.svg
  7. 250 125
      js/visualUI/commands/writer.js
  8. 145 71
      js/visualUI/ivprog_elements.js
  9. 35 34
      webpack.config.js

+ 36 - 32
.eslintrc.json

@@ -1,34 +1,38 @@
 {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "node": true
-    },
-    "parser": "@typescript-eslint/parser",
-    "plugins": ["@typescript-eslint"],
-    "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
-    "globals": {
-        "Atomics": "readonly",
-        "SharedArrayBuffer": "readonly"
-    },
-    "parserOptions": {
-        "ecmaVersion": 2018,
-        "sourceType": "module"
-    },
-    "rules": {
-        "camelcase": "off",
-        "no-unused-vars": "off",
-        "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
-        "@typescript-eslint/camelcase": "off"
+  "env": {
+    "browser": true,
+    "es6": true,
+    "node": true
+  },
+  "parser": "@typescript-eslint/parser",
+  "plugins": ["@typescript-eslint"],
+  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
+  "globals": {
+    "Atomics": "readonly",
+    "SharedArrayBuffer": "readonly"
+  },
+  "parserOptions": {
+    "ecmaVersion": 2018,
+    "sourceType": "module"
+  },
+  "rules": {
+    "camelcase": "off",
+    "no-unused-vars": "off",
+    "@typescript-eslint/no-unused-vars": [
+      "error",
+      { "argsIgnorePattern": "^_" }
+    ],
+    "@typescript-eslint/camelcase": "off",
+    "space-before-function-paren": ["error", "always"]
+  },
+  "overrides": [
+    {
+      "files": ["*.js", "*.jsx"],
+      "rules": {
+        "@typescript-eslint/explicit-member-accessibility": 0,
+        "@typescript-eslint/explicit-function-return-type": 0
+      }
     }
-    ,
-    "overrides": [
-        {
-            "files": ["*.js", "*.jsx"],
-            "rules": {
-                "@typescript-eslint/explicit-member-accessibility": 0,
-                "@typescript-eslint/explicit-function-return-type": 0
-            }
-        }
-    ]    
-}
+  ]
+}
+

+ 6 - 0
css/ivprog-visual-1.0.css

@@ -1078,3 +1078,9 @@ div.ui.checkbox.transition.visible {
 .pass_button button {
 	padding-bottom: 2px;
 }
+
+/* Write newline button*/
+.ivprog_newline_btn {
+  position: absolute;
+  height: 32px;
+}

+ 4 - 4
grammar/pt/ivprog.g4

@@ -27,7 +27,7 @@ RK_INTEGER
 
 RK_CHARACTER
   : 'caractere'
-  ;    
+  ;
 
 RK_SWITCH
   : 'escolha'
@@ -51,7 +51,7 @@ RK_FUNCTION
 
 RK_RETURN
   : 'devolva'
-  ;  
+  ;
 
 RK_FOR
   : 'para'
@@ -215,7 +215,7 @@ fragment ExponentPart
 STRING
   : '"' STRING_CHARACTER* '"'
   ;
-    
+
 fragment STRING_CHARACTER //String as defined at https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4
   : ~["\\\r\n]
   | ESC_SEQ
@@ -225,7 +225,7 @@ CHARACTER //Character as defined at https://github.com/antlr/grammars-v4/blob/ma
   : '\'' ( ESC_SEQ | ~['\\\r\n]) '\''
   ;
 
-WHITESPACE 
+WHITESPACE
   : ( ' ' | '\t') -> skip
   ;
 

+ 2 - 0
i18n/ui.csv

@@ -138,3 +138,5 @@ text_for_to,até,to,
 text_for_pass,passo,pass,
 text_relational_expression,Relacionais,Relational,
 initial_program_code,"programa {\n\n\t\tfuncao vazio inicio () {\n\t\t\t// Inicie seu codigo aqui!\n\t\t}\n}","program {\n\n\t\tfunction void main () {\n\t\t\t// Start your code here!\n\t\t}\n}",
+write_command_newline_on,Quebra de linha ativada, Line break is on,
+write_command_newline_off, Quebra de linha desativada, Line break is off,

File diff suppressed because it is too large
+ 1 - 0
img/new_line.svg


+ 97 - 0
img/no_new_line.svg

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="16"
+   id="svg2"
+   version="1.1"
+   width="16"
+   sodipodi:docname="x_iconfinder_button_linebreak_352910.svg"
+   inkscape:version="1.0 (4035a4fb49, 2020-05-01)">
+  <g
+     id="layer1"
+     transform="translate(0,-1036.3622)">
+    <path
+       d="m 1.5,1044.3622 10,0"
+       id="path3016"
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       d="m 1.5,1042.3622 10,0"
+       id="path3016-1"
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       d="m 1.5,1046.3622 10,0"
+       id="path3016-1-7"
+       style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <g
+       id="g3057"
+       transform="translate(-0.5,0)">
+      <path
+         d="m 11,6 4,0 0,2 -2,0"
+         id="path3053"
+         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         transform="translate(0,1036.3622)" />
+      <path
+         d="m 14,7 -1,1 1,1"
+         id="path3055"
+         style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         transform="translate(0,1036.3622)" />
+    </g>
+  </g>
+  <rect
+     transform="matrix(0.88009677,0.47479435,-0.61645077,0.78739345,0,0)"
+     style="fill:#f50000;fill-opacity:1;stroke:#000000;stroke-width:0"
+     id="rect838-3"
+     width="14.841698"
+     height="1.3098975"
+     x="4.0694704"
+     y="2.7956207" />
+  <metadata
+     id="metadata13">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:document-rotation="0"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="705"
+     id="namedview11"
+     showgrid="false"
+     inkscape:zoom="33.625"
+     inkscape:cx="8"
+     inkscape:cy="8"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <defs
+     id="defs4" />
+  <rect
+     y="10.471105"
+     x="-8.700532"
+     height="1.3153578"
+     width="14.788834"
+     id="rect838-3-5"
+     style="fill:#f50000;fill-opacity:1;stroke:#000000;stroke-width:0"
+     transform="matrix(-0.88324276,0.46891601,0.61389179,0.78939019,0,0)" />
+</svg>

+ 250 - 125
js/visualUI/commands/writer.js

@@ -1,26 +1,44 @@
-import * as Models from '../ivprog_elements';
-import { LocalizedStrings } from '../../services/localizedStringsService';
-import * as VariableValueMenu from './variable_value_menu';
-import * as VariableValueMenuManagement from './variable_value_menu';
-import * as CommandsManagement from '../commands';
-import * as GenericExpressionManagement from './generic_expression';
+import * as Models from "../ivprog_elements";
+import { LocalizedStrings } from "../../services/localizedStringsService";
+import * as VariableValueMenu from "./variable_value_menu";
+import * as VariableValueMenuManagement from "./variable_value_menu";
+import * as CommandsManagement from "../commands";
+import * as GenericExpressionManagement from "./generic_expression";
 
 export function createFloatingCommand () {
-	return $('<div class="ui writer created_element"> <i class="ui icon small upload"></i> <span> '+LocalizedStrings.getUI('text_command_write')+' var </span></div>');
+  return $(
+    '<div class="ui writer created_element"> <i class="ui icon small upload"></i> <span> ' +
+      LocalizedStrings.getUI("text_command_write") +
+      " var </span></div>"
+  );
 }
 
 export function renderCommand (command, function_obj) {
-	var ret = '';
-	ret += '<div class="ui writer command_container"> <i class="ui icon small upload command_drag"></i> <i class="ui icon times red button_remove_command"></i> <span class="span_command_spec">'+LocalizedStrings.getUI('text_command_write')+' ( </span><div class="all_elements_write"></div> <span class="close_parentheses span_command_spec">)</span> </div>';
-
-	var el = $(ret);
-	el.data('command', command);
-
-	//renderExpression (command, function_obj, div_to_render, expression_array)
-
-	GenericExpressionManagement.renderExpression(command, function_obj, el.find('.all_elements_write'), command.content);
-
-	/*for (var i = 0; i < command.content.length; i ++) {
+  const ret = `<div class="ui writer command_container">
+      <i class="ui icon small upload command_drag"></i>
+      <i class="ui icon times red button_remove_command"></i>
+      <span class="span_command_spec">${LocalizedStrings.getUI(
+        "text_command_write"
+      )}
+      ( </span><div class="all_elements_write"></div>
+      <span class="close_parentheses span_command_spec">)</span>
+    <img data-state="${command.newline ? "on" : "false"}" src="${
+    command.newline ? "img/new_line.svg" : "img/no_new_line.svg"
+  }" class="ivprog_newline_btn"/>
+    </div>`;
+  const el = $(ret);
+  el.data("command", command);
+
+  //renderExpression (command, function_obj, div_to_render, expression_array)
+
+  GenericExpressionManagement.renderExpression(
+    command,
+    function_obj,
+    el.find(".all_elements_write"),
+    command.content
+  );
+
+  /*for (var i = 0; i < command.content.length; i ++) {
 		var new_div_item = $( '<div class="var_value_menu_div"></div>' );
 		var div_parent_with_handler = $( '<div class="div_parent_handler"></div>' );
 		div_parent_with_handler.append($('<i class="ui icon ellipsis vertical inverted handler"></i>'));
@@ -39,121 +57,228 @@ export function renderCommand (command, function_obj) {
 		addHandlerIconAdd(el.find('.all_elements_write'), command, function_obj);
 	}*/
 
-	addHandlers(command, function_obj, el);
-	return el;
+  addHandlers(command, function_obj, el);
+  return el;
 }
 
-function addHandlersManager (command, function_obj, writer_dom, item_div, content_element) {
-
-	item_div.find('.times').on('click', function() {
-		for (var i = 0; i < command.content.length; i++) {
-			if (command.content[i] == content_element) {
-				delete command.content[i];
-	  			command.content.splice(i, 1);
-				
-				item_div.children().off();
-				item_div.off();
-				item_div.fadeOut();
-
-				if (command.content.length > 0) {
-					item_div.next('.icon_add_item_to_writer').fadeOut();
-				}
-				break;
-			}
-		}
-	});
+function addHandlersManager (
+  command,
+  _function_obj,
+  _writer_dom,
+  item_div,
+  content_element
+) {
+  item_div.find(".times").on("click", function () {
+    for (let i = 0; i < command.content.length; i++) {
+      if (command.content[i] == content_element) {
+        delete command.content[i];
+        command.content.splice(i, 1);
+
+        item_div.children().off();
+        item_div.off();
+        item_div.fadeOut();
+
+        if (command.content.length > 0) {
+          item_div.next(".icon_add_item_to_writer").fadeOut();
+        }
+        break;
+      }
+    }
+  });
 }
 
 function addHandlers (command, function_obj, writer_dom) {
-
-	writer_dom.find('.button_remove_command').on('click', function() {
-		if (CommandsManagement.removeCommand(command, function_obj, writer_dom)) {
-			writer_dom.fadeOut(400, function() {
-				writer_dom.remove();
-			});
-		}
-	});
-
-	Sortable.create(writer_dom.find(".all_elements_write")[0], {
-	    handle: '.ellipsis',
-	    animation: 100,
-	    ghostClass: 'ghost',
-	    group: 'writer_' + Math.floor(Math.random() * 10000000),
-	    draggable: '.div_parent_handler',
-	    onEnd: function (evt) {
-	    	
-	    	command.content.splice(evt.newIndex, 0, command.content.splice(evt.oldIndex, 1)[0]);
-
-	    	writer_dom.empty();
-	    	writer_dom.replaceWith(renderCommand(command, function_obj));
-	    }
-	  });
-
-
+  writer_dom.find(".button_remove_command").on("click", function () {
+    if (CommandsManagement.removeCommand(command, function_obj, writer_dom)) {
+      writer_dom.fadeOut(400, function () {
+        writer_dom.remove();
+      });
+    }
+  });
+
+  Sortable.create(writer_dom.find(".all_elements_write")[0], {
+    handle: ".ellipsis",
+    animation: 100,
+    ghostClass: "ghost",
+    group: "writer_" + Math.floor(Math.random() * 10000000),
+    draggable: ".div_parent_handler",
+    onEnd: function (evt) {
+      command.content.splice(
+        evt.newIndex,
+        0,
+        command.content.splice(evt.oldIndex, 1)[0]
+      );
+
+      writer_dom.empty();
+      writer_dom.replaceWith(renderCommand(command, function_obj));
+    },
+  });
+  // Attach event handles for the newline button
+  const newlineBtn = writer_dom.find(".ivprog_newline_btn");
+  newlineBtn.on("click", function () {
+    const state = this.dataset.state;
+    if (state === "on") {
+      this.dataset.state = "off";
+      command.newline = false;
+      this.setAttribute("src", "img/no_new_line.svg");
+    } else {
+      this.dataset.state = "on";
+      command.newline = true;
+      this.setAttribute("src", "img/new_line.svg");
+    }
+    writer_dom.data("command", command);
+    setPopup(newlineBtn, command.newline);
+  });
+  // Attach jquery popup
+  setPopup(newlineBtn, command.newline);
 }
 
-function addHandlerIconAdd (dom_object, command, function_obj, insert_after = false, after_which = null) {
-	var icon_add_item = $( '<i class="ui icon plus square outline icon_add_item_to_writer"></i> ' );
-	if (!insert_after) {
-		dom_object.append(icon_add_item);
-	} else {
-		icon_add_item.insertAfter(after_which);
-	}
-	
-	icon_add_item.on('click', function(e) {
-		var div_parent_with_handler = $( '<div class="div_parent_handler" style="display:none;"></div>' );
-		var new_div_item = $( '<div class="var_value_menu_div"></div>' );
-		div_parent_with_handler.append($('<i class="ui icon ellipsis vertical inverted handler"></i>'));
-		div_parent_with_handler.append(new_div_item);
-		div_parent_with_handler.append($('<i class="white inverted icon times handler"></i>'));
-		div_parent_with_handler.insertAfter(icon_add_item);
-
-		var new_related_menu = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true);
-
-		VariableValueMenu.renderMenu(command, new_related_menu, new_div_item, function_obj);
-
-		addHandlerIconAdd(dom_object, command, function_obj, true, div_parent_with_handler);
-
-		addHandlersManager(command, function_obj, dom_object, div_parent_with_handler, new_related_menu);
-		var pos = 1;
-		dom_object.find('.icon_add_item_to_writer').each(function() {
-			if ($(this).get(0) === icon_add_item.get(0)) {
-				command.content.splice(pos, 0, new_related_menu);
-			} else {
-				pos ++;
-			}
-		});
-		if (command.content.length == 1) {
-			icon_add_item.remove();
-		}
-		div_parent_with_handler.fadeIn();
-	});
+function setPopup (element, state) {
+  if (element.popup("exists")) {
+    element.popup("destroy");
+  }
+  const content = state
+    ? LocalizedStrings.getUI("write_command_newline_on")
+    : LocalizedStrings.getUI("write_command_newline_off");
+  element.popup({
+    content: content,
+    delay: {
+      show: 750,
+      hide: 0,
+    },
+  });
 }
 
-export function addContent (command, ref_object, dom_object, menu_var_or_value, function_obj, ref_object_content) {
-	
-	if (dom_object.hasClass('var_value_menu_div')) {
-		var icon_add_item = $( '<i class="ui icon plus square outline icon_add_item_to_writer"></i> ' );
-		icon_add_item.insertAfter(dom_object);
-
-		icon_add_item.on('click', function(e) {
-			var div_parent_with_handler = $( '<div class="div_parent_handler"></div>' );
-			div_parent_with_handler.append($('<i class="ui icon ellipsis vertical inverted handler"></i>'));
-			div_parent_with_handler.append(new_div_item);
-			div_parent_with_handler.append($('<i class="white inverted icon times handler"></i>'));
-
-			div_parent_with_handler.insertAfter(icon_add_item);
-			var new_related_menu = new Models.VariableValueMenu(VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all, null, null, null, true);
-
-			VariableValueMenu.renderMenu(command, new_related_menu, new_div_item, function_obj);
-
-			addHandlersManager(command, function_obj, dom_object, div_parent_with_handler, new_related_menu);
-
-			command.content.push(new_related_menu);
+function _addHandlerIconAdd (
+  dom_object,
+  command,
+  function_obj,
+  insert_after = false,
+  after_which = null
+) {
+  const icon_add_item = $(
+    '<i class="ui icon plus square outline icon_add_item_to_writer"></i> '
+  );
+  if (!insert_after) {
+    dom_object.append(icon_add_item);
+  } else {
+    icon_add_item.insertAfter(after_which);
+  }
+
+  icon_add_item.on("click", function (_event) {
+    const div_parent_with_handler = $(
+      '<div class="div_parent_handler" style="display:none;"></div>'
+    );
+    const new_div_item = $('<div class="var_value_menu_div"></div>');
+    div_parent_with_handler.append(
+      $('<i class="ui icon ellipsis vertical inverted handler"></i>')
+    );
+    div_parent_with_handler.append(new_div_item);
+    div_parent_with_handler.append(
+      $('<i class="white inverted icon times handler"></i>')
+    );
+    div_parent_with_handler.insertAfter(icon_add_item);
+
+    const new_related_menu = new Models.VariableValueMenu(
+      VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
+      null,
+      null,
+      null,
+      true
+    );
+
+    VariableValueMenu.renderMenu(
+      command,
+      new_related_menu,
+      new_div_item,
+      function_obj
+    );
+
+    addHandlerIconAdd(
+      dom_object,
+      command,
+      function_obj,
+      true,
+      div_parent_with_handler
+    );
+
+    addHandlersManager(
+      command,
+      function_obj,
+      dom_object,
+      div_parent_with_handler,
+      new_related_menu
+    );
+    let pos = 1;
+    dom_object.find(".icon_add_item_to_writer").each(function () {
+      if ($(this).get(0) === icon_add_item.get(0)) {
+        command.content.splice(pos, 0, new_related_menu);
+      } else {
+        pos++;
+      }
+    });
+    if (command.content.length == 1) {
+      icon_add_item.remove();
+    }
+    div_parent_with_handler.fadeIn();
+  });
+}
 
-			if (command.content.length == 1) {
-				icon_add_item.remove();
-			}
-		});
-	}
+export function addContent (
+  command,
+  _ref_object,
+  dom_object,
+  _menu_var_or_value,
+  function_obj,
+  _ref_object_content
+) {
+  if (dom_object.hasClass("var_value_menu_div")) {
+    const icon_add_item = $(
+      '<i class="ui icon plus square outline icon_add_item_to_writer"></i> '
+    );
+    icon_add_item.insertAfter(dom_object);
+
+    icon_add_item.on("click", function (_event) {
+      const div_parent_with_handler = $(
+        '<div class="div_parent_handler"></div>'
+      );
+      div_parent_with_handler.append(
+        $('<i class="ui icon ellipsis vertical inverted handler"></i>')
+      );
+      div_parent_with_handler.append(new_div_item);
+      div_parent_with_handler.append(
+        $('<i class="white inverted icon times handler"></i>')
+      );
+
+      div_parent_with_handler.insertAfter(icon_add_item);
+      const new_related_menu = new Models.VariableValueMenu(
+        VariableValueMenuManagement.VAR_OR_VALUE_TYPES.all,
+        null,
+        null,
+        null,
+        true
+      );
+
+      VariableValueMenu.renderMenu(
+        command,
+        new_related_menu,
+        new_div_item,
+        function_obj
+      );
+
+      addHandlersManager(
+        command,
+        function_obj,
+        dom_object,
+        div_parent_with_handler,
+        new_related_menu
+      );
+
+      command.content.push(new_related_menu);
+
+      if (command.content.length == 1) {
+        icon_add_item.remove();
+      }
+    });
+  }
 }

+ 145 - 71
js/visualUI/ivprog_elements.js

@@ -1,26 +1,80 @@
-import { Types } from './types';
-import WatchJS from 'melanke-watchjs';
-import * as AlgorithmManagement from './algorithm';
-
-export const COMMAND_TYPES = Object.freeze({function:"function", comment:"comment", reader:"reader", writer:"writer", attribution:"attribution", iftrue:"iftrue",
- repeatNtimes:"repeatNtimes", whiletrue:"whiletrue", dowhiletrue:"dowhiletrue", switch:"switch", switchcase:"switchcase", functioncall:"functioncall", break:"break",
- return:"return"});
-
-export const ARITHMETIC_TYPES = Object.freeze({plus:"plus", minus:"minus", multiplication:"multiplication", division:"division", module:"module", none:"none"});
-
-export const EXPRESSION_ELEMENTS = Object.freeze({exp_op_exp:"exp_op_exp", op_exp:"op_exp", par_exp_par:"par_exp_par", start_point:"start_point"});
-
-export const EXPRESSION_TYPES = Object.freeze({exp_conditional:"exp_conditional", exp_logic:"exp_logic", exp_arithmetic:"exp_arithmetic"});
-
-export const ARITHMETIC_COMPARISON = Object.freeze({greater_than:"greater_than", less_than:"less_than", equals_to:"equals_to", not_equals_to:"not_equals_to", greater_than_or_equals_to:"greater_than_or_equals_to", less_than_or_equals_to:"less_than_or_equals_to"});
-
-export const LOGIC_COMPARISON = Object.freeze({equals_to:"equals_to", not_equals_to:"not_equals_to", and:"and", or:"or", not:"not"});
-
-export const SYSTEM_FUNCTIONS_CATEGORIES = Object.freeze({math:'$mathLib', text:'$strLib', arrangement:'$arrayLib', conversion:'$langLib'});
+import { Types } from "./types";
+import WatchJS from "melanke-watchjs";
+import * as AlgorithmManagement from "./algorithm";
+
+export const COMMAND_TYPES = Object.freeze({
+  function: "function",
+  comment: "comment",
+  reader: "reader",
+  writer: "writer",
+  attribution: "attribution",
+  iftrue: "iftrue",
+  repeatNtimes: "repeatNtimes",
+  whiletrue: "whiletrue",
+  dowhiletrue: "dowhiletrue",
+  switch: "switch",
+  switchcase: "switchcase",
+  functioncall: "functioncall",
+  break: "break",
+  return: "return",
+});
+
+export const ARITHMETIC_TYPES = Object.freeze({
+  plus: "plus",
+  minus: "minus",
+  multiplication: "multiplication",
+  division: "division",
+  module: "module",
+  none: "none",
+});
+
+export const EXPRESSION_ELEMENTS = Object.freeze({
+  exp_op_exp: "exp_op_exp",
+  op_exp: "op_exp",
+  par_exp_par: "par_exp_par",
+  start_point: "start_point",
+});
+
+export const EXPRESSION_TYPES = Object.freeze({
+  exp_conditional: "exp_conditional",
+  exp_logic: "exp_logic",
+  exp_arithmetic: "exp_arithmetic",
+});
+
+export const ARITHMETIC_COMPARISON = Object.freeze({
+  greater_than: "greater_than",
+  less_than: "less_than",
+  equals_to: "equals_to",
+  not_equals_to: "not_equals_to",
+  greater_than_or_equals_to: "greater_than_or_equals_to",
+  less_than_or_equals_to: "less_than_or_equals_to",
+});
+
+export const LOGIC_COMPARISON = Object.freeze({
+  equals_to: "equals_to",
+  not_equals_to: "not_equals_to",
+  and: "and",
+  or: "or",
+  not: "not",
+});
+
+export const SYSTEM_FUNCTIONS_CATEGORIES = Object.freeze({
+  math: "$mathLib",
+  text: "$strLib",
+  arrangement: "$arrayLib",
+  conversion: "$langLib",
+});
 
 export class Variable {
-
-  constructor (type, name, value, dimensions = 0, is_constant = false, rows = 0, columns = 0) {
+  constructor (
+    type,
+    name,
+    value,
+    dimensions = 0,
+    is_constant = false,
+    rows = 0,
+    columns = 0
+  ) {
     this.type = type;
     this.name = name;
     this.value = value;
@@ -32,8 +86,17 @@ export class Variable {
 }
 
 export class Function {
-
-  constructor (name, return_type = Types.VOID, return_dimensions = 0, parameters_list = [], is_main = false, is_hidden = false, variables_list = [], function_comment = null, commands = []) {
+  constructor (
+    name,
+    return_type = Types.VOID,
+    return_dimensions = 0,
+    parameters_list = [],
+    is_main = false,
+    is_hidden = false,
+    variables_list = [],
+    function_comment = null,
+    commands = []
+  ) {
     this.type = COMMAND_TYPES.function;
     this.name = name;
     this.return_type = return_type;
@@ -48,8 +111,14 @@ export class Function {
 }
 
 export class SystemFunction {
-
-  constructor (identifier, return_type, return_dimensions, parameters_list, function_comment = null, category) {
+  constructor (
+    identifier,
+    return_type,
+    return_dimensions,
+    parameters_list,
+    function_comment = null,
+    category
+  ) {
     this.type = COMMAND_TYPES.function;
     this.identifier = identifier;
     this.return_type = return_type;
@@ -61,7 +130,6 @@ export class SystemFunction {
 }
 
 export class Comment {
-  
   constructor (comment_text) {
     this.type = COMMAND_TYPES.comment;
     this.comment_text = comment_text;
@@ -69,14 +137,12 @@ export class Comment {
 }
 
 export class Break {
-  
   constructor () {
     this.type = COMMAND_TYPES.break;
   }
 }
 
 export class Reader {
-  
   constructor (variable_value_menu = new VariableValueMenu()) {
     this.type = COMMAND_TYPES.reader;
     this.variable_value_menu = variable_value_menu;
@@ -84,15 +150,14 @@ export class Reader {
 }
 
 export class Writer {
-
-  constructor (content) {
+  constructor (content, newline = true) {
     this.type = COMMAND_TYPES.writer;
     this.content = content;
+    this.newline = newline;
   }
 }
 
 export class Attribution {
-
   constructor (variable, expression = []) {
     this.type = COMMAND_TYPES.attribution;
     this.variable = variable;
@@ -101,7 +166,6 @@ export class Attribution {
 }
 
 export class ExpressionOperator {
-
   constructor (type_op, item) {
     this.type_op = type_op; // Logic, Arithmetic OR Relational
     this.item = item;
@@ -109,7 +173,6 @@ export class ExpressionOperator {
 }
 
 export class ExpressionElement {
-
   constructor (type_exp, itens = []) {
     this.type_exp = type_exp;
     this.itens = itens;
@@ -117,7 +180,6 @@ export class ExpressionElement {
 }
 
 export class ConditionalExpression {
-
   constructor (expression) {
     this.type = EXPRESSION_TYPES.exp_conditional;
     this.expression = expression;
@@ -125,7 +187,6 @@ export class ConditionalExpression {
 }
 
 export class LogicExpression {
-
   constructor (has_neg, first_operand, second_operand, operator) {
     this.type = EXPRESSION_TYPES.exp_logic;
     this.has_neg = has_neg;
@@ -136,7 +197,6 @@ export class LogicExpression {
 }
 
 export class ArithmeticExpression {
-
   constructor (first_operand, second_operand, operator) {
     this.type = EXPRESSION_TYPES.exp_arithmetic;
     this.first_operand = first_operand;
@@ -146,7 +206,6 @@ export class ArithmeticExpression {
 }
 
 export class IfTrue {
-
   constructor (expression, commands_block, commands_else) {
     this.type = COMMAND_TYPES.iftrue;
     this.expression = expression;
@@ -156,8 +215,14 @@ export class IfTrue {
 }
 
 export class RepeatNTimes {
-
-  constructor (var_attribution, var_incrementation, expression1, expression2, expression3, commands_block) {
+  constructor (
+    var_attribution,
+    var_incrementation,
+    expression1,
+    expression2,
+    expression3,
+    commands_block
+  ) {
     this.type = COMMAND_TYPES.repeatNtimes;
     this.var_attribution = var_attribution;
     this.var_incrementation = var_incrementation;
@@ -169,7 +234,6 @@ export class RepeatNTimes {
 }
 
 export class WhileTrue {
-
   constructor (expression, commands_block) {
     this.type = COMMAND_TYPES.whiletrue;
     this.expression = expression;
@@ -178,7 +242,6 @@ export class WhileTrue {
 }
 
 export class DoWhileTrue {
-
   constructor (expression, commands_block) {
     this.type = COMMAND_TYPES.dowhiletrue;
     this.expression = expression;
@@ -187,7 +250,6 @@ export class DoWhileTrue {
 }
 
 export class Switch {
-
   constructor (variable, cases = []) {
     this.type = COMMAND_TYPES.switch;
     this.variable = variable;
@@ -196,24 +258,21 @@ export class Switch {
 }
 
 export class Return {
-
- constructor (variable_value_menu) {
+  constructor (variable_value_menu) {
     this.type = COMMAND_TYPES.return;
     this.variable_value_menu = variable_value_menu;
-  } 
+  }
 }
 
 export class SwitchCase {
-
- constructor (variable_value_menu, commands_block = []) {
+  constructor (variable_value_menu, commands_block = []) {
     this.type = COMMAND_TYPES.switchcase;
     this.variable_value_menu = variable_value_menu;
     this.commands_block = commands_block;
-  } 
+  }
 }
 
 export class FunctionCall {
-
   constructor (function_called, parameters_list) {
     this.type = COMMAND_TYPES.functioncall;
     this.function_called = function_called;
@@ -222,8 +281,14 @@ export class FunctionCall {
 }
 
 export class VariableValueMenu {
-
-  constructor (variable_and_value = 7, content = null, row = null, column = null, include_constant = true, dimensions = 0) {
+  constructor (
+    variable_and_value = 7,
+    content = null,
+    row = null,
+    column = null,
+    include_constant = true,
+    dimensions = 0
+  ) {
     this.type = "var_value";
     this.variable_and_value = variable_and_value;
     this.content = content;
@@ -235,7 +300,6 @@ export class VariableValueMenu {
 }
 
 export class FunctionCallMenu {
-  
   constructor (function_called = null, parameters_list = []) {
     this.type = "function_call";
     this.function_called = function_called;
@@ -244,31 +308,41 @@ export class FunctionCallMenu {
 }
 
 export class Program {
-
   constructor () {
     this.functions = [];
     this.globals = [];
   }
 
   addFunction (function_to_add) {
-
-    WatchJS.watch(function_to_add.parameters_list, function(){
-      if (window.insertContext) {
-        setTimeout(function(){ AlgorithmManagement.renderAlgorithm(); }, 300);
-        window.insertContext = false;
-      } else {
-        AlgorithmManagement.renderAlgorithm();
-      }
-    }, 1);
-
-    WatchJS.watch(function_to_add.variables_list, function(){
-      if (window.insertContext) {
-        setTimeout(function(){ AlgorithmManagement.renderAlgorithm(); }, 300);
-        window.insertContext = false;
-      } else {
-        AlgorithmManagement.renderAlgorithm();
-      }
-    }, 1);
+    WatchJS.watch(
+      function_to_add.parameters_list,
+      function () {
+        if (window.insertContext) {
+          setTimeout(function () {
+            AlgorithmManagement.renderAlgorithm();
+          }, 300);
+          window.insertContext = false;
+        } else {
+          AlgorithmManagement.renderAlgorithm();
+        }
+      },
+      1
+    );
+
+    WatchJS.watch(
+      function_to_add.variables_list,
+      function () {
+        if (window.insertContext) {
+          setTimeout(function () {
+            AlgorithmManagement.renderAlgorithm();
+          }, 300);
+          window.insertContext = false;
+        } else {
+          AlgorithmManagement.renderAlgorithm();
+        }
+      },
+      1
+    );
 
     this.functions.push(function_to_add);
   }

+ 35 - 34
webpack.config.js

@@ -11,10 +11,10 @@ module.exports = {
     path: path.resolve(__dirname, "build", "js"),
     filename: "[name].[contenthash].js",
     library: "ivprogCore",
-    libraryTarget: "umd"
+    libraryTarget: "umd",
   },
   node: {
-    fs: "empty"
+    fs: "empty",
   },
   module: {
     rules: [
@@ -24,71 +24,71 @@ module.exports = {
         use: {
           loader: "babel-loader",
           options: {
-            presets: ["@babel/preset-env"]
-          }
-        }
+            presets: ["@babel/preset-env"],
+          },
+        },
       },
       {
         test: /\.g4$/,
         exclude: /(node_modules)/,
         use: {
-          loader: "antlr4-webpack-loader"
-        }
+          loader: "antlr4-webpack-loader",
+        },
       },
       {
         test: /\.tsx?$/,
         use: "ts-loader",
-        exclude: /node_modules/
+        exclude: /node_modules/,
       },
       {
         test: /\.csv$/,
         use: [
           {
-            loader: path.resolve(__dirname, "i18n_csv_loader")
-          }
+            loader: path.resolve(__dirname, "i18n_csv_loader"),
+          },
         ],
-        exclude: /node_modules/
-      }
-    ]
+        exclude: /node_modules/,
+      },
+    ],
   },
   resolve: {
-    extensions: [".tsx", ".ts", ".js", ".csv"]
+    extensions: [".tsx", ".ts", ".js", ".csv"],
   },
   stats: {
-    colors: true
+    colors: true,
   },
   plugins: [
     new CleanWebpackPlugin({
       cleanOnceBeforeBuildPatterns: [path.resolve(__dirname, "build/**/*")],
-      watch: true
+      watch: true,
     }),
     new UpdateVersionPlugin(),
     new HtmlWebpackPlugin({
       template: "templates/index.html",
-      filename: path.resolve(__dirname, "build", "index.html")
+      filename: path.resolve(__dirname, "build", "index.html"),
     }),
     new HtmlWebpackPlugin({
       template: "templates/runner.html",
-      filename: path.resolve(__dirname, "build", "runner.html")
+      filename: path.resolve(__dirname, "build", "runner.html"),
     }),
     /*new ChangeScriptSourcePlugin(),*/
     new CopyPlugin([
       {
         from: "js/iassign-integration-functions.js",
-        to: path.resolve(__dirname, "build/js")
+        to: path.resolve(__dirname, "build/js"),
       },
       {
         from: "css/ivprog-visual-1.0.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       { from: "css/ivprog-term.css", to: path.resolve(__dirname, "build/css") },
       {
         from: "css/ivprog-assessment.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       {
         from: "css/ivprog-editor.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       { from: "css/roboto.css", to: path.resolve(__dirname, "build/css") },
       { from: "css/fonts/", to: path.resolve(__dirname, "build/css/fonts") },
@@ -98,39 +98,40 @@ module.exports = {
       { from: "js/semantic.min.js", to: path.resolve(__dirname, "build/js") },
       {
         from: "css/semantic.min.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       { from: "css/themes/", to: path.resolve(__dirname, "build/css/themes") },
       { from: "img/trash-icon.png", to: path.resolve(__dirname, "build/img") },
       { from: "img/empty.svg", to: path.resolve(__dirname, "build/img") },
+      { from: "img/new_line.svg", to: path.resolve(__dirname, "build/img") },
+      { from: "img/no_new_line.svg", to: path.resolve(__dirname, "build/img") },
       {
         from: "js/jquery.json-editor.min.js",
-        to: path.resolve(__dirname, "build/js")
+        to: path.resolve(__dirname, "build/js"),
       },
       {
         from: "node_modules/codemirror/lib/codemirror.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       {
         from: "node_modules/codemirror/addon/hint/show-hint.css",
-        to: path.resolve(__dirname, "build/css")
+        to: path.resolve(__dirname, "build/css"),
       },
       {
         from: "node_modules/codemirror/theme/ttcn.css",
-        to: path.resolve(__dirname, "build/css")
-      }
+        to: path.resolve(__dirname, "build/css"),
+      },
       /*{from:'index.html', to:path.resolve(__dirname, 'build')},
         {from:'runner.html', to:path.resolve(__dirname, 'build')},*/
-    ])
+    ]),
   ],
   optimization: {
     splitChunks: {
-      chunks: "all"
-    }
+      chunks: "all",
+    },
   },
   devtool: "source-map",
   watchOptions: {
-    ignored: [path.resolve(__dirname, ".ima_version.json")]
-  }
+    ignored: [path.resolve(__dirname, ".ima_version.json")],
+  },
 };
-