############################################################################### # # Comments - A class for writing the Excel XLSX Worksheet file. # # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2013-2025, John McNamara, jmcnamara@cpan.org # from . import xmlwriter from .utility import _preserve_whitespace, xl_rowcol_to_cell class Comments(xmlwriter.XMLwriter): """ A class for writing the Excel XLSX Comments file. """ ########################################################################### # # Public API. # ########################################################################### def __init__(self): """ Constructor. """ super().__init__() self.author_ids = {} ########################################################################### # # Private API. # ########################################################################### def _assemble_xml_file(self, comments_data=None): # Assemble and write the XML file. if comments_data is None: comments_data = [] # Write the XML declaration. self._xml_declaration() # Write the comments element. self._write_comments() # Write the authors element. self._write_authors(comments_data) # Write the commentList element. self._write_comment_list(comments_data) self._xml_end_tag("comments") # Close the file. self._xml_close() ########################################################################### # # XML methods. # ########################################################################### def _write_comments(self): # Write the element. xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main" attributes = [("xmlns", xmlns)] self._xml_start_tag("comments", attributes) def _write_authors(self, comment_data): # Write the element. author_count = 0 self._xml_start_tag("authors") for comment in comment_data: author = comment[3] if author is not None and author not in self.author_ids: # Store the author id. self.author_ids[author] = author_count author_count += 1 # Write the author element. self._write_author(author) self._xml_end_tag("authors") def _write_author(self, data): # Write the element. self._xml_data_element("author", data) def _write_comment_list(self, comment_data): # Write the element. self._xml_start_tag("commentList") for comment in comment_data: row = comment[0] col = comment[1] text = comment[2] author = comment[3] font_name = comment[6] font_size = comment[7] font_family = comment[8] # Look up the author id. author_id = None if author is not None: author_id = self.author_ids[author] # Write the comment element. font = (font_name, font_size, font_family) self._write_comment(row, col, text, author_id, font) self._xml_end_tag("commentList") def _write_comment(self, row, col, text, author_id, font): # Write the element. ref = xl_rowcol_to_cell(row, col) attributes = [("ref", ref)] if author_id is not None: attributes.append(("authorId", author_id)) self._xml_start_tag("comment", attributes) # Write the text element. self._write_text(text, font) self._xml_end_tag("comment") def _write_text(self, text, font): # Write the element. self._xml_start_tag("text") # Write the text r element. self._write_text_r(text, font) self._xml_end_tag("text") def _write_text_r(self, text, font): # Write the element. self._xml_start_tag("r") # Write the rPr element. self._write_r_pr(font) # Write the text r element. self._write_text_t(text) self._xml_end_tag("r") def _write_text_t(self, text): # Write the text element. attributes = [] if _preserve_whitespace(text): attributes.append(("xml:space", "preserve")) self._xml_data_element("t", text, attributes) def _write_r_pr(self, font): # Write the element. self._xml_start_tag("rPr") # Write the sz element. self._write_sz(font[1]) # Write the color element. self._write_color() # Write the rFont element. self._write_r_font(font[0]) # Write the family element. self._write_family(font[2]) self._xml_end_tag("rPr") def _write_sz(self, font_size): # Write the element. attributes = [("val", font_size)] self._xml_empty_tag("sz", attributes) def _write_color(self): # Write the element. attributes = [("indexed", 81)] self._xml_empty_tag("color", attributes) def _write_r_font(self, font_name): # Write the element. attributes = [("val", font_name)] self._xml_empty_tag("rFont", attributes) def _write_family(self, font_family): # Write the element. attributes = [("val", font_family)] self._xml_empty_tag("family", attributes)