def _apply_styles(old_properties: BaseProperties, styles: List[BeautifulSoup]): """ applies all styles to old_properties :param old_properties: properties for changing :param styles: styles in order to apply """ # hierarchy of styles: defaults -> paragraph -> numbering -> character for current_style in styles: # apply styles in reverse order if current_style.pPr: change_paragraph_properties(old_properties, current_style.pPr) if current_style.rPr: change_run_properties(old_properties, current_style.rPr)
def _get_numbering_formatting(self) -> Optional[Run]: """ if the paragraph is a list item applies it's properties to the paragraph adds numbering run to the list of paragraph runs :returns: numbering run if there is the text in numbering else None """ if self.xml.numPr and self.numbering_extractor: numbering_run = Run(self, self.styles_extractor) self.numbering_extractor.parse(self.xml.numPr, self, numbering_run) if numbering_run.text: if self.xml.pPr.rPr: change_run_properties(numbering_run, self.xml.pPr.rPr) return numbering_run return None
def parse(self, xml: BeautifulSoup, paragraph_properties: BaseProperties, run_properties: BaseProperties): """ parses numPr content and extracts properties for paragraph for given numId and list level changes old_paragraph properties according to list properties changes run_properties adding text of numeration and it's properties :param xml: BeautifulSoup tree with numPr from document.xml or styles.xml (style content) :param paragraph_properties: Paragraph for changing :param run_properties: Run for changing """ if not xml: return ilvl, num_id = xml.ilvl, xml.numId if not num_id or num_id['w:val'] not in self.num_list: return else: num_id = num_id['w:val'] if not ilvl: try: style_id = xml['w:styleId'] num = self.num_list[num_id] # find link on this styleId in the levels list for level_num, level in num.levels.items(): if 'styleId' in level and level['styleId'] == style_id: ilvl = level_num except KeyError: return else: ilvl = ilvl['w:val'] lvl_info = self.num_list[num_id].get_level_info(ilvl) text = self._get_list_text(ilvl, num_id) if lvl_info['styleId']: self.styles_extractor.parse(lvl_info['styleId'], paragraph_properties, "numbering") if lvl_info['pPr']: change_paragraph_properties(paragraph_properties, lvl_info['pPr']) if lvl_info['rPr']: change_run_properties(run_properties, lvl_info['rPr']) change_run_properties(paragraph_properties, lvl_info['rPr']) run_properties.text = text paragraph_properties.list_level = self.levels_count
def _make_run_list(self): """ makes runs of the paragraph and adds them to the paragraph list """ run_list = self.xml.find_all('w:r') for run_tree in run_list: new_run = Run(self, self.styles_extractor) if run_tree.rStyle: self.styles_extractor.parse(run_tree.rStyle['w:val'], new_run, "character") if self.xml.pPr and self.xml.pPr.rPr: change_run_properties(new_run, self.xml.pPr.rPr) if run_tree.rPr: change_run_properties(new_run, run_tree.rPr) new_run.get_text(run_tree) if not new_run.text: continue if self.runs and self.runs[-1] == new_run: self.runs[-1].text += new_run.text else: self.runs.append(new_run)