def write_deps(dirname, deps): """Writes dependencies into a given module. """ f = lmh_locate("content", match_repo(dirname), "META-INF", "MANIFEST.MF") n = re.sub(r"dependencies: (.*)", "dependencies: "+",".join(deps), read_file(f)) write_file(f, n) std("Wrote new dependencies to", f)
def my_excepthook(exctype, value, tb): if exctype == KeyboardInterrupt: return e = ''.join(traceback.format_exception(exctype, value, tb)) err(e) err("lmh seems to have crashed with %s"%exctype) err("a report will be generated in ") s = "cwd = {0}\n args = {1}\n".format(cwd, sys.argv) s = s + e write_file(lmh_locate("logs", time.strftime("%Y-%m-%d-%H-%M-%S.log")), s)
def my_excepthook(exctype, value, tb): if exctype == KeyboardInterrupt: return e = ''.join(traceback.format_exception(exctype, value, tb)) err(e) err("lmh seems to have crashed with %s" % exctype) err("a report will be generated in ") s = "cwd = {0}\n args = {1}\n".format(cwd, sys.argv) s = s + e write_file(lmh_locate("logs", time.strftime("%Y-%m-%d-%H-%M-%S.log")), s)
def find_and_replace_file(file, match, replace, replace_match = None): """Finds and replaces a single file. """ if len(match) != len(replace): err("Find and Replace patterns are not of the same length. ") return False # Compile thex regexp try: match_regex = [re.compile(m) for m in match] except Exception as e: err(e) err("Unable to compile regular expressions. ") return False # get the repository repo = os.path.relpath(find_repo_dir(file), lmh_locate("content")) # We did nothing yet did = False if replace_match == None: def replace_match(match, replace): # TODO: Migrate this to the parent scope. # did = True # Make a template, replacer_template = {} replacer_template["repo"] = repo for i, g in enumerate(match.groups()): replacer_template["g"+str(i)] = g # And replace in it return Template(replace).substitute(replacer_template) # Read file and search file_content = read_file(file) new_file_content = file_content # Iterate over the regexes and replace for (m, r) in zip(match_regex, replace): new_file_content = re.sub(m, lambda x:replace_match(x, r), new_file_content) if file_content != new_file_content: std(file) # If something has changed, write back the file. write_file(file, new_file_content) if did: std(file) return did
def export(f=None): """Exports the list of currently installed repositories. """ # Get all locally installed directories installed = match_repos(lmh_locate("content")) if (f == None): for mod in installed: std(mod) return True try: write_file(f, os.linesep.join(installed)) return True except: err("Unable to write %s" % f) return False
def export(f = None): """Exports the list of currently installed repositories. """ # Get all locally installed directories installed = match_repos(lmh_locate("content")) if(f == None): for mod in installed: std(mod) return True try: write_file(f, os.linesep.join(installed)) return True except: err("Unable to write %s" % f) return False
def add_symbols(fname, warns=[]): # Add missing symbols form language bindings to module q = find_sds(fname, warns) if len(q) == 1: # we have already done something return q[0] (fmodname, defs, syms, symdefs, modcontent) = q # check if we still need them def need_sym(d): # negated req = ["sym", d[1], d[2]] try: name = "-".join(d[2]) except: name = "" # Normalise for issue #166 req[2] = "-".join(req[2]).split("-") req[1] = len(req[2]) # We have an empty argument, what's this? if name == "": # it is empty return False return not ((req in syms) or (name in symdefs)) # OK filter them out required = list(filter(need_sym, defs)) # Add them if we need to if len(required) > 0: std("Adding %s symbol definition(s) from %s: " % (len(required), fname), newline=False) towrite = add_symis(modcontent, required) std() write_file(fmodname, towrite) return True
def add_symbols(fname, warns=[]): # Add missing symbols form language bindings to module q = find_sds(fname, warns) if len(q) == 1: # we have already done something return q[0] (fmodname, defs, syms, symdefs, modcontent) = q # check if we still need them def need_sym(d): # negated req = ["sym", d[1], d[2]] try: name = "-".join(d[2]) except: name = "" # Normalise for issue #166 req[2] = "-".join(req[2]).split("-") req[1] = len(req[2]) # We have an empty argument, what's this? if name == "": # it is empty return False return not ((req in syms) or (name in symdefs)) # OK filter them out required = list(filter(need_sym, defs)) # Add them if we need to if len(required) > 0: std("Adding %s symbol definition(s) from %s: " % (len(required), fname), newline = False) towrite = add_symis(modcontent, required) std() write_file(fmodname, towrite) return True
def copy_template_dir(source, destination, vars): """Copies over a template directory. """ # Make absolute paths source = os.path.abspath(source) destination = os.path.abspath(destination) try: # Remove already existing files. distutils.dir_util.copy_tree(source, destination) # Find all the template files for f in find_files(destination, "tpl")[0]: # Substitute everything in the template newcontent = Template(read_file(f)).safe_substitute(vars) write_file(f[:-len(".tpl")], newcontent) # Delete the tpl file os.remove(f) except Exception as e: err("Error initalising template. ") err(e) return False return True
def install_branch(self, branch): """ Installs the given branch. """ # Resolve path to branch. (rpath, dpath) = self.get_paths(branch) # make sure it exists if not dpath: err("Unable to find given generated content branch '" + branch + "'. ") return False # and is not installed. if self.is_installed(branch): err("Given generated branch '" + branch + "' already installed. Did you want to pull?") return False (o, e) = do_data(rpath, "config", "--local", "--get", "remote.origin.url") if not do(rpath, "rev-parse", "--verify", "--quiet", branch): if not do(rpath, "branch", branch, "--track", "origin/" + branch): return False # Clone it shared if not do(rpath, "clone", rpath, dpath, "--shared", "-b", branch): return False # set up .git/objects/info/alternates relatively if not write_file(os.path.join(dpath, ".git/objects/info/alternates"), "../../../.git/objects"): return False # and set the origin correctly. if not do(dpath, "remote", "set-url", "origin", o.rstrip("\n")): return False return do(rpath, "branch", "-D", branch)
def install_branch(self, branch): """ Installs the given branch. """ # Resolve path to branch. (rpath, dpath) = self.get_paths(branch) # make sure it exists if not dpath: err("Unable to find given generated content branch '"+branch+"'. ") return False # and is not installed. if self.is_installed(branch): err("Given generated branch '"+branch+"' already installed. Did you want to pull?") return False (o, e) = do_data(rpath, "config", "--local", "--get", "remote.origin.url") if not do(rpath, "rev-parse", "--verify", "--quiet", branch): if not do(rpath, "branch", branch, "--track", "origin/"+branch): return False # Clone it shared if not do(rpath, "clone", rpath, dpath, "--shared", "-b", branch): return False # set up .git/objects/info/alternates relatively if not write_file(os.path.join(dpath, ".git/objects/info/alternates"), "../../../.git/objects"): return False # and set the origin correctly. if not do(dpath, "remote", "set-url", "origin", o.rstrip("\n")): return False return do(rpath, "branch", "-D", branch)
def create_multi(modname, pre_terms, *langs): if len(langs) == 0: err("You need to create at least one language. ") return False lang = langs[0] # Read the module try: content = read_file(modname + ".tex") except: err("Unable to read original module", modname + ".tex") return False # Module content module_content_regex = r"^((?:.|\n)*)\\begin\{module\}\[(?:(.*),\s*)?id=([^,\]]*)(?:\s*(.*))\]((?:.|\n)*?)\\end\{module\}((?:.|\n)*)$" module_move_regex = r"(\\(?:gimport|symdef|symtest|symvariant|symi+)(?:(?:\[(?:[^\]])*\])|(?:\{(?:[^\}])*\}))*((\n|$|\s)?))" # Find the module mod_content = re.findall(module_content_regex, content) if len(mod_content) != 1: err("Expected exactly one module environment. (Is the module really monolingual?)" ) return False mod_content = mod_content[0] # Main Language Content main_module = "" main_language = "" # Prefix and suffix to add to the module mod_prefix = mod_content[0] mod_suffix = mod_content[5] # Id of the module mod_id = mod_content[2] mod_meta = mod_content[1] + mod_content[3] if mod_meta != "": mod_meta = "[" + mod_meta + "]" # We only want to move these module_to_move = "".join( [m[0] for m in re.findall(module_move_regex, mod_content[4])]) module_keep = re.sub(module_move_regex, lambda match: match.group(2), mod_content[4]) # Assemble the main module main_module = mod_prefix main_module += "\\begin{modsig}" + mod_meta + "{" + mod_id + "}" main_module += module_to_move main_module += "\\end{modsig}" main_module += mod_suffix try: write_file(modname + ".tex", main_module) except: err("Unable to write", modname + ".tex") return False # Assemble the main language binding main_language = mod_prefix main_language += "\\begin{modnl}" + mod_meta + "{" + mod_id + "}{" + lang + "}\n" main_language += module_keep main_language += "\n\\end{modnl}" main_language += mod_suffix try: write_file(modname + "." + lang + ".tex", main_language) except: err("Unable to write", modname + "." + lang + ".tex") return False lmh.lib.io.__supressStd__ = True # Add the symbols frome the language file name add_symbols(modname + "." + lang + ".tex") # Translate to all the other languages for l in langs[1:]: if not transmod(modname, lang, l, pre_terms=pre_terms): lmh.lib.io.__supressStd__ = False return False lmh.lib.io.__supressStd__ = False std("Created multilingual module", modname + ".tex") # Thats it. return True
def init_branch(self, branch): """ Creates a new branch for status information. """ # Get name and path. bsplit = branch.split(":") if len(bsplit) == 1: (name, pth) = (bsplit[0], bsplit[0]) else: (name, pth) = (bsplit[0], bsplit[1]) std("Creating branch '" + name + "' at '" + pth + "'. ") # Check if the branch already exists. if name in self.get_all_branches(tuple=False): err("Branch '" + name + "' already exists, can not create it again. Use --install to install. " ) return False # Get the paths rpath = match_repo(self.repo, abs=True) dpath = os.path.join(rpath, pth) meta_inf_path = os.path.join(rpath, "META-INF", "MANIFEST.MF") # Find paths for the .gitignore gitignore_path = os.path.join(rpath, ".gitignore") gitignore_entry = os.path.join("/", pth) + "\n" # and either add to it or create it. if os.path.isfile(gitignore_path): write_file(gitignore_path, read_file(gitignore_path) + gitignore_entry) else: write_file(gitignore_path, gitignore_entry) # Update the meta-inf written = False lines = get_metainf_lines(self.repo) # try to append it to a line that already exists. for (i, l) in enumerate(lines): if l.startswith(gbranchstring): lines[i] = lines[i].rstrip("\n") + " " + branch written = True break # or make a new one. if written == False: lines.extend([gbranchstring + " " + branch]) # and write that file. write_file(meta_inf_path, lines) # Create the orphaned branch. if not make_orphan_branch(rpath, name): return False # push it if not do(rpath, "push", "-u", "origin", name): err("Pushing branch to origin failed. ") return False # Clear the deploy branch cache for this repository. self.clear_branch_cache() # install it. if not self.install_branch(name): return False # change the commit message if not do(dpath, "commit", "--amend", "--allow-empty", "-m", "Create deploy branch. "): return False # and push it. if not do(dpath, "push", "--force", "origin", name): return False std("Generated files branch '" + name + "' created, installed and pushed. ") std("Please commit and push META-INF/MANIFEST.MF and .gitignore to publish installation. " ) return True
def transmod(modname, org_lang, dest_lang, pre_terms = {}): """Translate a module from one language to another. """ # Load json from a file if pre_terms is a string if type(pre_terms) == str: try: pre_terms = json.loads(read_file(pre_terms)) except: try: pre_terms = json.loads(pre_terms) except: err("Unable to load json in file %r" % pre_terms) err("Make sure you have given a valid JSON-encoded string or path to a valid .json file. ") return False # Load the set of pre-translated terms if org_lang in pre_terms: pre_terms = pre_terms[org_lang] if dest_lang in pre_terms: pre_terms = pre_terms[dest_lang] else: pre_terms = {} else: pre_terms = {} # filenames for the original + translated modules orfn = "%s.%s.tex" % (modname, org_lang) newfn = "%s.%s.tex" % (modname, dest_lang) # read the original file try: content = read_file(orfn) except: err("Unable to read original module", orfn) return False # # STEP 1: Replace the third argument to the modnl + viewnl environments # content = re.sub(r"(\\begin\{modnl\}\[[^\]]*\]\{[^\}]*\})\{"+org_lang+r"\}", r"\1{"+dest_lang+"}", content) content = re.sub(r"(\\begin\{viewnl\}\[[^\]]*\]\{[^\}]*\})\{"+org_lang+r"\}", r"\1{"+dest_lang+"}", content) # # STEP 2: Update everything inside the environments # def replacer(match): content = match.group(2) # trefi -> mtrefi content = re.sub(r"\\trefi\[([^\]]*)\]\{([^\}]*)\}", r"\\mtrefi[\1?\2]{\\ttl{\2}}", content) # trefii -> mtrefii content = re.sub(r"\\trefii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}", r"\\mtrefii[\1?\2-\3]{\\ttl{\2 \3}}", content) # trefiii -> mtrefiii content = re.sub(r"\\trefiii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\mtrefiii[\1?\2-\3-\4]{\\ttl{\2 \3 \4}}", content) # defi content = re.sub(r"\\defi\[([^\]]*)\]\{([^\}]*)\}", r"\\defi[\1]{\\ttl{\2}}", content) content = re.sub(r"\\defi\{([^\}]*)\}", r"\\defi[\1]{\\ttl{\1}}", content) # defii content = re.sub(r"\\defii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}", r"\\defii[\1]{\\ttl{\2}}{\\ttl{\3}}", content) content = re.sub(r"\\defii\{([^\}]*)\}\{([^\}]*)\}", r"\\defii[\1-\2]{\\ttl{\1}}{\\ttl{\2}}", content) # defiii content = re.sub(r"\\defiii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\defiii[\1]{\\ttl{\2}}{\\ttl{\3}}{\\ttl{\4}}", content) content = re.sub(r"\\defiii\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\defiii[\1-\2-\3]{\\ttl{\1}}{\\ttl{\2}}{\\ttl{\3}}", content) def inner_supper(m): # Inner replacement function # Inserts the \ttl before any trailing whitespace. (sub_inner, n) = re.subn(r"([\n\f\t\v\s]+)$", r"}\1", m.group(1)) if n == 0: sub_inner+="}" return r"\ttl{"+sub_inner+m.group(6) def supper(m): # Outer replacement function. toreplace = m.group(4) if re.match(r"^([\n\f\t\v\s]*)$", toreplace): # we are only whitespaces => do nothing pass else: # we are ntop only whitespaces => replace some sentences. toreplace = re.sub(r"(((\w)+\s+)*((\w)+\s*))([\.\!\?\,\;]?)", inner_supper, toreplace) return m.group(1)+toreplace+m.group(5) # Replace non-wrapped text fragments content = re.sub(r"((\]|\}|\$[^\$]*\$)(\w*))([^\\\{\}\$\]\[]+)(\s*)", supper, content) # and return the content return match.group(1)+content+match.group(4) # Replace text inside the environments of modnl and viewnl content = re.sub(r"(\\begin{modnl})((.|\n)*)(\\end{modnl})", replacer, content) content = re.sub(r"(\\begin{viewnl})((.|\n)*)(\\end{viewnl})", replacer, content) # # STEP 3: Apply the pre-translated directory to \ttl{...} # # Replace all the technical terms def replacer2(match): # prefer full matches if match.groups(1)[0] in pre_terms: return match.groups(1)[0][pre_terms] # Split the terms and look check if we can translate them terms = [] for t in match.groups(1)[0].split(" "): if t in pre_terms: terms.append((pre_terms[t], True)) else: terms.append((t, False)) # Put the results back together result = "" is_open_ttl = False # For each of the terms for (r, s) in terms: if not is_open_ttl: # We do not have an openn ttl if s: result+=r+" " else: result+="\\ttl{"+r+" " is_open_ttl = True else: # We do have an open ttl if s: result += result[:-1]+"} "+r+" " is_open_ttl = False else: result += r+" " # Close the last bracket if needed result = result[:-1] if is_open_ttl: result +="}" return result content = re.sub(r"\\ttl\{([^\}]*)\}", replacer2, content) # write back the file try: write_file(newfn, content) except: err("Unable to write new module", newfn) return False # and do some logging std("Prepared translation of", modname, "from") std(orfn) std("to") std(newfn) std("Please finish the translation and then commit the module. ") # we need it for the return code return True
def create_multi(modname, pre_terms, *langs): if len(langs) == 0: err("You need to create at least one language. ") return False lang = langs[0] # Read the module try: content = read_file(modname+".tex") except: err("Unable to read original module", modname+".tex") return False # Module content module_content_regex = r"^((?:.|\n)*)\\begin\{module\}\[(?:(.*),\s*)?id=([^,\]]*)(?:\s*(.*))\]((?:.|\n)*?)\\end\{module\}((?:.|\n)*)$" module_move_regex = r"(\\(?:gimport|symdef|symtest|symvariant|symi+)(?:(?:\[(?:[^\]])*\])|(?:\{(?:[^\}])*\}))*((\n|$|\s)?))" # Find the module mod_content = re.findall(module_content_regex, content) if len(mod_content) != 1: err("Expected exactly one module environment. (Is the module really monolingual?)") return False mod_content = mod_content[0] # Main Language Content main_module = "" main_language = "" # Prefix and suffix to add to the module mod_prefix = mod_content[0] mod_suffix = mod_content[5] # Id of the module mod_id = mod_content[2] mod_meta = mod_content[1]+mod_content[3] if mod_meta != "": mod_meta = "["+mod_meta+"]" # We only want to move these module_to_move = "".join([m[0] for m in re.findall(module_move_regex, mod_content[4])]) module_keep = re.sub(module_move_regex, lambda match:match.group(2), mod_content[4]) # Assemble the main module main_module = mod_prefix main_module += "\\begin{modsig}"+mod_meta+"{"+mod_id+"}" main_module += module_to_move main_module += "\\end{modsig}" main_module += mod_suffix try: write_file(modname+".tex", main_module) except: err("Unable to write", modname+".tex") return False # Assemble the main language binding main_language = mod_prefix main_language += "\\begin{modnl}"+mod_meta+"{"+mod_id+"}{"+lang+"}\n" main_language += module_keep main_language += "\n\\end{modnl}" main_language += mod_suffix try: write_file(modname+"."+lang+".tex", main_language) except: err("Unable to write", modname+"."+lang+".tex") return False lmh.lib.io.__supressStd__ = True # Add the symbols frome the language file name add_symbols(modname+"."+lang+".tex") # Translate to all the other languages for l in langs[1:]: if not transmod(modname, lang, l, pre_terms = pre_terms): lmh.lib.io.__supressStd__ = False return False lmh.lib.io.__supressStd__ = False std("Created multilingual module", modname+".tex") # Thats it. return True
def set_config(key, value): """ Sets a configuration setting to a certain value. """ # first ensure the value is a string value = str(value) # check if the given key exists if not key in config_meta: err("Option", key, "does not exist. ") return False # Get the datatype of the config setting datatype = config_meta[key]["type"] # and typecast to the given type if datatype == "string": value = str(value) elif datatype == "bool": value = value.lower() if value == "true" or value == "1" or value == "on": value = True elif value == "false" or value == "0" or value == "off": value = False else: err("Option", key, " is of type boolean, please use the values 'true' or 'false'. ") return False elif datatype == "int": try: value = int(value) except: err("Option", key, " is of type integer, please use a valid integer. ") return False elif datatype == "int+": try: value = int(value) if value < 0: raise ValueError except: err("Option", key, " is of type positive integer, please use a valid positive integer. ") return False # Re-load the existing data data = {} try: data = json.loads(read_file(config_file)) except: pass # write the config setting data[key] = value # and rew-rite the json file. try: write_file(config_file, json.dumps(data, indent=4)) except: err("Unable to write to config file. ") return False return True
def set_config(key, value): """ Sets a configuration setting to a certain value. """ # first ensure the value is a string value = str(value) # check if the given key exists if not key in config_meta: err("Option", key, "does not exist. ") return False # Get the datatype of the config setting datatype = config_meta[key]["type"] # and typecast to the given type if datatype == "string": value = str(value) elif datatype == "bool": value = value.lower() if value == "true" or value == "1" or value == "on": value = True elif value == "false" or value == "0" or value == "off": value = False else: err( "Option", key, " is of type boolean, please use the values 'true' or 'false'. " ) return False elif datatype == "int": try: value = int(value) except: err("Option", key, " is of type integer, please use a valid integer. ") return False elif datatype == "int+": try: value = int(value) if value < 0: raise ValueError except: err( "Option", key, " is of type positive integer, please use a valid positive integer. " ) return False # Re-load the existing data data = {} try: data = json.loads(read_file(config_file)) except: pass # write the config setting data[key] = value # and rew-rite the json file. try: write_file(config_file, json.dumps(data, indent=4)) except: err("Unable to write to config file. ") return False return True
def rename(where, renamings, simulate = False): """Moves modules from source to dest. """ where = os.path.abspath(where) if not os.path.isdir(where): err("Cannot rename:", where, "is not a directory. ") return False if len(renamings) % 2 != 0: err("You must provide renamings in pairs. ") return False if len(renamings) == 0: std("Nothing to rename ...") return True regexes = [] replaces = [] # Compile regexes i = 0 while i< len(renamings): # What we need to find find = renamings[i] find_parts = find.split("-") find_args = r"\{"+(r"\}\{".join(find_parts))+r"\}" find_i = "i"*len(find_parts) # What we need to replace replace = renamings[i+1] replace_parts = replace.split("-") replace_args = "{"+("}{".join(replace_parts))+"}" replace_i = "i"*len(replace_parts) # defi regexes.append(re.compile(r"\\def"+find_i+r"\["+find+r"\]"+find_args)) replaces.append("\\def"+replace_i+"["+replace+"]"+replace_args) # defi (Michael) regexes.append(re.compile(r"(\\def(?:i{1,3}))\["+find+r"\](\{(?:[^\}]*)\})")) replaces.append("\\1["+replace+"]\\2") # trefi regexes.append(re.compile(r"\\tref"+find_i+r"\[([^\]]*)\]"+find_args)) replaces.append("\\\\tref"+replace_i+"[\\1]"+replace_args) # atrefi regexes.append(re.compile(r"\\atref"+find_i+r"\[([^\]]*)\]\{([^\}]*)\}"+find_args)) replaces.append("\\\\atref"+replace_i+"[\\1]{\\2}"+replace_args) # mtrefi regexes.append(re.compile(r"\\mtref"+find_i+r"\[([^\]\?]*)\?"+find+r"\]"+find_args)) replaces.append("\\mtref"+replace_i+"[\\1?"+replace+"]"+replace_args) # go to the next pattern. i = i+2 actions = zip(regexes, replaces) # Find all the files for file in find_files(where, "tex")[0]: # Read a file content = read_file(file) # Run all of the actions for (f, r) in actions: content = f.sub(r, content) write_file(file, content) return True
def rename(where, renamings, simulate=False): """Moves modules from source to dest. """ where = os.path.abspath(where) if not os.path.isdir(where): err("Cannot rename:", where, "is not a directory. ") return False if len(renamings) % 2 != 0: err("You must provide renamings in pairs. ") return False if len(renamings) == 0: std("Nothing to rename ...") return True regexes = [] replaces = [] # Compile regexes i = 0 while i < len(renamings): # What we need to find find = renamings[i] find_parts = find.split("-") find_args = r"\{" + (r"\}\{".join(find_parts)) + r"\}" find_i = "i" * len(find_parts) # What we need to replace replace = renamings[i + 1] replace_parts = replace.split("-") replace_args = "{" + ("}{".join(replace_parts)) + "}" replace_i = "i" * len(replace_parts) # defi regexes.append( re.compile(r"\\def" + find_i + r"\[" + find + r"\]" + find_args)) replaces.append("\\def" + replace_i + "[" + replace + "]" + replace_args) # defi (Michael) regexes.append( re.compile(r"(\\def(?:i{1,3}))\[" + find + r"\](\{(?:[^\}]*)\})")) replaces.append("\\1[" + replace + "]\\2") # trefi regexes.append( re.compile(r"\\tref" + find_i + r"\[([^\]]*)\]" + find_args)) replaces.append("\\\\tref" + replace_i + "[\\1]" + replace_args) # atrefi regexes.append( re.compile(r"\\atref" + find_i + r"\[([^\]]*)\]\{([^\}]*)\}" + find_args)) replaces.append("\\\\atref" + replace_i + "[\\1]{\\2}" + replace_args) # mtrefi regexes.append( re.compile(r"\\mtref" + find_i + r"\[([^\]\?]*)\?" + find + r"\]" + find_args)) replaces.append("\\mtref" + replace_i + "[\\1?" + replace + "]" + replace_args) # go to the next pattern. i = i + 2 actions = zip(regexes, replaces) # Find all the files for file in find_files(where, "tex")[0]: # Read a file content = read_file(file) # Run all of the actions for (f, r) in actions: content = f.sub(r, content) write_file(file, content) return True
def transmod(modname, org_lang, dest_lang, pre_terms={}): """Translate a module from one language to another. """ # Load json from a file if pre_terms is a string if type(pre_terms) == str: try: pre_terms = json.loads(read_file(pre_terms)) except: try: pre_terms = json.loads(pre_terms) except: err("Unable to load json in file %r" % pre_terms) err("Make sure you have given a valid JSON-encoded string or path to a valid .json file. " ) return False # Load the set of pre-translated terms if org_lang in pre_terms: pre_terms = pre_terms[org_lang] if dest_lang in pre_terms: pre_terms = pre_terms[dest_lang] else: pre_terms = {} else: pre_terms = {} # filenames for the original + translated modules orfn = "%s.%s.tex" % (modname, org_lang) newfn = "%s.%s.tex" % (modname, dest_lang) # read the original file try: content = read_file(orfn) except: err("Unable to read original module", orfn) return False # # STEP 1: Replace the third argument to the modnl + viewnl environments # content = re.sub( r"(\\begin\{modnl\}\[[^\]]*\]\{[^\}]*\})\{" + org_lang + r"\}", r"\1{" + dest_lang + "}", content) content = re.sub( r"(\\begin\{viewnl\}\[[^\]]*\]\{[^\}]*\})\{" + org_lang + r"\}", r"\1{" + dest_lang + "}", content) # # STEP 2: Update everything inside the environments # def replacer(match): content = match.group(2) # trefi -> mtrefi content = re.sub(r"\\trefi\[([^\]]*)\]\{([^\}]*)\}", r"\\mtrefi[\1?\2]{\\ttl{\2}}", content) # trefii -> mtrefii content = re.sub(r"\\trefii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}", r"\\mtrefii[\1?\2-\3]{\\ttl{\2 \3}}", content) # trefiii -> mtrefiii content = re.sub( r"\\trefiii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\mtrefiii[\1?\2-\3-\4]{\\ttl{\2 \3 \4}}", content) # defi content = re.sub(r"\\defi\[([^\]]*)\]\{([^\}]*)\}", r"\\defi[\1]{\\ttl{\2}}", content) content = re.sub(r"\\defi\{([^\}]*)\}", r"\\defi[\1]{\\ttl{\1}}", content) # defii content = re.sub(r"\\defii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}", r"\\defii[\1]{\\ttl{\2}}{\\ttl{\3}}", content) content = re.sub(r"\\defii\{([^\}]*)\}\{([^\}]*)\}", r"\\defii[\1-\2]{\\ttl{\1}}{\\ttl{\2}}", content) # defiii content = re.sub( r"\\defiii\[([^\]]*)\]\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\defiii[\1]{\\ttl{\2}}{\\ttl{\3}}{\\ttl{\4}}", content) content = re.sub( r"\\defiii\{([^\}]*)\}\{([^\}]*)\}\{([^\}]*)\}", r"\\defiii[\1-\2-\3]{\\ttl{\1}}{\\ttl{\2}}{\\ttl{\3}}", content) def inner_supper(m): # Inner replacement function # Inserts the \ttl before any trailing whitespace. (sub_inner, n) = re.subn(r"([\n\f\t\v\s]+)$", r"}\1", m.group(1)) if n == 0: sub_inner += "}" return r"\ttl{" + sub_inner + m.group(6) def supper(m): # Outer replacement function. toreplace = m.group(4) if re.match(r"^([\n\f\t\v\s]*)$", toreplace): # we are only whitespaces => do nothing pass else: # we are ntop only whitespaces => replace some sentences. toreplace = re.sub(r"(((\w)+\s+)*((\w)+\s*))([\.\!\?\,\;]?)", inner_supper, toreplace) return m.group(1) + toreplace + m.group(5) # Replace non-wrapped text fragments content = re.sub(r"((\]|\}|\$[^\$]*\$)(\w*))([^\\\{\}\$\]\[]+)(\s*)", supper, content) # and return the content return match.group(1) + content + match.group(4) # Replace text inside the environments of modnl and viewnl content = re.sub(r"(\\begin{modnl})((.|\n)*)(\\end{modnl})", replacer, content) content = re.sub(r"(\\begin{viewnl})((.|\n)*)(\\end{viewnl})", replacer, content) # # STEP 3: Apply the pre-translated directory to \ttl{...} # # Replace all the technical terms def replacer2(match): # prefer full matches if match.groups(1)[0] in pre_terms: return match.groups(1)[0][pre_terms] # Split the terms and look check if we can translate them terms = [] for t in match.groups(1)[0].split(" "): if t in pre_terms: terms.append((pre_terms[t], True)) else: terms.append((t, False)) # Put the results back together result = "" is_open_ttl = False # For each of the terms for (r, s) in terms: if not is_open_ttl: # We do not have an openn ttl if s: result += r + " " else: result += "\\ttl{" + r + " " is_open_ttl = True else: # We do have an open ttl if s: result += result[:-1] + "} " + r + " " is_open_ttl = False else: result += r + " " # Close the last bracket if needed result = result[:-1] if is_open_ttl: result += "}" return result content = re.sub(r"\\ttl\{([^\}]*)\}", replacer2, content) # write back the file try: write_file(newfn, content) except: err("Unable to write new module", newfn) return False # and do some logging std("Prepared translation of", modname, "from") std(orfn) std("to") std(newfn) std("Please finish the translation and then commit the module. ") # we need it for the return code return True
def init_branch(self, branch): """ Creates a new branch for status information. """ # Get name and path. bsplit = branch.split(":") if len(bsplit) == 1: (name, pth) = (bsplit[0], bsplit[0]) else: (name, pth) = (bsplit[0], bsplit[1]) std("Creating branch '"+name+"' at '"+pth+"'. ") # Check if the branch already exists. if name in self.get_all_branches(tuple=False): err("Branch '"+name+"' already exists, can not create it again. Use --install to install. ") return False # Get the paths rpath = match_repo(self.repo, abs=True) dpath = os.path.join(rpath, pth) meta_inf_path = os.path.join(rpath, "META-INF", "MANIFEST.MF") # Find paths for the .gitignore gitignore_path = os.path.join(rpath, ".gitignore") gitignore_entry = os.path.join("/", pth)+"\n" # and either add to it or create it. if os.path.isfile(gitignore_path): write_file(gitignore_path, read_file(gitignore_path)+gitignore_entry) else: write_file(gitignore_path, gitignore_entry) # Update the meta-inf written = False lines = get_metainf_lines(self.repo) # try to append it to a line that already exists. for (i, l) in enumerate(lines): if l.startswith(gbranchstring): lines[i] = lines[i].rstrip("\n") + " " + branch written = True break # or make a new one. if written == False: lines.extend([gbranchstring+" "+ branch]) # and write that file. write_file(meta_inf_path, lines) # Create the orphaned branch. if not make_orphan_branch(rpath, name): return False # push it if not do(rpath, "push", "-u", "origin", name): err("Pushing branch to origin failed. ") return False # Clear the deploy branch cache for this repository. self.clear_branch_cache() # install it. if not self.install_branch(name): return False # change the commit message if not do(dpath, "commit", "--amend", "--allow-empty", "-m", "Create deploy branch. "): return False # and push it. if not do(dpath, "push", "--force", "origin", name): return False std("Generated files branch '"+name+"' created, installed and pushed. ") std("Please commit and push META-INF/MANIFEST.MF and .gitignore to publish installation. ") return True