modify something
This commit is contained in:
		
							parent
							
								
									cb2cd421d3
								
							
						
					
					
						commit
						c04efe041d
					
				
					 12 changed files with 308 additions and 76 deletions
				
			
		|  | @ -3,6 +3,7 @@ A Scheme-like typesetting LISP interpreter and editor that using SILE typesettin | |||
| 
 | ||||
| 
 | ||||
| ## Dependencies | ||||
| * Python3 | ||||
| * PyQt5>=5.15 | ||||
| * QScintilla>=2.12 | ||||
| * SILE>=0.10 | ||||
|  | @ -20,10 +21,10 @@ see `src/example.pdf` | |||
| 
 | ||||
| To make a wheel package, run the following command in the root folder: | ||||
| 
 | ||||
|   `python setup.py bdist_wheel` | ||||
|   `python3 setup.py bdist_wheel` | ||||
| 
 | ||||
| and then: | ||||
| 
 | ||||
|   `cd dist; ls` | ||||
| 
 | ||||
| `Clochur-x.y.z-py3-none-any.whl` will in it. | ||||
| `Clochur-x.y.z-py3-none-any.whl` will be in it. | ||||
|  |  | |||
|  | @ -2,6 +2,28 @@ | |||
| [script "packages/font-fallback"] | ||||
| [script "packages/grid"] | ||||
| 
 | ||||
| [define section-var 1] | ||||
| [define sub-section-var 1] | ||||
| [define section-title ""] | ||||
| 
 | ||||
| % custom macro | ||||
| [def-syntax section | ||||
| [[_ x][begin | ||||
| [set! section-title [str-append [str-append [str section-var] [str ". "  ]] [str x]]] | ||||
| [font [[size "20pt"][weight "800"]] section-title] | ||||
| [set! section-var [+ section-var 1]] | ||||
| [set! sub-section-var 1] | ||||
| ]]] | ||||
| 
 | ||||
| % custom macro | ||||
| 
 | ||||
| 
 | ||||
| [def-syntax subsection | ||||
| [[_ x][begin | ||||
| [set! section-title [str-append [str-append [str sub-section-var] [str ". "  ]] [str x]]] | ||||
| [font [[size "16pt"][weight "600"]] section-title] | ||||
| [set! sub-section-var [+ sub-section-var 1]] | ||||
| ]]] | ||||
| 
 | ||||
| 
 | ||||
| [docu-para [[class "book"][papersize "b5"]]] | ||||
|  | @ -12,9 +34,11 @@ | |||
| 
 | ||||
| [font-size "20pt" "Welcome to use"] [font [[family "sligeach_orig"][size "20pt"]] "Clóċur"][font-size "20pt" ", a toy editor, toy intepreter and a toy typesetting-engine frontend."] | ||||
| 
 | ||||
| [call section "What is Clochur?"] | ||||
| [section "What is Clochur?"] | ||||
| 
 | ||||
| Clochur, or printed as [str "\""][font-family "sligeach_orig" "Clóċur" ][str "\""] in Irish language (Clóċur as Roman type, which means [q]typesetting[q]), is a toy-lisp typesetting language with a intepreter written in Python, and with a simple Editor written in PyQt and Qscintilla. | ||||
| 
 | ||||
| 
 | ||||
| Clochur, or printed as "\""[font-family "sligeach_orig" "Clóċur"]"\"" in Irish language ([italic "\"CLOW-kur\""] Clóċur as Roman type, which means [q]typesetting[q]), is a toy-lisp typesetting language with a intepreter written in Python 3, and with a simple Editor written in PyQt5 and QScintilla. | ||||
| 
 | ||||
| It generate a XML that is readable for SILE, which is a typesetting engine written in Lua, | ||||
| and it generate PDF with SILE. | ||||
|  | @ -28,4 +52,23 @@ The functions that it has (although may be buggy or needed to be tested) is: | |||
|  - count basic arithmetic expression. | ||||
| 
 | ||||
| [str "- lambda function"], function definition. | ||||
| ] | ||||
| 
 | ||||
| [section "Simple manual"] | ||||
| 
 | ||||
| [subsection "Macro"] | ||||
| 
 | ||||
| Using 'def-syntax', you can add your macro to sile. the example is a "custom-section" macro: | ||||
| 
 | ||||
| [font-family "Noto Sans Mono CJK TC" | ||||
| % custom macro | ||||
| "[def-syntax \"section\"  | ||||
| 
 | ||||
| [[_ x][begin] ] | ||||
| 
 | ||||
| [set! section-title [str-append [str-append [str [str \"section-var\"]] [str \". \"  ]] [str x]]] | ||||
| 
 | ||||
| [font [[size \"20pt\"][weight \"800\"]] [str \"section-title\"]] | ||||
| 
 | ||||
| [set! [str \"section-var\"] [+ [str \"section-var\"] 1]] | ||||
| 
 | ||||
| ]]]" | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| import re | ||||
| from PyQt5.Qsci import QsciLexerCustom, QsciScintilla | ||||
| from PyQt5.QtGui import * | ||||
| from Editor.Parser import Parser | ||||
| from Clochur.Parser import Parser | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -34,8 +34,16 @@ class ClochurLexer(QsciLexerCustom): | |||
|         self.QUOTES = ['"'] | ||||
|         self.PARENTHESIS = ["[", "]"] | ||||
| 
 | ||||
|         self.PRIMARY = ['define', 'def-syntax' , 'True', 'False', 'lambda', '-', '+', | ||||
|             '*', '/', '>' ,'=','<','>=','<=', 'if', 'docu', 'font', 'font-family'] | ||||
|         self.parent = parent | ||||
| 
 | ||||
|          | ||||
|         macro_list = ['docu', 'font', 'font-family','font-size','underline','bold','italic'] | ||||
|         boolean_list = ['True', 'False'] | ||||
|         operator_list = [ '-', '+', '*', '/', '>' ,'=','<','>=','<='] | ||||
|         # SILE and SILE-STRING-ADD! is internal, so they're not added. | ||||
|         function_list = ['if', 'docu', 'docu-para', 'script', 'call','xml-to-string', 'begin', | ||||
|             'str','str-append','set!','print', 'define', 'def-syntax', 'lambda', 'eval'] | ||||
|         self.PRIMARY = macro_list + boolean_list + operator_list + function_list | ||||
| 
 | ||||
|         self.split_pattern = re.compile(r'(\s+|\\%|%|\\\[|\\\]|[[]|[]])') | ||||
| 
 | ||||
|  | @ -106,7 +114,7 @@ class ClochurLexer(QsciLexerCustom): | |||
| 
 | ||||
| 
 | ||||
|         self.startStyling(start, 0x1f) | ||||
|         rainbow_state = 0 | ||||
|         rainbow_state = 0 # 0~6  = Rainbowmode ; 0~6 + 10 (i.e. 10~16)  = Rainbowmode with string | ||||
| 
 | ||||
|         index = SCI(QsciScintilla.SCI_LINEFROMPOSITION, start) | ||||
| 
 | ||||
|  | @ -128,7 +136,7 @@ class ClochurLexer(QsciLexerCustom): | |||
|             #print(line_utf8_splitted_len_pair) | ||||
| 
 | ||||
|             is_comment = False | ||||
|             is_string = False | ||||
|             next_is_defined_var = False | ||||
| 
 | ||||
|             i = 0 | ||||
|             if index > 0: | ||||
|  | @ -140,12 +148,37 @@ class ClochurLexer(QsciLexerCustom): | |||
| 
 | ||||
|             for item in line_utf8_splitted_len_pair: | ||||
| 
 | ||||
|                 ## add to complete list | ||||
|                 #if item["str"] in [ "define", "def-syntax"]: | ||||
|                 #    next_is_defined_var = True | ||||
|                 #elif next_is_defined_var == True and not (item["str"] in ["[","]"]): | ||||
|                 #    print(next_is_defined_var,item["str"]) | ||||
|                 #    self.parent.append_autocompletion_item(item["str"]) | ||||
|                 #    next_is_defined_var = False | ||||
|                 #else: | ||||
|                 #    pass | ||||
| 
 | ||||
|                 '''comment''' | ||||
|                 if item["str"] == "%": | ||||
|                     is_comment = True | ||||
|                 if is_comment == True: | ||||
|                     new_state = self.Comment # end of comment | ||||
|                  | ||||
|                 # string | ||||
|                 elif re.match(tmp_parser.string_pattern ,item["str"]): | ||||
|                     new_state = self.String | ||||
|                 elif re.match(r"[\"]([^\"\\]|[\\][\"nt]|[\\][\\])+?", item["str"]): | ||||
|                     rainbow_state += 10 | ||||
|                     new_state = self.String | ||||
|                 elif (re.match(r"([^\"\\]|[\\][\"nt]|[\\][\\])+?[\"]" ,item["str"]) or re.match(r'["]' ,item["str"])): | ||||
|                     new_state = self.String | ||||
|                     rainbow_state -= 10 | ||||
|                  | ||||
|                 elif item["str"] == "]" and rainbow_state >= 10: | ||||
|                     new_state = self.String | ||||
|                 elif rainbow_state >= 10: | ||||
|                     new_state = self.String | ||||
| 
 | ||||
|                 elif item["str"] in self.PRIMARY: # keywords | ||||
|                     new_state = self.Keyword | ||||
| 
 | ||||
|  | @ -155,27 +188,26 @@ class ClochurLexer(QsciLexerCustom): | |||
|                 elif re.match(tmp_parser.float_pattern, item["str"]): | ||||
|                     new_state = self.Number | ||||
| 
 | ||||
|                 # string | ||||
|                 elif re.match(tmp_parser.string_pattern ,item["str"]): | ||||
|                     new_state = self.String | ||||
|                 elif re.match(r"[\"]([^\"\\]|[\\][\"\n\t]|[\\])*?", item["str"]): | ||||
|                     is_string = True | ||||
|                     new_state = self.String | ||||
|                 elif re.match(r"([^\"\\]|[\\][\"\n\t]|[\\])*?[\"]" ,item["str"]): | ||||
|                     new_state = self.String | ||||
|                     is_string = False | ||||
|                 elif is_string == True: | ||||
|                     new_state = self.String | ||||
| 
 | ||||
|                 #parenthesis: rainbow mode | ||||
|                 elif item["str"] == "[": | ||||
|                     if rainbow_state >= 10: | ||||
|                         new_state = self.String | ||||
|                     elif rainbow_state < 7: | ||||
|                         print("rainbow_state" + str(type(rainbow_state)) + str(rainbow_state)) | ||||
|                         new_state = getattr(self, "Rainbow" + str(rainbow_state)) | ||||
|                         rainbow_state = (rainbow_state + 1) % 7 | ||||
|                     else: | ||||
|                         pass | ||||
|                 elif item["str"] == "]": | ||||
|                     if rainbow_state >= 10: | ||||
|                         new_state = self.String | ||||
|                     elif rainbow_state < 7: | ||||
|                         rainbow_state = (rainbow_state - 1) % 7 | ||||
|                         new_state = getattr(self, "Rainbow" + str(rainbow_state)) | ||||
|                     else: | ||||
|                         pass | ||||
|                 else: | ||||
|                     pass | ||||
| 
 | ||||
|                 word_length = item["len"] | ||||
|                 i += word_length | ||||
|  | @ -2,9 +2,9 @@ | |||
| #-*-coding:utf-8-*- | ||||
| 
 | ||||
| from PyQt5.QtGui import * | ||||
| from PyQt5.Qsci import QsciScintilla | ||||
| from PyQt5.Qsci import QsciScintilla, QsciAPIs | ||||
| 
 | ||||
| from Editor.ClochurLexer import ClochurLexer | ||||
| from Clochur.ClochurLexer import ClochurLexer | ||||
| 
 | ||||
| class CustomQsciEditor(QsciScintilla): | ||||
|     def __init__(self, parent=None): | ||||
|  | @ -15,8 +15,7 @@ class CustomQsciEditor(QsciScintilla): | |||
| 
 | ||||
|         self.tab_width = 4 | ||||
| 
 | ||||
|         lexer = ClochurLexer(self) | ||||
|         self.setLexer(lexer) | ||||
|         | ||||
| 
 | ||||
|         # Margin 0 for line numbers | ||||
|         font = QFont() | ||||
|  | @ -51,6 +50,39 @@ class CustomQsciEditor(QsciScintilla): | |||
|         self.setTabWidth(4) | ||||
|         self.setBackspaceUnindents(True) | ||||
| 
 | ||||
|         #  set auto complete  | ||||
|          | ||||
|         #set lexer | ||||
|         self.lexer = ClochurLexer(self) | ||||
|         self.auto_complete_api = QsciAPIs(self.lexer) # autocomplete function | ||||
|         self.setLexer(self.lexer) | ||||
|          | ||||
|         self.setAutoCompletionCaseSensitivity(True) | ||||
| 
 | ||||
|         self.setAutoCompletionReplaceWord(False) | ||||
| 
 | ||||
|         # Use the predefined APIs as the source.  | ||||
|         self.setAutoCompletionSource(QsciScintilla.AcsAll) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         # after 1 character, show completetion | ||||
|         self.setAutoCompletionThreshold(1) | ||||
| 
 | ||||
|         # add autocompletion items | ||||
|         autocompletions = self.lexer.PRIMARY | ||||
|      | ||||
|          | ||||
|         for ac in autocompletions: | ||||
|             self.auto_complete_api.add(ac) | ||||
| 
 | ||||
|         # "prepare" the QsciAPIs-object:  | ||||
|         self.auto_complete_api.prepare() | ||||
| 
 | ||||
|     def append_autocompletion_item(self, item): | ||||
|         self.auto_complete_api.add(item) | ||||
|         self.auto_complete_api.prepare() | ||||
| 
 | ||||
|     def set_word_wrap(self): | ||||
|         self.setWrapMode(QsciScintilla.WrapMode.WrapWord) | ||||
|     def set_no_word_wrap(self): | ||||
|  | @ -2,7 +2,8 @@ | |||
| 
 | ||||
| import re | ||||
| import xml.etree.ElementTree as ET | ||||
| from Editor.Parser import Parser | ||||
| import itertools | ||||
| from Clochur.Parser import Parser | ||||
| 
 | ||||
| ''' | ||||
| macro expansion for example: | ||||
|  | @ -21,6 +22,11 @@ class Interpreter: | |||
|         self.macro_list = dict() | ||||
|         self.silexml = ET.Element('sile') | ||||
| 
 | ||||
|         #self.editor = None | ||||
| 
 | ||||
|         #if "editor" in kwargs.keys(): | ||||
|         #    self.editor = kwargs["editor"] | ||||
| 
 | ||||
|         self.preprocessing_commands = '''[def-syntax docu | ||||
|     [[_ x] [SILE[docu-aux x]]] | ||||
|     [[_ x y...] [SILE[docu-aux x y...]]]] | ||||
|  | @ -103,9 +109,11 @@ class Interpreter: | |||
|             string = str(string) | ||||
|         if re.match(string_pattern, string): | ||||
|             # reverse the escape characters | ||||
|             print(string) | ||||
|             while True: | ||||
|                 string_before = string | ||||
|                 string = re.sub(r'\\"(.+)',r'"\1',string) | ||||
|             print(string) | ||||
|                 if string_before == string: | ||||
|                     break | ||||
|             return string[1:-1] | ||||
|         else: | ||||
|             return string | ||||
|  | @ -153,10 +161,26 @@ class Interpreter: | |||
| 
 | ||||
|             else: | ||||
|                 return sexp["token"] | ||||
|          | ||||
|         elif isinstance(sexp, Lambda): | ||||
|             return sexp | ||||
|          | ||||
|         # lambda apply | ||||
|         elif isinstance(sexp[0], Lambda): | ||||
|             return self.apply(sexp) | ||||
| 
 | ||||
|         # count sexp[0] first. | ||||
|         elif isinstance(sexp[0], list): | ||||
|             new_sexp_0 = self.interprete_aux(sexp[0]) | ||||
|             new_sexp = [new_sexp_0] + sexp[1:] | ||||
|             return self.interprete_aux(new_sexp) | ||||
|          | ||||
| 
 | ||||
|         elif sexp[0]["token"] in ["+", "-", "*", "/", "<", "=", ">", "<=", ">="]: | ||||
|             if len(sexp) != 3: | ||||
|                 parser = Parser() | ||||
|                 raise Exception("Ln %d, Col %d: the argument length %d of %s is not correct." % | ||||
|                         (sexp[0]["line"], sexp[0]["col"], len(sexp), a.generate_printable_sexp(sexp))) | ||||
|                         (sexp[0]["line"], sexp[0]["col"], len(sexp), parser.generate_printable_sexp(sexp))) | ||||
|             else: | ||||
|                 if sexp[0]["token"] == "+": | ||||
|                     return self.interprete_aux(sexp[1]) + self.interprete_aux(sexp[2]) | ||||
|  | @ -203,7 +227,8 @@ class Interpreter: | |||
|                     pass | ||||
|              | ||||
|             if not is_found: | ||||
|                 raise Exception("The syntax pattern for %s is not found." % a.generate_printable_sexp(sexp)) | ||||
|                 parser = Parser() | ||||
|                 raise Exception("The syntax pattern for %s is not found." % parser.generate_printable_sexp(sexp)) | ||||
|             else: | ||||
|                 new_sexp = self.macro_expand(syntax_after, unification) | ||||
|                  | ||||
|  | @ -217,7 +242,13 @@ class Interpreter: | |||
|                 raise Exception("Ln %d, Col %d: the type of %s should be symbol, not %s" % | ||||
|                         (sexp[1]["line"], sexp[1]["col"], sexp[1], sexp[1]["type"])) | ||||
|             else: | ||||
|                 self.env[-1][sexp[1]["token"]] = self.interprete_aux(sexp[2]) | ||||
|                 defined_var = sexp[1]["token"]    | ||||
|                 self.env[-1][defined_var] = self.interprete_aux(sexp[2]) | ||||
|                  | ||||
|                 #if self.editor != None: | ||||
|                 #    self.editor.append_autocompletion_item(defined_var) | ||||
|             return "" | ||||
|              | ||||
|         elif sexp[0]["token"] == "if": | ||||
|             if len(sexp) != 4: | ||||
|                 raise Exception("Ln %d, Col %d: the number of argument of if should be 3." % | ||||
|  | @ -233,7 +264,12 @@ class Interpreter: | |||
|                 raise Exception("Ln %d, Col %d: the argument number of str should be 1" % | ||||
|                         (sexp[0]["line"], sexp[0]["col"])) | ||||
|             else: | ||||
|                 if isinstance(sexp[1], dict) and (not (sexp[1]["token"] in self.macro_list.keys())): | ||||
|                 vars_frame = [frame.keys() for frame in self.env] | ||||
|                 vars_list = list(itertools.chain.from_iterable(vars_frame)) | ||||
|                 macro_vars = self.macro_list.keys() | ||||
|                 if isinstance(sexp[1], dict) and \ | ||||
|                     (not (sexp[1]["token"] in macro_vars)) and \ | ||||
|                     (not (sexp[1]["token"] in vars_list)) : | ||||
|                     return str(self.destring(sexp[1]["token"])) | ||||
|                 else: | ||||
|                     return str(self.destring(self.interprete_aux(sexp[1]))) | ||||
|  | @ -253,6 +289,14 @@ class Interpreter: | |||
|                 result = self.interprete_aux(sexp[1]) | ||||
|                 print(result) | ||||
|                 return "" | ||||
|         elif sexp[0]["token"] == 'eval': | ||||
|             if len(sexp) != 2: | ||||
|                 raise Exception("Ln %d, Col %d: the argument number of eval should be 1" % | ||||
|                         (sexp[0]["line"], sexp[0]["col"])) | ||||
|             else: | ||||
|                 result = self.interprete_aux(sexp[1]) | ||||
|                 return result | ||||
|          | ||||
|         elif sexp[0]["token"] == "set!": | ||||
|             if sexp[1]["type"] != "sym": | ||||
|                 raise Exception("Ln %d, Col %d: the type of %s should be symbol, not %s" % | ||||
|  | @ -269,6 +313,8 @@ class Interpreter: | |||
|                     raise Exception("Ln %d, Col %d: the variable %s is not found!" % | ||||
|                             (sexp[1]["line"], sexp[1]["col"], sexp[1]["token"])) | ||||
| 
 | ||||
|             return "" | ||||
|          | ||||
|          | ||||
|         elif sexp[0]["token"] == "def-syntax": | ||||
|             if len(sexp) < 3: | ||||
|  | @ -289,6 +335,10 @@ class Interpreter: | |||
|                  | ||||
|                 self.macro_list[syntax_name] = result_list | ||||
| 
 | ||||
|                 # add to auto completion list | ||||
|                 #if self.editor != None: | ||||
|                 #    self.editor.append_autocompletion_item(defined_var) | ||||
| 
 | ||||
|             return "" | ||||
| 
 | ||||
|         elif sexp[0]["token"] == "begin": | ||||
|  | @ -351,6 +401,58 @@ class Interpreter: | |||
|             else: | ||||
|                 raise Exception("Line %d, Col. %d, the form of call is mal-formed." % (sexp[0]["line"], sexp[0]["col"])) | ||||
|          | ||||
|         # make a List class object | ||||
|         elif sexp[0]["token"] == "ls": | ||||
|             result = [] | ||||
| 
 | ||||
|             if len(sexp) == 1: | ||||
|                 return result | ||||
|             else: | ||||
|                 result = [self.interprete_aux(x) for x in sexp[1:]] | ||||
| 
 | ||||
|             return List(result) | ||||
| 
 | ||||
|         # (car List) | ||||
|         elif sexp[0]["token"] == "car": | ||||
|             if len(sexp) != 2: | ||||
|                 raise Exception("Line %d, Col. %d, the argument length should be 1" % (sexp[0]["line"], sexp[0]["col"])) | ||||
|             elif not isinstance(sexp[1], List): | ||||
|                 raise Exception("Line %d, Col. %d, the argument is not a list." % (sexp[1]["line"], sexp[1]["col"])) | ||||
|             else: | ||||
|                 ls = sexp[1].ls | ||||
|                 return ls[0] | ||||
| 
 | ||||
|         # (cdr List) | ||||
|         elif sexp[0]["token"] == "cdr": | ||||
|             if len(sexp) != 2: | ||||
|                 raise Exception("Line %d, Col. %d, the argument length should be 1" % (sexp[0]["line"], sexp[0]["col"])) | ||||
|             elif not isinstance(sexp[1], List): | ||||
|                 raise Exception("Line %d, Col. %d, the argument is not a list." % (sexp[1]["line"], sexp[1]["col"])) | ||||
|             else: | ||||
|                 ls = sexp[1].ls | ||||
|                 return ls[1:] | ||||
| 
 | ||||
|         # (cons any List) | ||||
|         elif sexp[0]["token"] == "cons": | ||||
|             if len(sexp) != 3: | ||||
|                 raise Exception("Line %d, Col. %d, the argument length should be 2" % (sexp[0]["line"], sexp[0]["col"])) | ||||
|             elif not isinstance(sexp[2], List): | ||||
|                 raise Exception("Line %d, Col. %d, the 2nd argument of cons is not a list." % (sexp[2]["line"], sexp[2]["col"])) | ||||
|             else: | ||||
|                 car = sexp[1] | ||||
|                 cdr = sexp[2].ls | ||||
|                 result_ls = List([sexp[1]]+cdr) | ||||
|                 return result_ls | ||||
|          | ||||
| 
 | ||||
|         elif sexp[0]["token"] == "ls-ref": | ||||
|             if len(sexp) != 3: | ||||
|                 raise Exception("Line %d, Col. %d, the argument length should be 1" % (sexp[0]["line"], sexp[0]["col"])) | ||||
|             elif not isinstance(sexp[1], List): | ||||
|                 raise Exception("Line %d, Col. %d, the 2nd argument of cons is not a list." % (sexp[2]["line"], sexp[2]["col"])) | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         # if it's a sub-xml-element, show the string form of it, or return the input unchanged. | ||||
|         # It's recommended to use it only print it in terminal with 'print' | ||||
|         elif sexp[0]["token"] == "xml-to-string": | ||||
|  | @ -384,6 +486,11 @@ class Interpreter: | |||
|             return ET.tostring(self.silexml, encoding="unicode") | ||||
| 
 | ||||
|         else: | ||||
|             ret = self.apply(sexp) | ||||
|             return ret | ||||
| 
 | ||||
|     def apply(self, sexp): | ||||
|              | ||||
|         sexp_new = [self.interprete_aux(x) for x in sexp] | ||||
|              | ||||
|         if isinstance(sexp_new[0], Lambda): | ||||
|  | @ -426,7 +533,7 @@ class Interpreter: | |||
|             if isinstance(before_stx[i], list): | ||||
|                 unification = self.unify(sexp[i], before_stx[i], unification) | ||||
|             elif before_stx[i]["token"] in unification.keys(): | ||||
|                 raise Exception("the variable %s is double defined." % before-stx[i]) | ||||
|                 raise Exception("the variable %s is double defined." % before_stx[i]) | ||||
|             elif re.match(r".+[.]{3}$", before_stx[i]["token"]): | ||||
|                 if i == len(before_stx) - 1: | ||||
|                     unification[before_stx[i]["token"]] = {"content": sexp[i:], "dotted":True} | ||||
|  | @ -467,8 +574,14 @@ class SubXMLElement: | |||
|     def __init__(self, element): | ||||
|         self.element = element | ||||
|      | ||||
|     def __str__(init): | ||||
|     def __str__(self): | ||||
|         return "" | ||||
| 
 | ||||
| # closure | ||||
| class List: | ||||
|     def __init__(self, ls): | ||||
|         self.ls = ls | ||||
| 
 | ||||
| # closure | ||||
| class Lambda: | ||||
|     def __init__(self, vars, body, env): | ||||
|  | @ -6,7 +6,7 @@ class Parser(): | |||
|         bool_pattern = r"(?P<bool>True|False)" | ||||
|         int_pattern  =r"(?P<int>[+-]?\d+)" | ||||
|         symbol_pattern = r"(?P<sym>[_a-zA-Z][-!:._0-9a-zA-Z]*)" | ||||
|         string_pattern = r"(?P<str>[\"]([^\"\\]|[\\][\\\"\n\t]|[\\])*?[\"])" | ||||
|         string_pattern = r"(?P<str>[\"]([^\"\\]|[\\][\\\"nt]|[\\])*?[\"])" | ||||
|         parenthesis_pattern = r"(?P<paren>[[]|[]])" | ||||
|         percent_pattern = r"(?P<percent>[%])" | ||||
|         space_pattern  = r"(?P<space>[ \t]+)" | ||||
|  | @ -14,13 +14,17 @@ from PyQt5 import QtWebEngineWidgets | |||
| from PyQt5.QtWidgets import * | ||||
| from PyQt5.Qsci import QsciScintilla | ||||
| 
 | ||||
| from Editor import qrc_resources | ||||
| src_dirname = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) | ||||
| sys.path.append(src_dirname) | ||||
| 
 | ||||
| from Editor import __about__ | ||||
| from Editor import FindReplace | ||||
| from Editor.Interpreter import Interpreter, Lambda | ||||
| from Editorimport CustomQsciEditor | ||||
| from Editor.Parser import Parser | ||||
| 
 | ||||
| from Clochur import qrc_resources | ||||
| 
 | ||||
| from Clochur import __about__ | ||||
| from Clochur import FindReplace | ||||
| from Clochur.Interpreter import Interpreter, Lambda | ||||
| from Clochur import CustomQsciEditor | ||||
| from Clochur.Parser import Parser | ||||
| 
 | ||||
| 
 | ||||
| sile_command = 'sile' | ||||
|  | @ -175,7 +179,6 @@ class Window(QMainWindow): | |||
|         format_menu = menuBar.addMenu("&Format") | ||||
|         format_menu.addAction(self.bold_action) | ||||
|         format_menu.addAction(self.italic_action) | ||||
|         format_menu.addAction(self.strike_action) | ||||
|         format_menu.addAction(self.underline_action) | ||||
| 
 | ||||
|         help_menu = menuBar.addMenu("&Help") | ||||
|  | @ -195,7 +198,11 @@ class Window(QMainWindow): | |||
|             self.opened_file_dirname = os.path.dirname(file_path[0]) | ||||
|             self.file = open(file_path[0], 'r', encoding='utf-8') | ||||
|             self.editor.setText(self.file.read()) | ||||
|             self.setWindowTitle("Clochur - %s" % self.filename) | ||||
|             self.editor.setModified(False) | ||||
|             self.file.close() | ||||
|         else: | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -207,7 +214,7 @@ class Window(QMainWindow): | |||
|              | ||||
|         else: | ||||
|             self.file = open(os.path.join(self.opened_file_dirname,self.filename), 'w', encoding='utf-8') | ||||
|             file_content = editor.text() | ||||
|             file_content = self.editor.text() | ||||
|             self.file.write(file_content) | ||||
|             self.file.close() | ||||
|              | ||||
|  | @ -218,6 +225,7 @@ class Window(QMainWindow): | |||
|                 with open(os.path.join(self.tmp_folder, self.tmp_file), 'r') as f: | ||||
|                     data = json.load(f) | ||||
|                     data["untitled"].remove(self.untitled_id) | ||||
|                     self.untitled_id = None | ||||
|                  | ||||
|                 with open(os.path.join(self.tmp_folder, self.tmp_file), 'w') as f: | ||||
|                     json.dump(data, f, indent=4) | ||||
|  | @ -286,10 +294,14 @@ class Window(QMainWindow): | |||
|         if self.editor.isModified(): | ||||
|             reply = QMessageBox.question(self,'','Do You want to save this file? The text has been modified', QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, QMessageBox.No) | ||||
|             if reply == QMessageBox.Yes: | ||||
|                 if self.filename !=  None: | ||||
|                     self.save_call() | ||||
|                 else: | ||||
| 
 | ||||
|                     file_path = QFileDialog.getSaveFileName(self, 'Save file as...', self.opened_file_dirname, "CLC typesetting format (*.clc)") | ||||
|                     if file_path[0] != '': | ||||
|                         self.file = open(file_path[0], 'w', encoding='utf-8') | ||||
|                     file_content = editor.text() | ||||
|                         file_content = self.editor.text() | ||||
|                         self.file.write(file_content) | ||||
|                         self.file.close() | ||||
|                         self.removing_untitled_id() | ||||
|  | @ -378,7 +390,6 @@ class Window(QMainWindow): | |||
| 
 | ||||
|         formatToolBar.addAction(self.bold_action) | ||||
|         formatToolBar.addAction(self.italic_action) | ||||
|         formatToolBar.addAction(self.strike_action) | ||||
|         formatToolBar.addAction(self.underline_action) | ||||
| 
 | ||||
|         '''create font adder''' | ||||
							
								
								
									
										
											BIN
										
									
								
								src/example.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/example.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in a new issue