def substitute(source, newcommands): """ Expand all newcommands in the list 'newcommands' of (pattern, replacement) pairs. source can be a filename or just a string with text. If source is a filename, a backup file with extension .old~ is first made and then the original file is overwritten by the new text with expanded commands. """ if os.path.isfile(source): shutil.copy(source, source + '.old~') f = open(source, 'r') text = f.read() f.close() else: text = source from doconce import debugpr for pattern, replacement in newcommands: text, n = re.subn(pattern, replacement, text) if n: debugpr('newcommand replacement: %s -> %s (%d times)' % (pattern, replacement, n)) # newcommands can be nested, let's repeat depth = 2 for i in range(depth): for pattern, replacement in newcommands: m = re.search(pattern, text) text, n = re.subn(pattern, replacement, text) if n: debugpr('newcommand replacement: %s -> %s (%d times)' % (pattern, replacement, n)) if os.path.isfile(source): f = open(source, 'w') f.write(text) f.close() else: return text
def ref_and_label_commoncode(section_label2title, format, filestr): filestr = fix_ref_section_chapter(filestr, format) # Deal with the problem of identical titles, which makes problem # with non-unique links in reST: add a counter to the title debugtext = '' section_pattern = r'^\s*(={3,9})(.+?)(={3,9})(\s*label\{(.+?)\})?' all_sections = re.findall(section_pattern, filestr, flags=re.MULTILINE) # First count the no of titles with the same wording titles = {} max_heading = 1 # track the top heading level for correct TITLE typesetting for heading, title, dummy2, dummy3, label in all_sections: entry = None if label == '' else label if title in titles: titles[title].append(entry) else: titles[title] = [entry] max_heading = max(max_heading, len(heading)) # Typeset TITLE so that it gets the highest+1 (but no higher) section sevel max_heading += 2 # one level up (2 =) max_heading = min(max_heading, 9) pattern = r'^TITLE:\s*(.+)$' if format == 'sphinx': # Title cannot be more than 63 chars... m = re.search(pattern, filestr, flags=re.MULTILINE) if m: title = m.group(1).strip() if len(title) > 63: errwarn('*** error: sphinx title cannot be longer than 63 characters') errwarn(' current title: "%s" (%d characters)' % (title, len(title))) _abort() filestr = re.sub(pattern, '.. Document title:\n\n%s \g<1> %s\n' % ('='*max_heading, '='*max_heading), filestr, flags=re.MULTILINE) # Make new titles title_counter = {} # count repeated titles (need to append counter to make unique links) sections = [] for heading, title, dummy2, dummy3, label in all_sections: label = None if label == '' else label if len(titles[title]) > 1: if title in title_counter: title_counter[title] += 1 else: title_counter[title] = 1 # Add much whitespace so we can recognize the titles after # formats are compiled and remove the number new_title = title + ' (%d) ' % title_counter[title] sections.append((heading, new_title, label, title)) if label in section_label2title: section_label2title[label] = new_title else: sections.append((heading, title, label, title)) # Make replacements for heading, title, label, old_title in sections: if title != old_title: debugtext += '\nchanged title: %s -> %s\n' % (old_title, title) # Avoid trouble with \t, \n in replacement title = title.replace('\\', '\\\\') # The substitution depends on whether we have a label or not if label is not None: title_pattern = r'%s\s*%s\s*%s\s*label\{%s\}' % (heading, re.escape(old_title), heading, label) # title may contain ? () etc., that's why we take re.escape replacement = '.. _%s:\n\n' % label + r'%s %s %s' % \ (heading, title, heading) else: title_pattern = r'%s\s*%s\s*%s' % (heading, re.escape(old_title), heading) replacement = r'%s %s %s' % (heading, title, heading) filestr, n = re.subn(title_pattern, replacement, filestr, count=1) if n > 1: raise ValueError('Replaced more than one title. BUG!') # remove label{...} from output #filestr = re.sub(r'^label\{.+?\}\s*$', '', filestr, flags=re.MULTILINE) cpattern = re.compile(r'^label\{[^}]+?\}\s*$', flags=re.MULTILINE) filestr = cpattern.sub('', filestr) filestr = re.sub(r'label\{[^}]+?\}', '', filestr) # all the remaining import doconce doconce.debugpr(debugtext) return filestr
def ref_and_label_commoncode(section_label2title, format, filestr): # .... see section ref{my:sec} is replaced by # see the section "...section heading..." pattern = r'[Ss]ection(s?)\s+ref\{' replacement = r'the section\g<1> ref{' filestr = re.sub(pattern, replacement, filestr) pattern = r'[Cc]hapter(s?)\s+ref\{' replacement = r'the chapter\g<1> ref{' filestr = re.sub(pattern, replacement, filestr) # Need special adjustment to handle start of sentence (capital) or not. pattern = r'([.?!])\s+the (sections?|captions?)\s+ref' replacement = r'\g<1> The \g<2> ref' filestr = re.sub(pattern, replacement, filestr) # Remove Exercise, Project, Problem in references since those words # are used in the title of the section too pattern = r'(the\s*)?([Ee]xercises?|[Pp]rojects?|[Pp]roblems?)\s+ref\{' replacement = r'ref{' filestr = re.sub(pattern, replacement, filestr) # Deal with the problem of identical titles, which makes problem # with non-unique links in reST: add a counter to the title debugtext = '' section_pattern = r'^\s*(_{3,9}|={3,9})(.+?)(_{3,9}|={3,9})(\s*label\{(.+?)\})?' all_sections = re.findall(section_pattern, filestr, flags=re.MULTILINE) # First count the no of titles with the same wording titles = {} max_heading = 3 # track the top heading level for correct TITLE typesetting for heading, title, dummy2, dummy3, label in all_sections: entry = None if label == '' else label if title in titles: titles[title].append(entry) else: titles[title] = [entry] max_heading = max(max_heading, len(heading)) # Typeset TITLE so that it gets the highest (but no higher) section sevel filestr = re.sub(r'^TITLE:\s*(.+)$', '%s \g<1> %s\n' % ('='*max_heading, '='*max_heading), filestr, flags=re.MULTILINE) # Make new titles title_counter = {} # count repeated titles sections = [] for heading, title, dummy2, dummy3, label in all_sections: label = None if label == '' else label if len(titles[title]) > 1: if title in title_counter: title_counter[title] += 1 else: title_counter[title] = 1 new_title = title + ' (%d) ' % title_counter[title] sections.append((heading, new_title, label, title)) if label in section_label2title: section_label2title[label] = new_title else: sections.append((heading, title, label, title)) # Make replacements for heading, title, label, old_title in sections: if title != old_title: debugtext += '\nchanged title: %s -> %s\n' % (old_title, title) # Avoid trouble with \t, \n in replacement title = title.replace('\\', '\\\\') # The substitution depends on whether we have a label or not if label is not None: title_pattern = r'%s\s*%s\s*%s\s*label\{%s\}' % (heading, re.escape(old_title), heading, label) # title may contain ? () etc., that's why we take re.escape replacement = '.. _%s:\n\n' % label + r'%s %s %s' % \ (heading, title, heading) else: title_pattern = r'%s\s*%s\s*%s' % (heading, re.escape(old_title), heading) replacement = r'%s %s %s' % (heading, title, heading) filestr, n = re.subn(title_pattern, replacement, filestr, count=1) if n > 1: raise ValueError('Replaced more than one title. BUG!') # remove label{...} from output #filestr = re.sub(r'^label\{.+?\}\s*$', '', filestr, flags=re.MULTILINE) cpattern = re.compile(r'^label\{[^}]+?\}\s*$', flags=re.MULTILINE) filestr = cpattern.sub('', filestr) filestr = re.sub(r'label\{[^}]+?\}', '', filestr) # all the remaining import doconce doconce.debugpr(debugtext) return filestr
def ref_and_label_commoncode(section_label2title, format, filestr): # .... see section ref{my:sec} is replaced by # see the section "...section heading..." pattern = r"[Ss]ection(s?)\s+ref\{" replacement = r"the section\g<1> ref{" filestr = re.sub(pattern, replacement, filestr) pattern = r"[Cc]hapter(s?)\s+ref\{" replacement = r"the chapter\g<1> ref{" filestr = re.sub(pattern, replacement, filestr) # Need special adjustment to handle start of sentence (capital) or not. pattern = r"([.?!]\s+|\n\n|[%=~-]\n+)the (sections?|chapters?)\s+ref" replacement = r"\g<1>The \g<2> ref" filestr = re.sub(pattern, replacement, filestr) # Remove Exercise, Project, Problem in references since those words # are used in the title of the section too pattern = r"(the\s*)?([Ee]xercises?|[Pp]rojects?|[Pp]roblems?)\s+ref\{" replacement = r"ref{" filestr = re.sub(pattern, replacement, filestr) # Deal with the problem of identical titles, which makes problem # with non-unique links in reST: add a counter to the title debugtext = "" section_pattern = r"^\s*(={3,9})(.+?)(={3,9})(\s*label\{(.+?)\})?" all_sections = re.findall(section_pattern, filestr, flags=re.MULTILINE) # First count the no of titles with the same wording titles = {} max_heading = 1 # track the top heading level for correct TITLE typesetting for heading, title, dummy2, dummy3, label in all_sections: entry = None if label == "" else label if title in titles: titles[title].append(entry) else: titles[title] = [entry] max_heading = max(max_heading, len(heading)) # Typeset TITLE so that it gets the highest+1 (but no higher) section sevel max_heading += 2 # one level up (2 =) max_heading = min(max_heading, 9) pattern = r"^TITLE:\s*(.+)$" if format == "sphinx": # Title cannot be more than 63 chars... m = re.search(pattern, filestr, flags=re.MULTILINE) if m: title = m.group(1).strip() if len(title) > 63: print "*** error: sphinx title cannot be longer than 63 characters" print ' current title: "%s" (%d characters)' % (title, len(title)) _abort() filestr = re.sub( pattern, ".. Document title:\n\n%s \g<1> %s\n" % ("=" * max_heading, "=" * max_heading), filestr, flags=re.MULTILINE, ) # Make new titles title_counter = {} # count repeated titles sections = [] for heading, title, dummy2, dummy3, label in all_sections: label = None if label == "" else label if len(titles[title]) > 1: if title in title_counter: title_counter[title] += 1 else: title_counter[title] = 1 new_title = title + " (%d) " % title_counter[title] sections.append((heading, new_title, label, title)) if label in section_label2title: section_label2title[label] = new_title else: sections.append((heading, title, label, title)) # Make replacements for heading, title, label, old_title in sections: if title != old_title: debugtext += "\nchanged title: %s -> %s\n" % (old_title, title) # Avoid trouble with \t, \n in replacement title = title.replace("\\", "\\\\") # The substitution depends on whether we have a label or not if label is not None: title_pattern = r"%s\s*%s\s*%s\s*label\{%s\}" % (heading, re.escape(old_title), heading, label) # title may contain ? () etc., that's why we take re.escape replacement = ".. _%s:\n\n" % label + r"%s %s %s" % (heading, title, heading) else: title_pattern = r"%s\s*%s\s*%s" % (heading, re.escape(old_title), heading) replacement = r"%s %s %s" % (heading, title, heading) filestr, n = re.subn(title_pattern, replacement, filestr, count=1) if n > 1: raise ValueError("Replaced more than one title. BUG!") # remove label{...} from output # filestr = re.sub(r'^label\{.+?\}\s*$', '', filestr, flags=re.MULTILINE) cpattern = re.compile(r"^label\{[^}]+?\}\s*$", flags=re.MULTILINE) filestr = cpattern.sub("", filestr) filestr = re.sub(r"label\{[^}]+?\}", "", filestr) # all the remaining import doconce doconce.debugpr(debugtext) return filestr
def ref_and_label_commoncode(section_label2title, format, filestr): # .... see section ref{my:sec} is replaced by # see the section "...section heading..." pattern = r'[Ss]ection(s?)\s+ref\{' replacement = r'the section\g<1> ref{' filestr = re.sub(pattern, replacement, filestr) pattern = r'[Cc]hapter(s?)\s+ref\{' replacement = r'the chapter\g<1> ref{' filestr = re.sub(pattern, replacement, filestr) # Need special adjustment to handle start of sentence (capital) or not. pattern = r'([.?!]\s+|\n\n|[%=~-]\n+)the (sections?|chapters?)\s+ref' replacement = r'\g<1>The \g<2> ref' filestr = re.sub(pattern, replacement, filestr) # Remove Exercise, Project, Problem in references since those words # are used in the title of the section too pattern = r'(the\s*)?([Ee]xercises?|[Pp]rojects?|[Pp]roblems?)\s+ref\{' replacement = r'ref{' filestr = re.sub(pattern, replacement, filestr) # Deal with the problem of identical titles, which makes problem # with non-unique links in reST: add a counter to the title debugtext = '' section_pattern = r'^\s*(={3,9})(.+?)(={3,9})(\s*label\{(.+?)\})?' all_sections = re.findall(section_pattern, filestr, flags=re.MULTILINE) # First count the no of titles with the same wording titles = {} max_heading = 1 # track the top heading level for correct TITLE typesetting for heading, title, dummy2, dummy3, label in all_sections: entry = None if label == '' else label if title in titles: titles[title].append(entry) else: titles[title] = [entry] max_heading = max(max_heading, len(heading)) # Typeset TITLE so that it gets the highest+1 (but no higher) section sevel max_heading += 2 # one level up (2 =) max_heading = min(max_heading, 9) pattern = r'^TITLE:\s*(.+)$' if format == 'sphinx': # Title cannot be more than 63 chars... m = re.search(pattern, filestr, flags=re.MULTILINE) if m: title = m.group(1).strip() if len(title) > 63: print '*** error: sphinx title cannot be longer than 63 characters' print ' current title: "%s" (%d characters)' % (title, len(title)) _abort() filestr = re.sub(pattern, '.. Document title:\n\n%s \g<1> %s\n' % ('=' * max_heading, '=' * max_heading), filestr, flags=re.MULTILINE) # Make new titles title_counter = {} # count repeated titles sections = [] for heading, title, dummy2, dummy3, label in all_sections: label = None if label == '' else label if len(titles[title]) > 1: if title in title_counter: title_counter[title] += 1 else: title_counter[title] = 1 new_title = title + ' (%d) ' % title_counter[title] sections.append((heading, new_title, label, title)) if label in section_label2title: section_label2title[label] = new_title else: sections.append((heading, title, label, title)) # Make replacements for heading, title, label, old_title in sections: if title != old_title: debugtext += '\nchanged title: %s -> %s\n' % (old_title, title) # Avoid trouble with \t, \n in replacement title = title.replace('\\', '\\\\') # The substitution depends on whether we have a label or not if label is not None: title_pattern = r'%s\s*%s\s*%s\s*label\{%s\}' % ( heading, re.escape(old_title), heading, label) # title may contain ? () etc., that's why we take re.escape replacement = '.. _%s:\n\n' % label + r'%s %s %s' % \ (heading, title, heading) else: title_pattern = r'%s\s*%s\s*%s' % (heading, re.escape(old_title), heading) replacement = r'%s %s %s' % (heading, title, heading) filestr, n = re.subn(title_pattern, replacement, filestr, count=1) if n > 1: raise ValueError('Replaced more than one title. BUG!') # remove label{...} from output #filestr = re.sub(r'^label\{.+?\}\s*$', '', filestr, flags=re.MULTILINE) cpattern = re.compile(r'^label\{[^}]+?\}\s*$', flags=re.MULTILINE) filestr = cpattern.sub('', filestr) filestr = re.sub(r'label\{[^}]+?\}', '', filestr) # all the remaining import doconce doconce.debugpr(debugtext) return filestr