diff --git a/src/ReportBase/_Endnotes.py b/src/ReportBase/_Endnotes.py index 07d6ce75e..fa8084c09 100644 --- a/src/ReportBase/_Endnotes.py +++ b/src/ReportBase/_Endnotes.py @@ -24,6 +24,7 @@ Provide utilities for printing endnotes in text reports. """ from gen.plug.docgen import FontStyle, ParagraphStyle, FONT_SANS_SERIF +from gen.lib import NoteType from gen.ggettext import gettext as _ def add_endnote_styles(style_sheet): @@ -147,7 +148,9 @@ def write_endnotes(bibliography, database, doc, printnotes=False): 'type': str(note.get_type())}) doc.end_paragraph() doc.write_styled_note(note.get_styledtext(), - note.get_format(),'Endnotes-Notes') + note.get_format(),'Endnotes-Notes', + contains_html= note.get_type() \ + == NoteType.HTML_CODE) ind += 1 def _format_source_text(source): diff --git a/src/gen/lib/notetype.py b/src/gen/lib/notetype.py index 6e9974e43..859089b38 100644 --- a/src/gen/lib/notetype.py +++ b/src/gen/lib/notetype.py @@ -67,6 +67,8 @@ class NoteType(GrampsType): SOURCE_TEXT = 21 # this is used for verbatim source text in SourceRef CITATION = 22 REPORT_TEXT = 23 # this is used for notes used for reports + # indicate a note is html code + HTML_CODE = 24 _CUSTOM = CUSTOM _DEFAULT = GENERAL @@ -81,6 +83,7 @@ class NoteType(GrampsType): (SOURCE_TEXT, _("Source text"), "Source text"), (CITATION, _('Citation'), "Citation"), (REPORT_TEXT, _("Report"), "Report"), + (HTML_CODE, _("Html code"), "Html code"), ] _DATAMAPIGNORE = [ diff --git a/src/gen/plug/docgen/textdoc.py b/src/gen/plug/docgen/textdoc.py index 38c51a834..81f120175 100644 --- a/src/gen/plug/docgen/textdoc.py +++ b/src/gen/plug/docgen/textdoc.py @@ -203,12 +203,17 @@ class TextDoc(object): """ raise NotImplementedError - def write_styled_note(self, styledtext, format, style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): """ Convenience function to write a styledtext to the cairo doc. styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. overwrite this method if the backend supports styled notes """ diff --git a/src/plugins/docgen/AsciiDoc.py b/src/plugins/docgen/AsciiDoc.py index 847befc9d..518cea7ca 100644 --- a/src/plugins/docgen/AsciiDoc.py +++ b/src/plugins/docgen/AsciiDoc.py @@ -362,7 +362,18 @@ class AsciiDoc(BaseDoc,TextDoc): else: self.f.write(this_text) - def write_styled_note(self,styledtext,format,style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): + """ + Convenience function to write a styledtext to the ASCII doc. + styledtext : assumed a StyledText object to write + format : = 0 : Flowed, = 1 : Preformatted + style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. AsciiDoc prints the html without handling it + """ text = str(styledtext) if format: #Preformatted note, keep all white spaces, tabs, LF's diff --git a/src/plugins/docgen/HtmlDoc.py b/src/plugins/docgen/HtmlDoc.py index 63e90ca23..d5eabebb5 100644 --- a/src/plugins/docgen/HtmlDoc.py +++ b/src/plugins/docgen/HtmlDoc.py @@ -467,12 +467,18 @@ class HtmlDoc(BaseDoc, TextDoc): #end div element self.__reduce_list() - def write_styled_note(self, styledtext, format, style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): """ Convenience function to write a styledtext to the html doc. styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. HtmlDoc will show the html as pure text, so + no escaping will happen. """ text = str(styledtext) @@ -481,7 +487,13 @@ class HtmlDoc(BaseDoc, TextDoc): markuptext = self._backend.add_markup_from_styled(text, s_tags, split='\n\n') self.htmllist += [Html('div', id='grampsstylednote')] - if format == 1: + if contains_html: + #just dump the note out as it is. Adding markup would be dangerous + # as it could destroy the html. If html code, one can do the + self.start_paragraph(style_name) + self.__write_text(text, markup=True) + self.end_paragraph() + elif format == 1: #preformatted, retain whitespace. #so use \n\n for paragraph detection #FIXME: following split should be regex to match \n\s*\n instead? diff --git a/src/plugins/docgen/LaTeXDoc.py b/src/plugins/docgen/LaTeXDoc.py index 91b01a7a5..862190547 100644 --- a/src/plugins/docgen/LaTeXDoc.py +++ b/src/plugins/docgen/LaTeXDoc.py @@ -603,13 +603,20 @@ class LaTeXDoc(BaseDoc, TextDoc): text = text.replace('\\_'*13, '\\underline{\hspace{3cm}}') self._backend.write(text) - def write_styled_note(self, styledtext, format, style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): """ Convenience function to write a styledtext to the latex doc. styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. LatexDoc ignores notes that contain html """ + if contains_html: + return text = str(styledtext) s_tags = styledtext.get_tags() diff --git a/src/plugins/docgen/ODFDoc.py b/src/plugins/docgen/ODFDoc.py index fa6ea88a5..21c05490f 100644 --- a/src/plugins/docgen/ODFDoc.py +++ b/src/plugins/docgen/ODFDoc.py @@ -1202,12 +1202,17 @@ class ODFDoc(BaseDoc, TextDoc, DrawDoc): self.cntnt.write('') self.end_paragraph() - def write_styled_note(self, styledtext, format, style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): """ Convenience function to write a styledtext to the latex doc. styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. RTFDoc prints the html without handling it """ text = str(styledtext) s_tags = styledtext.get_tags() diff --git a/src/plugins/docgen/RTFDoc.py b/src/plugins/docgen/RTFDoc.py index 8110927f2..ed67f11fd 100644 --- a/src/plugins/docgen/RTFDoc.py +++ b/src/plugins/docgen/RTFDoc.py @@ -396,7 +396,18 @@ class RTFDoc(BaseDoc,TextDoc): index = index+1 self.f.write('}}\\par\n') - def write_styled_note(self,styledtext,format,style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): + """ + Convenience function to write a styledtext to the latex doc. + styledtext : assumed a StyledText object to write + format : = 0 : Flowed, = 1 : Preformatted + style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. RTFDoc prints the html without handling it + """ text = str(styledtext) if format: # Preformatted note diff --git a/src/plugins/lib/libcairodoc.py b/src/plugins/lib/libcairodoc.py index bbd705fed..28dda69f5 100644 --- a/src/plugins/lib/libcairodoc.py +++ b/src/plugins/lib/libcairodoc.py @@ -1286,12 +1286,17 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc): self.write_text(line) self.end_paragraph() - def write_styled_note(self, styledtext, format, style_name): + def write_styled_note(self, styledtext, format, style_name, + contains_html=False): """ Convenience function to write a styledtext to the cairo doc. styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted - style_name : name of the style to use for default presentation + style_name : name of the style to use for default presentation + contains_html: bool, the backend should not check if html is present. + If contains_html=True, then the textdoc is free to handle that in + some way. Eg, a textdoc could remove all tags, or could make sure + a link is clickable. CairoDoc does nothing different for html notes """ text = str(styledtext) @@ -1352,7 +1357,7 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc): text """ markuptext = self._backend.add_markup_from_styled(text, s_tags) - self.__write_text(text, markup=True) + self.__write_text(markuptext, markup=True) def add_media_object(self, name, pos, x_cm, y_cm, alt=''): new_image = GtkDocPicture(pos, name, x_cm, y_cm) diff --git a/src/plugins/textreport/DetAncestralReport.py b/src/plugins/textreport/DetAncestralReport.py index 6ee5a6cb5..90a17d947 100644 --- a/src/plugins/textreport/DetAncestralReport.py +++ b/src/plugins/textreport/DetAncestralReport.py @@ -40,7 +40,7 @@ from gen.ggettext import gettext as _ #------------------------------------------------------------------------ from gen.display.name import displayer as _nd from Errors import ReportError -from gen.lib import EventType, FamilyRelType, Person +from gen.lib import EventType, FamilyRelType, Person, NoteType from gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle, FONT_SANS_SERIF, FONT_SERIF, INDEX_TYPE_TOC, PARA_ALIGN_CENTER) @@ -281,7 +281,9 @@ class DetAncestorReport(Report): for notehandle in notelist: note = self.database.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(),"DAR-Entry") + note.get_format(), "DAR-Entry", + contains_html= note.get_type() \ + == NoteType.HTML_CODE) first = True if self.inc_names: @@ -417,7 +419,9 @@ class DetAncestorReport(Report): for notehandle in notelist: note = self.database.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(),"DAR-MoreDetails") + note.get_format(),"DAR-MoreDetails", + contains_html= note.get_type() \ + == NoteType.HTML_CODE) def write_parents(self, person): family_handle = person.get_main_parents_family_handle() diff --git a/src/plugins/textreport/DetDescendantReport.py b/src/plugins/textreport/DetDescendantReport.py index e97f46713..15bb98a60 100644 --- a/src/plugins/textreport/DetDescendantReport.py +++ b/src/plugins/textreport/DetDescendantReport.py @@ -41,7 +41,7 @@ from gen.ggettext import gettext as _ #------------------------------------------------------------------------ from gen.display.name import displayer as _nd from Errors import ReportError -from gen.lib import FamilyRelType, Person +from gen.lib import FamilyRelType, Person, NoteType from gen.plug.menu import (BooleanOption, NumberOption, PersonOption, EnumeratedListOption) from gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle, @@ -412,7 +412,8 @@ class DetDescendantReport(Report): for notehandle in notelist: note = self.database.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(),"DDR-MoreDetails") + note.get_format(),"DDR-MoreDetails", + contains_html= note.get_type() == NoteType.HTML_CODE) def __write_parents(self, person): family_handle = person.get_main_parents_family_handle() @@ -637,7 +638,8 @@ class DetDescendantReport(Report): for notehandle in notelist: note = self.database.get_note_from_handle(notehandle) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(),"DDR-Entry") + note.get_format(),"DDR-Entry", + contains_html= note.get_type() == NoteType.HTML_CODE) first = True if self.inc_names: diff --git a/src/plugins/textreport/FamilyGroup.py b/src/plugins/textreport/FamilyGroup.py index 45d3f3111..bae296c4d 100644 --- a/src/plugins/textreport/FamilyGroup.py +++ b/src/plugins/textreport/FamilyGroup.py @@ -236,7 +236,9 @@ class FamilyGroup(Report): self.doc.end_cell() self.doc.start_cell("FGR-TextContentsEnd", 2) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(), 'FGR-Note') + note.get_format(), 'FGR-Note', + contains_html= note.get_type() == \ + gen.lib.NoteType.HTML_CODE) self.doc.end_cell() self.doc.end_row() diff --git a/src/plugins/textreport/IndivComplete.py b/src/plugins/textreport/IndivComplete.py index 3ecc4825a..fb64a5503 100644 --- a/src/plugins/textreport/IndivComplete.py +++ b/src/plugins/textreport/IndivComplete.py @@ -37,7 +37,7 @@ from collections import defaultdict # GRAMPS modules # #------------------------------------------------------------------------ -from gen.lib import EventRoleType, EventType, Person +from gen.lib import EventRoleType, EventType, Person, NoteType from gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle, TableStyle, TableCellStyle, FONT_SANS_SERIF, INDEX_TYPE_TOC, PARA_ALIGN_CENTER) @@ -216,7 +216,8 @@ class IndivCompleteReport(Report): note = self.database.get_note_from_handle(notehandle) text = note.get_styledtext() note_format = note.get_format() - self.doc.write_styled_note(text, note_format, 'IDS-Normal') + self.doc.write_styled_note(text, note_format, 'IDS-Normal', + contains_html= note.get_type() == NoteType.HTML_CODE) self.doc.end_cell() self.doc.end_row() @@ -253,7 +254,8 @@ class IndivCompleteReport(Report): note_format = note.get_format() self.doc.start_row() self.doc.start_cell('IDS-NormalCell', 2) - self.doc.write_styled_note(text, note_format, 'IDS-Normal') + self.doc.write_styled_note(text, note_format, 'IDS-Normal', + contains_html= note.get_type() == NoteType.HTML_CODE) self.doc.end_cell() self.doc.end_row() diff --git a/src/plugins/textreport/MarkerReport.py b/src/plugins/textreport/MarkerReport.py index 209187504..08ec22c6e 100644 --- a/src/plugins/textreport/MarkerReport.py +++ b/src/plugins/textreport/MarkerReport.py @@ -40,7 +40,7 @@ from ReportBase import Report, ReportUtils, MenuReportOptions from gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle, TableStyle, TableCellStyle, FONT_SANS_SERIF, INDEX_TYPE_TOC, PARA_ALIGN_CENTER) -from gen.lib import MarkerType +from gen.lib import MarkerType, NoteType from Filters import GenericFilterFactory, Rules from gen.display.name import displayer as name_displayer import DateHandler @@ -412,7 +412,9 @@ class MarkerReport(Report): self.doc.start_cell('MR-TableCell', 2) self.doc.write_styled_note(note.get_styledtext(), - note.get_format(), 'MR-Note') + note.get_format(), 'MR-Note', + contains_html= note.get_type() \ + == NoteType.HTML_CODE) self.doc.end_cell() self.doc.end_row() diff --git a/src/plugins/webreport/NarrativeWeb.py b/src/plugins/webreport/NarrativeWeb.py index dd116332e..690fa8e21 100644 --- a/src/plugins/webreport/NarrativeWeb.py +++ b/src/plugins/webreport/NarrativeWeb.py @@ -69,7 +69,7 @@ log = logging.getLogger(".WebPage") from gen.ggettext import sgettext as _ import gen.lib from gen.lib import UrlType, EventType, Person, date, Date, ChildRefType, \ - FamilyRelType, NameType, Name + FamilyRelType, NameType, Name, NoteType import const import Sort from gen.plug.menu import PersonOption, NumberOption, StringOption, \ @@ -364,7 +364,8 @@ class BasePage(object): # styled notes htmlnotetext = self.styled_note(note.get_styledtext(), - note.get_format()) + note.get_format(), contains_html = + note.get_type() == NoteType.HTML_CODE) text = htmlnotetext or Html("p", note_text) # return text of the note to its callers @@ -377,9 +378,9 @@ class BasePage(object): # ################################################# - def styled_note(self, styledtext, format): + def styled_note(self, styledtext, format, contains_html=False): """ - styledtext : assumed a StyledText object to write + styledtext : assumed a StyledText object to write format : = 0 : Flowed, = 1 : Preformatted style_name : name of the style to use for default presentation """ @@ -393,7 +394,9 @@ class BasePage(object): markuptext = self._backend.add_markup_from_styled(text, s_tags, split='\n\n') htmllist = Html("div", id = "grampsstylednote") - if format == 1: + if contains_html: + htmllist.extend((Html('p') + text)) + elif format == 1: #preformatted, retain whitespace. #so use \n\n for paragraph detection htmllist += Html("pre", indent=None) + markuptext.split('\n\n') @@ -1466,7 +1469,8 @@ class BasePage(object): # Web Site address elif _type == UrlType.WEB_HOME: - if not uri.startswith("http://"): + if not (uri.startswith("http://") or + uri.startswith("https://")): uri = "http://%(website)s" % { "website" : uri } # FTP server address