fix recursive max bug

This commit is contained in:
Tan, Kian-ting 2021-06-28 23:35:14 +08:00
parent 42c4a28944
commit 0225017097
5 changed files with 141 additions and 41 deletions

View file

@ -2,10 +2,14 @@
[script "packages/font-fallback"] [script "packages/font-fallback"]
[script "packages/grid"] [script "packages/grid"]
[script "packages/image"] [script "packages/image"]
[script "packages/url"]
[define section-var 1] [define section-var 1]
[define sub-section-var 1] [define sub-section-var 1]
[define image-var 1]
[define section-title ""] [define section-title ""]
[define image-desc ""]
% custom macro % custom macro
[def-syntax section [def-syntax section
@ -26,6 +30,13 @@
[set! sub-section-var [+ sub-section-var 1]] [set! sub-section-var [+ sub-section-var 1]]
]]] ]]]
[def-syntax image-desc
[[_ x][str-append-many
[set! image-desc [str-append-many [str image-var] [str ". " ] [str x]]]
[call center [italic image-desc]]
[set! sub-section-var [+ sub-section-var 1]]
]]]
[docu-para [[class "book"][papersize "b5"]]] [docu-para [[class "book"][papersize "b5"]]]
[docu [docu
@ -35,11 +46,15 @@
[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."] [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."]
Author: Yoxem Chen (aka Tan, Kian-ting) <[call href [[src "mailto:yoxem.tem98@nctu.edu.tw"]] "yoxem.tem98@nctu.edu.tw"]>
Website: [call href [[src "https://www.github.com/Yoxem/Clochur"]] "https://www.github.com/Yoxem/Clochur"]
[section "What is Clochur?"] [section "What is Clochur?"]
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. 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, It generate a XML that is readable for SILE, which is a typesetting engine written in Lua,
and it generate PDF with SILE. and it generate PDF with SILE.
@ -54,12 +69,68 @@ The functions that it has (although may be buggy or needed to be tested) is:
[str "- lambda function"], function definition. [str "- lambda function"], function definition.
[subsection "Why it's called Clochur?"]
The author has (unofficially) learned Irish language (for a while and uncontinuously), so use the name.
[subsection "How is the language? It seems that it uses brackets insteads of parathesis."]
The langauge is inspired by SILE and Scheme, even though it has some different characteristics. To make the code neat and consider that parathesis is used more often than bracket, so it's more suitable to use bracket for syntatical usage.
It's a toy language, so many of the function of Scheme, is not used here (for example call/cc), and there is no "\"let\"" to support local variables. However, you can call SILE function and using the packages of it with "\"call\"" and "\"script\"" respectively.
[subsection "Does it support Taiwanese (Hokkien)/Hakka/Mandarin/Japanese/Korean or any other language that I want?"]
SILE supports utf-8, and Clochur will generate a XML that is readable to SILE, as long as any language that SILE can support, Clochur will support. It you find any bug, please tell me.
[section "Simple manual"] [section "Simple manual"]
[subsection "Editor interface"] [subsection "Editor interface"]
[call img [[src "total-interface.png"] [height "200px"]]] [call img [[src "total-interface.png"] [height "200px"]]]
[image-desc "The interface of Clochur"]
Clochur is not a WYSIWYG editor, you have to type the lisp language by your self. Nevertheless, it's not a pure text-editor, it contains a PDF viewer powered by PDF.js, If you have edited you code, you can click the green right arrow botton on the first toolbar to convert it to XML file, then generate and show PDF file from it.
[call img [[src "toolbars.png"] [height "60pt"]]]
[image-desc "The toolbars of Clochur"]
The description of the botton of the 1st toolbar is shown below (from left to right):
- Create a file (create a new window)
- Open a file
- Save a file
- Save as...
- Convert to PDF
- Redo
- Undo
- Cut
- Copy
- Paste
The description of the botton of the 2nd toolbar is shown below (from left to right):
- apply "bold" macro to the selected text
- apply "italic" macro to the selected text
- apply "underline" macro to the selected text
- "font" list
- apply the "font" shown in the "font" list to the selected text
[subsection "Arimetic calculation and variable and function definition"] [subsection "Arimetic calculation and variable and function definition"]
@ -76,7 +147,6 @@ The functions that it has (although may be buggy or needed to be tested) is:
Using [font-family "Noto Sans Mono CJK TC" "def-syntax"], you can add your macro to sile. the example is a "custom-section" macro: Using [font-family "Noto Sans Mono CJK TC" "def-syntax"], you can add your macro to sile. the example is a "custom-section" macro:
[call noindent][font-family "Noto Sans Mono CJK TC" "[def-syntax subsection"] [call noindent][font-family "Noto Sans Mono CJK TC" "[def-syntax subsection"]
[call noindent][font-family "Noto Sans Mono CJK TC" "[[_ x][str-append"] [call noindent][font-family "Noto Sans Mono CJK TC" "[[_ x][str-append"]

View file

@ -17,15 +17,7 @@ class CustomQsciEditor(QsciScintilla):
# Margin 0 for line numbers
font = QFont()
font.setFamily(self.font_family)
font.setPointSize(self.font_size)
fontMetrics = QFontMetrics(font)
self.setMarginsFont(font)
self.setMarginWidth(0, fontMetrics.width("00") + 6)
self.setMarginLineNumbers(0, True)
self.setMarginsBackgroundColor(QColor("#cccccc"))
# brace matching # brace matching
@ -79,6 +71,17 @@ class CustomQsciEditor(QsciScintilla):
# "prepare" the QsciAPIs-object: # "prepare" the QsciAPIs-object:
self.auto_complete_api.prepare() self.auto_complete_api.prepare()
# Margin 0 for line numbers
font = QFont()
font.setFamily(self.font_family)
font.setPointSize(self.font_size)
fontMetrics = QFontMetrics(font)
self.setMarginsFont(font)
self.setMarginWidth(0, fontMetrics.width("000") + 5)
self.setMarginLineNumbers(0, True)
self.setMarginsBackgroundColor(QColor("#cccccc"))
def append_autocompletion_item(self, item): def append_autocompletion_item(self, item):
self.auto_complete_api.add(item) self.auto_complete_api.add(item)
self.auto_complete_api.prepare() self.auto_complete_api.prepare()

View file

@ -32,10 +32,10 @@ class Interpreter:
[[_ x y...] [SILE[docu-aux x y...]]]] [[_ x y...] [SILE[docu-aux x y...]]]]
[def-syntax docu-aux %[def-syntax docu-aux
[[_ x] [str x]] % [[_ x] [str x]]
[[_ [x...]] [str [x...]]] % [[_ [x...]] [str [x...]]]
[[_ x y...] [str-append [docu-aux x] [docu-aux y...]]]] % [[_ x y...] [str-append [docu-aux x] [docu-aux y...]]]]
[def-syntax str-append-many [def-syntax str-append-many
[[_ x y] [str-append x y]] [[_ x y] [str-append x y]]
@ -126,14 +126,17 @@ class Interpreter:
return string return string
# \[ => [ ; \] => ] ; \\ => \ # \[ => [ ; \] => ] ; \\ => \
def remove_escaping_chars(self, sexp): def remove_and_change_escaping_chars(self, sexp):
if isinstance(sexp, list): if isinstance(sexp, list):
sexp = [self.remove_escaping_chars(x) for x in sexp] sexp = [self.remove_and_change_escaping_chars(x) for x in sexp]
elif not sexp["type"] in ["int", "flo"]: elif not sexp["type"] in ["int", "flo"]:
sexp_word = sexp["token"] sexp_word = sexp["token"]
sexp_word = sexp_word.replace("\\[", "[") sexp_word = sexp_word.replace("\\[", "[")
sexp_word = sexp_word.replace("\\]", "]") sexp_word = sexp_word.replace("\\]", "]")
sexp_word = sexp_word.replace("\\\\", "\\") sexp_word = sexp_word.replace("\\\\", "\\")
sexp_word = sexp_word.replace("&", "&amp;")
sexp_word = sexp_word.replace("<", "&lt;")
sexp_word = sexp_word.replace(">", "&gt;")
sexp["token"] = sexp_word sexp["token"] = sexp_word
else: else:
pass pass
@ -142,7 +145,7 @@ class Interpreter:
def interprete(self, sexps): def interprete(self, sexps):
sexps = self.remove_escaping_chars(sexps) sexps = self.remove_and_change_escaping_chars(sexps)
sexps = self.remove_spaces_and_newlines(sexps) sexps = self.remove_spaces_and_newlines(sexps)
result = None result = None
@ -500,6 +503,13 @@ class Interpreter:
# else: # else:
# self.silexml.text += self.interprete_aux(sexp[1]) # self.silexml.text += self.interprete_aux(sexp[1])
elif sexp[0]["token"] == "docu-aux":
args = sexp[1:]
new_args = [[{"token":"str", "style":"sym"} , arg] for arg in args]
new_args_processed = [self.interprete_aux(arg) for arg in new_args]
return "".join(new_args_processed)
elif sexp[0]["token"] == "SILE": elif sexp[0]["token"] == "SILE":
inner = self.interprete_aux(sexp[1]) inner = self.interprete_aux(sexp[1])

View file

@ -263,16 +263,29 @@ class Window(QMainWindow):
pass pass
def save_pdf_call(self): def save_pdf_call(self):
convert_folder = self.opened_file_dirname
dest_pdf_path = QFileDialog.getSaveFileName(self, 'Save pdf as...', self.opened_file_dirname, "Porfable document format (*.pdf)") dest_pdf_path = QFileDialog.getSaveFileName(self, 'Save pdf as...', self.opened_file_dirname, "Porfable document format (*.pdf)")
if dest_pdf_path[0] != '': if dest_pdf_path[0] != '':
self.convert_call() self.convert_call()
sile_pdf_path = os.path.join(self.tmp_folder, self.tmp_output_file+".pdf") sile_pdf_path = os.path.join(convert_folder, self.tmp_output_file+".pdf")
shutil.copyfile(sile_pdf_path, dest_pdf_path[0]) shutil.copyfile(sile_pdf_path, dest_pdf_path[0])
pass pass
def convert_call(self): def convert_call(self):
will_convert = True
if self.filename == None or self.editor.isModified():
reply = QMessageBox.question(self,'','You have to save the content before convert it. Save it?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
self.save_call()
else:
will_convert = False
if will_convert:
text = self.editor.text() text = self.editor.text()
parser = Parser() parser = Parser()
@ -281,8 +294,10 @@ class Window(QMainWindow):
intepreter = Interpreter() intepreter = Interpreter()
result = intepreter.interprete(parse_tree) result = intepreter.interprete(parse_tree)
sile_xml_path = os.path.join(self.tmp_folder, self.tmp_output_file+".xml") convert_folder = self.opened_file_dirname
sile_pdf_path = os.path.join(self.tmp_folder, self.tmp_output_file+".pdf")
sile_xml_path = os.path.join(convert_folder, self.tmp_output_file+".xml")
sile_pdf_path = os.path.join(convert_folder, self.tmp_output_file+".pdf")
with open(sile_xml_path, "w") as xml: with open(sile_xml_path, "w") as xml:
xml.write(result) xml.write(result)
@ -469,9 +484,11 @@ class Window(QMainWindow):
def remove_tmp_outputs(self): def remove_tmp_outputs(self):
sile_xml_path = os.path.join(self.tmp_folder, self.tmp_output_file+".xml") convert_folder = self.opened_file_dirname
sile_pdf_path = os.path.join(self.tmp_folder, self.tmp_output_file+".pdf")
sile_toc_path = os.path.join(self.tmp_folder, self.tmp_output_file+".toc") sile_xml_path = os.path.join(convert_folder, self.tmp_output_file+".xml")
sile_pdf_path = os.path.join(convert_folder, self.tmp_output_file+".pdf")
sile_toc_path = os.path.join(convert_folder, self.tmp_output_file+".toc")
if os.path.isfile(sile_xml_path): if os.path.isfile(sile_xml_path):
os.remove(sile_xml_path) os.remove(sile_xml_path)

Binary file not shown.