diff --git a/texla/Renderers/MediaWikiRenderer.py b/texla/Renderers/MediaWikiRenderer.py index 78c219c..53edb97 100644 --- a/texla/Renderers/MediaWikiRenderer.py +++ b/texla/Renderers/MediaWikiRenderer.py @@ -1,579 +1,577 @@ import logging from .Renderer import Renderer from ..PageTree.PageTree import * class MediaWikiRenderer(Renderer): def __init__(self, configs, reporter): - super().__init__(reporter) + super().__init__(configs, reporter) self.configs = configs self.doc_title = configs['doc_title'] #saving the hooks self.render_hooks = { #root 'root-block': self.r_document, 'default': self.default, #text 'par': self.r_par, 'newpage': self.r_newpage, 'newline': self.r_newline, '\\': self.r_newline, 'text': self.r_text, 'clearpage': self.r_newpage, 'cleardoublepage': self.r_newpage, #formatting 'emph': self.r_textit, 'textbf': self.r_textbf, 'textit': self.r_textit, 'textsc': self.r_textsc, 'textsuperscript': self.r_superscript, 'textsubscript': self.r_subscript, 'underline': self.r_underline, 'uline': self.r_underline, '%': self.r_special_character, '&': self.r_special_character, '$': self.r_special_character, '{': self.r_special_character, '}': self.r_special_character, '#': self.r_special_character, '_': self.r_special_character, 'dots': self.r_dots, 'ldots': self.r_dots, 'flushright': self.r_flushright, 'flushleft': self.r_flushleft, 'center': self.r_center, 'centerline': self.r_center, 'abstract': self.r_abstract, 'linebreak': self.r_break, 'pagebreak': self.r_break, 'nolinebreak': self.r_break, 'nopagebreak': self.r_break, 'verbatim': self.r_verbatim, 'verb': self.r_verb, #spaces 'vspace': self.r_vspace, 'mandatory_space': self.r_mandatory_space, #theorems 'theorem' : self.r_theorem, 'proof' : self.r_proof, #sectioning 'part': self.sectioning, 'chapter': self.sectioning, 'section': self.sectioning, 'subsection': self.sectioning, 'subsubsection': self.sectioning, 'paragraph': self.sectioning, 'subparagraph': self.sectioning, #math 'displaymath': self.r_display_math, 'inlinemath': self.r_inline_math, 'ensuremath': self.r_inline_math, 'equation': self.r_display_math, 'eqnarray': self.r_align, 'multline': self.r_align, 'align': self.r_align, 'alignat': self.r_align, 'gather': self.r_gather, #lists 'itemize': self.r_itemize, 'enumerate': self.r_enumerate, 'description': self.r_description, #quotes 'quotation': self.r_quotes, 'quote': self.r_quotes, 'verse': self.r_verse, 'footnote': self.r_footnote, #labels 'label': self.r_label, 'ref': self.r_ref, 'vref': self.r_ref, 'pageref': self.r_ref, 'eqref': self.r_ref, #accents "accented_letter": self.r_accented_letter, #figures "figure": self.r_figure } - #register plugins - self.register_plugins(configs["plugins"]) #tree object self.tree = PageTree(configs) #parameter for list formatting self.list_level = '' #parameters for theorem handling self.in_theorem = False self.theorem_number = 0 self.th_numbering = {} ######################################## #STARTING POINT def start_rendering(self, root_block): """starting rendering from root-block""" #start rendering of base class super(MediaWikiRenderer, self).start_rendering(root_block) self.render_block(root_block) #after rendering self.tree.after_render() #end rendering of base class super(MediaWikiRenderer, self).end_rendering() ####### ROOT BLOCK def r_document(self, block): #we trigger the rendering of content text = self.render_children_blocks(block) #text is the tex outside sections self.tree.addText(text) #returning the text to respect the interface return text ######################################## #DEFAULT def default(self, block): #we don't print anything return '' ######################################### #TEXT def r_text(self, block): text = block.attributes['text'] - + # The following replace happens as ~ is the latex symbol # for unbreakable space return text.replace("~", " ") def r_newline(self, block): return '\n' def r_newpage(self, block): return '\n\n' def r_par(self, block): return '\n\n' ######################################### #SECTIONING def sectioning(self, block): title = block.attributes['title'] section_name = block.attributes['section_name'] #remove the \n insiede title title = re.sub('\\n*', '', title) #creation of the new page self.tree.createPage(title, section_name) #content processing text = self.render_children_blocks(block) #adding text to current page self.tree.addText(text) #exiting the section self.tree.exitPage() return '' ######################################### #MATH def r_display_math(self, block): s = block.attributes['content'] #rendering labels self.render_blocks(block.labels) return '' + s + '' def r_inline_math(self, block): s = block.attributes['content'] #rendering labels self.render_blocks(block.labels) return '' + s + '' def r_align(self, block): s = block.attributes['content'] #rendering labels self.render_blocks(block.labels) return '\\begin{align}' +\ s + '\end{align}' def r_gather(self, block): s = block.attributes['content'] output = [] for eq in s.split("\\\\"): eq = eq.replace("\n","").strip() output.append('' +\ eq + '') #rendering labels self.render_blocks(block.labels) return '\n'.join(output) ######################################### #LABELS and refs def r_label(self, block): label = block.attributes['label'] self.tree.addLabel(label) return '' def r_ref(self, block): ref = block.attributes['ref'] #saving ref in Babel of PageTree self.tree.addReference(ref) return "{{ref@"+ ref+ "}}" ######################################### #FIGURE def r_figure(self, block): captions = block.get_children("caption") includegraphics = block.get_children("includegraphics") s = "[[File:" if len(includegraphics): inc = includegraphics[0] s += inc.attributes["img_name"] else: return "" if len(block.get_children("centering")): s += "|" + self.configs["keywords"]["center"] if len(captions): cap = captions[0] s += "|" + cap.attributes["caption"] s += "]]" return s; ######################################### #FORMATTING def r_special_character(self, block): return block.attributes['character'] def r_dots(self, block): return '...' def r_textbf(self, block): s = [] s.append("\'\'\'") s.append(self.render_children_blocks(block)) s.append("\'\'\'") return ''.join(s) def r_textit(self, block): s = [] s.append("\'\'") s.append(self.render_children_blocks(block)) s.append("\'\'") return ''.join(s) def r_textsc(self, block): return self.render_children_blocks(block).upper() def r_superscript(self, block): s = [] s.append('') s.append(self.render_children_blocks(block)) s.append('') return ''.join(s) def r_subscript(self, block): s = [] s.append('') s.append(self.render_children_blocks(block)) s.append('') return ''.join(s) def r_underline(self, block): s = [] s.append('{{Sottolineato|') s.append(self.render_children_blocks(block)) s.append('}}') return ''.join(s) def r_abstract(self, block): s = [] s.append('{{Abstract|') s.append(self.render_children_blocks(block)) s.append('}}') return ''.join(s) def r_break(self, block): return '' def r_vspace(self,block): return '\n\n' def r_mandatory_space(self,block): return ' ' def r_verbatim(self, block): return '
' + block.attributes['content'] +'
' def r_verb(self, block): return '' + block.attributes['content'] +'' ######################################### #ALIGNMENT def r_center(self, block): s = [] s.append('{{Center|') s.append(self.render_children_blocks(block)) s.append('}}') return ''.join(s) def r_flushleft(self, block): s = [] s.append('{{Flushleft|') s.append(self.render_children_blocks(block)) s.append('}}') return ''.join(s) def r_flushright(self, block): s = [] s.append('{{Flushright|') s.append(self.render_children_blocks(block)) s.append('}}') return ''.join(s) ######################################### #LISTS def r_itemize(self, block): self.list_level += '*' s = ['\n'] for item in block.ch_blocks: s.append(self.list_level) s.append(self.render_children_blocks(item).strip()) s.append("\n") self.list_level = self.list_level[:-1] return ''.join(s) def r_enumerate(self, block): self.list_level += '#' s = ['\n'] for item in block.ch_blocks: s.append(self.list_level) s.append(self.render_children_blocks(item).strip()) s.append("\n") self.list_level = self.list_level[:-1] return ''.join(s) def r_description(self, block): s = ['\n'] for item in block.ch_blocks: s.append(';') s.append(item.attributes['word']) s.append(':') s.append(self.render_children_blocks(item)) s.append("\n") return ''.join(s) ######################################### #QUOTES def r_quotes(self, block): s = [] s.append('
') s.append(self.render_children_blocks(block)) s.append('
') return ''.join(s) def r_verse(self, block): s = [] s.append('
') s.append('\n'.join(self.render_children_blocks(block).split('//'))) s.append('
') return ''.join(s) def r_footnote(self, block): s = [] s.append("") s.append(self.render_children_blocks(block)) s.append("") return ''.join(s) ######################################### #Theorems def r_theorem(self, block): #the label in theorems is not working for now th_definition = block.attributes['definition'] th_title = '' if block.attributes['title'] != None: th_title +=" "+ block.attributes['title'] s = [] #adding the theorem to the tree self.theorem_number += 1 self.tree.addTheorem(str(self.theorem_number), th_definition) #checking if the Environment template is used environ = False if self.configs['lang'] =='it': if th_definition.lower() == 'teorema': #adding content to page through a template s.append("\n{{InizioTeorema|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineTeorema}}\n") elif th_definition.lower() == 'definizione': s.append("\n{{InizioDefinizione|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineDefinizione}}\n") elif th_definition.lower() == 'proposizione': s.append("\n{{InizioProposizione|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineProposizione}}\n") elif th_definition.lower() == 'lemma': s.append("\n{{InizioLemma|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineLemma}}\n") elif th_definition.lower() == 'corollario': s.append("\n{{InizioCorollario|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineCorollario}}\n") elif th_definition.lower()[:-2] == 'eserciz': s.append("\n{{InizioEsercizio|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineEsercizio}}\n") elif th_definition.lower()[:-1] == 'osservazion': s.append("\n{{InizioOsservazione|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineOsservazione}}\n") elif th_definition.lower()[:-2] == 'esemp': s.append("\n{{InizioEsempio|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineEsempio}}\n") elif th_definition.lower() == 'dimostrazione': s.append("\n{{InizioDimostrazione|titolo=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{FineDimostrazione}}\n") else: s.append("\n{{Environment|name="+ th_definition + \ "|title=" + th_title +\ "|content=") s.append(self.render_children_blocks(block)) s.append("}}\n") elif self.configs['lang'] =='en': if th_definition.lower() == 'theorem': #adding content to page through a template s.append("\n{{BeginTheorem|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndTheorem}}\n") elif th_definition.lower() == 'definition': s.append("\n{{BeginDefinition|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndDefinition}}\n") elif th_definition.lower() == 'proposition': s.append("\n{{BeginProposition|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndProposition}}\n") elif th_definition.lower() == 'lemma': s.append("\n{{BeginLemma|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndLemma}}\n") elif th_definition.lower() == 'corollary': s.append("\n{{BeginCorollary|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndCorollary}}\n") elif th_definition.lower() == 'exercise': s.append("\n{{BeginExercise|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndExercise}}\n") elif th_definition.lower() == 'observation': s.append("\n{{BeginObservation|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndObservation}}\n") elif th_definition.lower() == 'remark': s.append("\n{{BeginRemark|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndRemark}}\n") elif th_definition.lower() == 'example': s.append("\n{{BeginExample|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndExample}}\n") elif th_definition.lower() == 'demonstration': s.append("\n{{BeginDemonstration|title=" + \ th_title+"|number={{thnum@"+ str(self.theorem_number)+"}}"+\ "|anchor={{thanchor@"+ str(self.theorem_number) +"}}}}") s.append(self.render_children_blocks(block)) s.append("{{EndDemonstration}}\n") else: s.append("\n{{Environment|name="+ th_definition + \ "|title=" + th_title +\ "|content=") s.append(self.render_children_blocks(block)) s.append("}}\n") #exit from theorem ambient self.tree.exitTheorem() return '\n'.join(s) def r_proof(self, block): s=[] if self.configs['lang'] == 'it': if block.title !=None: s.append('\n{{InizioDimostrazione|titolo='+\ block.attributes['title']+ "}}") s.append(self.render_children_blocks(block)) s.append("{{FineDimostrazione}}\n") else: s.append('\n{{InizioDimostrazione}}') s.append(self.render_children_blocks(block)) s.append("{{FineDimostrazione}}\n") elif self.configs['lang'] == 'en': if block.title !=None: s.append('\n{{BeginProof|title='+\ block.attributes['title']+"}}") s.append(self.render_children_blocks(block)) s.append("{{EndProof}}\n") else: s.append('\n{{BeginProof}}') s.append(self.render_children_blocks(block)) s.append("{{EndProof}}\n") return '\n'.join(s) ######################################### #ACCENTED letters def r_accented_letter(self, block): if block.attributes["accent_type"] == '"' \ and block.attributes["letter"] == "a": return "รค" if block.attributes["accent_type"] in ["'","`"]: return block.attributes["letter"]+\ block.attributes["accent_type"] else: return block.attributes["letter"] diff --git a/texla/Renderers/Renderer.py b/texla/Renderers/Renderer.py index e127439..80c9888 100644 --- a/texla/Renderers/Renderer.py +++ b/texla/Renderers/Renderer.py @@ -1,178 +1,186 @@ from ..Parser import Blocks from ..Parser.TreeExplorer import TreeExplorer import logging import importlib class Renderer(): - def __init__(self, reporter): + def __init__(self, configs, reporter): + self.configs = configs self.reporter = reporter #hooks implemented directly by the Renderer class. self.render_hooks = {} #plugins hooks self.pre_render_hooks = {} self.post_render_hooks = {} self.start_hooks = [] self.end_hooks = [] self.loaded_plugins = {} self.tree_explorer = None + #registering plugins from the configs + self.register_plugins() - def register_plugins(self, plugins): - for plugin in plugins: + def register_plugins(self): + for plugin in self.configs["plugins"]: module = importlib.import_module("..plugins"+'.'+ plugin, __name__) if hasattr(module, "plugin_render_hooks"): self.loaded_plugins[plugin] = module self.register_render_plugin_hooks(module.plugin_render_hooks) logging.debug("Renderer.register_plugins "\ "@ Loaded plugin: {}".format(plugin)) logging.debug("Plugin {} render hooks: {}".format( plugin, list(module.plugin_render_hooks.keys()))) if hasattr(module, "plugin_lifecycle_hooks"): self.register_lifecyle_plugin_hooks(module.plugin_lifecycle_hooks) logging.debug("Plugin {} lifecycle hooks: {}".format( plugin, list(module.plugin_lifecycle_hooks.keys()))) + #adding the configurations to the plugin + if "plugins_configs" in self.configs: + if plugin in self.configs["plugins_configs"]: + logging.debug("Plugin {} passing configs...".format(plugin)) + module.configs = self.configs["plugins_configs"][plugin] def register_render_plugin_hooks(self, hooks): '''This function registers the hooks for renderer plugins. The plugins can define hooks for pre and post render actions. The pre hook receives the block before the rendering and can only return the block itself, modified. The post hook receive the block and the text from the renderer: it has to return the final text only. The keyword ALL creates a hooks for all the blocks. Note that it is always called after all the other hooks.''' for bl in hooks: if "pre" in hooks[bl]: self.register_pre_renderer_hook(bl, hooks[bl]["pre"]) if "post" in hooks[bl]: self.register_post_renderer_hook(bl, hooks[bl]["post"]) #checking ALL keyword if "ALL" in hooks: if "pre" in hooks["ALL"]: self.register_pre_renderer_hook(bl, hooks["ALL"]["pre"]) if "post" in hooks["ALL"]: self.register_post_renderer_hook(bl, hooks["ALL"]["post"]) def register_lifecyle_plugin_hooks(self, hooks): ''' This function registers the hooks for the renderer lifecycle. Plugins can register hooks for the start and end actions. The start hook is called with the root_block of the chain. The end hook is called without arguments. These hooks must be used only to signal the actions to the plugins.''' if "start" in hooks: self.register_start_hook(hooks["start"]) if "end" in hooks: self.register_end_hook(hooks["end"]) def register_pre_renderer_hook(self, block, hook): if block not in self.pre_render_hooks: self.pre_render_hooks[block] = [] self.pre_render_hooks[block].append(hook) def register_post_renderer_hook(self, block, hook): if block not in self.post_render_hooks: self.post_render_hooks[block] = [] self.post_render_hooks[block].append(hook) def register_start_hook(self, hook): self.start_hooks.append(hook) def register_end_hook(self, hook): self.end_hooks.append(hook) def start_rendering(self, root_block): '''This function create a TreeExplorer instance and passes it to the plugin that has the variable needs_tree_explorer=True. Then it starts the plugins''' self.tree_explorer = TreeExplorer(root_block) #passing the tree_explorer for pl in self.loaded_plugins.values(): if hasattr(pl, "needs_tree_explorer"): if pl.needs_tree_explorer: logging.debug("Renderer @ Inserting "\ "TreeExplorer into plugin {}".format(pl)) pl.tree_explorer = self.tree_explorer #starting the plugins for hook in self.start_hooks: hook(root_block) def end_rendering(self): #ending plugins for hook in self.end_hooks: hook() def render_children_blocks(self, block, collapse=True): '''This is one of the most important funciont of the rendering process. This function takes all the children blocks of a block and get they rendering output. If collapsed=True it returns a unique string, otherwise it returns a list of tuples with[(block_name, output)] ''' output = [] for bl in block.ch_blocks: #it's not necessary checking for renderer_hook #because default hook is mandatory output.append((bl.block_name, self.render_block(bl))) if collapse: return ''.join([x[1] for x in output]) else: return output def render_block(self, bl): '''This function calls the right render_hook for the block. If there isn't an hook it calld the default, that is mandatory''' output = "" ######### pre hooks ############ #hooks executed in the order of inserction #They receive the block and they can only modify the block object if bl.block_name in self.pre_render_hooks: for prehook in self.pre_render_hooks[bl.block_name]: #calling prehook with the block prehook(bl) #calling after the others the ALL hooks if "ALL" in self.pre_render_hooks: for prehook in self.pre_render_hooks["ALL"]: #calling prehook with the block prehook(bl) ######## rendering ############# if bl.block_name in self.render_hooks: logging.debug('Render @ block: ' + bl.block_name) output = self.render_hooks[bl.block_name](bl) else: #default hook is mandatory logging.debug('Render @ block: default@' + bl.block_name) #reporting to the Reporter if bl.block_name != "default": self.reporter.add_not_rendered_block(bl) output = self.render_hooks['default'](bl) ######## post hooks ########### #hooks executed in the order of inserction. #They receive the block and text. They have to return the #output text, that is passed to the next posthook if bl.block_name in self.post_render_hooks: for posthook in self.post_render_hooks[bl.block_name]: #calling posthook with the block and output output = posthook(bl, output) #calling ALL hooks after the others if "ALL" in self.post_render_hooks: for posthook in self.post_render_hooks["ALL"]: #calling posthook with the block and output output = posthook(bl, output) #final output return output def render_blocks(self, bls, collapse=False): '''This function renderes a list of blocks. It's the same as render_children_blocks but with a generic list''' output = [] for bl in bls: output.append((bl.block_name,self.render_block(bl))) if collapse: return ''.join([x[1] for x in output]) else: return output diff --git a/texla/Renderers/plugins/math_check_online.py b/texla/Renderers/plugins/math_check_online.py index bb7a006..7b56fa0 100644 --- a/texla/Renderers/plugins/math_check_online.py +++ b/texla/Renderers/plugins/math_check_online.py @@ -1,109 +1,110 @@ import requests import logging from multiprocessing import Process, Pool, Queue from os import path def request_formula(tex): - url_check = 'http://restbase.wikitolearn.org/pool.wikitolearn.org/v1/media/math/check/tex' + url_check = 'http://restbase.{0}/pool.{0}/v1/media/math/check/tex'.format(configs["domain"]) header = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' } payload = {'q': tex} r = requests.post(url_check, data=payload, headers=header) if r.status_code == 200: return True else: return False formulas = [] bad_formulas = Queue() def save_math(block): tex = block.attributes["content"] #saving the formula only if it's longer than 10 if len(tex) > 5: logging.debug("Plugin math_check_online @ saving formula {}".format( tex)) formulas.append((tex, block.id)) def save_math_align(block): tex = "\\begin{align}" + block.attributes["content"] + "\\end{align}" #saving the formula only if it's longer than 10 if len(tex) > 50: logging.debug("Plugin math_check_online @ saving formula {}".format( tex)) formulas.append((tex, block.id)) def check_math(formula): ok = request_formula(formula[0]) if ok: logging.info("Plugin math_check_online @ formula {}, block_id: {}". format("OK", formula[1])) else: logging.error("Plugin math_check_online @ formula {}, block_id: {}". format("BAD", formula[1])) bad_formulas.put(formula) def start_pool(): - pool = Pool(processes=6) + pool = Pool(processes=int(configs["threads"])) logging.info("Plugin math_check_online @ total formulas to check: {}". format(len(formulas))) pool.map(check_math, formulas) #saving results logging.info("GOOD FORMULAS: {} --- BAD FORMULAS: {}".format( len(formulas)-bad_formulas.qsize(), bad_formulas.qsize())) log_matherrors_file_path = path.relpath("sandbox/math_errors.txt") with open(log_matherrors_file_path, "w") as f: f.write("Math Errors Tree Log: \n") f.write("---------------------\n") ids = [] while not bad_formulas.empty(): form = bad_formulas.get() ids.append(form[1]) output = tree_explorer.print_tree_to_blocks(ids) f.write(output + "\n\n") def start_check(): p = Process(target=start_pool) p.start() plugin_render_hooks = { 'displaymath': { "pre": save_math }, 'inlinemath': { "pre": save_math }, 'ensuremath': { "pre": save_math }, 'equation': { "pre": save_math }, 'eqnarray': { "pre": save_math_align }, 'multline': { "pre": save_math_align }, 'align': { "pre": save_math_align }, 'alignat': { "pre": save_math_align } } plugin_lifecycle_hooks = {"end": start_check} needs_tree_explorer = True tree_explorer = None +configs = {}