@@ -19,6 +19,28 @@ def __init__(self):
1919 self .newline = "\n "
2020 self .default_indent = ' '
2121
22+ def __str__ (self ):
23+ return self .document
24+
25+ def __iadd__ (self , other ):
26+ """Add other to this document"""
27+ if isinstance (other , str ):
28+ self .document += other
29+ return self
30+ elif isinstance (other , RSTDocument ):
31+ self .document += other .document
32+ return self
33+ else :
34+ raise ValueError ("+= for RSTDocument only supported with string and RSTDocument objects" )
35+
36+ def __add__ (self , other ):
37+ """Create a new RSTDocument containing the text of this and the other document"""
38+ new_rst_doc = RSTDocument ()
39+ new_rst_doc .document = self .document + other .document
40+ new_rst_doc .newline = self .newline
41+ new_rst_doc .default_indent = self .default_indent
42+ return new_rst_doc
43+
2244 @staticmethod
2345 def __get_headingline (title , heading_char ):
2446 """Create a heading line for a given title"""
@@ -210,59 +232,14 @@ def add_include(self, filename, indent=None):
210232 self .document += self .newline
211233
212234 def add_figure (self ,
213- img ,
214- caption = None ,
215- legend = None ,
216- alt = None ,
217- height = None ,
218- width = None ,
219- scale = None ,
220- align = None ,
221- target = None ):
222- """
223-
224- :param img: Path to the image to be shown as part of the figure.
225- :param caption: Optional caption for the figure
226- :type caption: String or RSTDocument
227- :param legend: Figure legend
228- :type legend: String or RST Document
229- :param alt: Alternate text. A short description of the image used when the image cannot be displayed.
230- :param height: Height of the figure in pixel
231- :type height: Int
232- :param width: Width of the figure in pixel
233- :type width: Int
234- :param scale: Uniform scaling of the figure in %. Default is 100.
235- :type scale: Int
236- :param align: Alignment of the figure. One of RTDDocument.ALIGN
237- :param target: Hyperlink to be placed on the image.
235+ figure ):
238236 """
239- self .document += self .newline
240- self .document += ".. figure:: %s" % img
241- self .document += self .newline
242- if scale is not None :
243- self .document += (self .indent_text (':scale: %i' % scale ) + ' %' + self .newline )
244- if alt is not None :
245- self .document += (self .indent_text (':alt: %s' % alt ) + self .newline )
246- if height is not None :
247- self .document += (self .indent_text (':height: %i px' % height ) + self .newline )
248- if width is not None :
249- self .document += (self .indent_text (':width: %i px' % width ) + self .newline )
250- if align is not None :
251- if align not in self .ALIGN :
252- raise ValueError ('align not valid. Found %s expected one of %s' % (str (align ), str (self .ALIGN )))
253- self .document += (self .indent_text (':align: %s' % align ) + self .newline )
254- if target is not None :
255- self .document += (self .indent_text (':target: %s' % target ) + self .newline )
256- self .document += self .newline
257- if caption is not None :
258- curr_caption = caption if not isinstance (caption , RSTDocument ) else caption .document
259- self .document += (self .indent_text (curr_caption ) + self .newline )
260- if legend is not None :
261- if caption is None :
262- self .document += (self .indent_text ('.. ' ) + self .newline + self .default_indent + self .newline )
263- curr_legend = legend if not isinstance (legend , RSTDocument ) else legend .document
264- self .document += (self .indent_text (curr_legend ) + self .newline )
265- self .document += self .newline
237+ Add a Figure to the document
238+
239+ :param figure: RSTFigure to add to the document. If set to None then do nothing
240+ """
241+ if figure is not None :
242+ figure .render (rst_doc = self )
266243
267244 def add_sidebar (self , text , title , subtitle = None ):
268245 """
@@ -346,6 +323,16 @@ def add_table(self, rst_table, **kwargs):
346323 """
347324 rst_table .render (self , ** kwargs )
348325
326+ def add_toc (self , rst_toc ):
327+ """
328+ Render an RSTToc in this document
329+
330+ :param rst_toc: RST table of contents object to render
331+ :type rst_toc: RSTToc
332+ :return:
333+ """
334+ rst_toc .render (self )
335+
349336 def write (self , filename , mode = 'w' ):
350337 """
351338 Write the document to file
@@ -438,6 +425,10 @@ def set_cell(self, row, col, text):
438425 def __len__ (self ):
439426 return self .num_rows ()
440427
428+ def __str__ (self ):
429+ """Render figure as string"""
430+ return self .render (rst_doc = None ).document
431+
441432 def num_rows (self ):
442433 """
443434 :return: Number of rows in the table
@@ -564,6 +555,8 @@ def render(self,
564555 :param table_ref: Name of the reference to be used for the table
565556 :param latex_tablecolumns: Latex columns description to be rendered as part of the Sphinx tabularcolumns::
566557 argument. E.g. '|p{3.5cm}|p{1cm}|p{10.5cm}|'
558+
559+ :returns: RSTDocument with the rendered table.
567560 """
568561 if len (self .__table ) == 0 and ignore_empty :
569562 return rst_doc if rst_doc is not None else RSTDocument ()
@@ -604,3 +597,186 @@ def render(self,
604597
605598 # Return the table
606599 return rst_doc
600+
601+
602+ class RSTToc :
603+ """
604+ Helper class for defining a table of contents
605+ """
606+ def __init__ (
607+ self ,
608+ entries : list = None ,
609+ caption : str = None ,
610+ name : str = None ,
611+ maxdepth : int = None ,
612+ titlesonly : bool = False ,
613+ hidden : bool = False ,
614+ numbered : bool = False ,
615+ glob : bool = False ,
616+ includehidden : bool = False ,
617+ reversed : bool = False
618+ ):
619+ self .entries = entries if entries is not None else []
620+ self .caption = caption
621+ self .name = name
622+ self .maxdepth = maxdepth
623+ self .titlesonly = titlesonly
624+ self .hidden = hidden
625+ self .numbered = numbered
626+ self .glob = glob
627+ self .includehidden = includehidden
628+ self .reversed = reversed
629+
630+ def __iadd__ (self , other ):
631+ """
632+ Add and entry to the table of contents
633+ :param other: String for a single entry or list, tuple, or set of strings with multiple entries, or
634+ another RSTToc object with the entries to add
635+ :return:
636+ """
637+ if isinstance (other , str ):
638+ self .entries .append (other )
639+ elif isinstance (other , (list , tuple , set )):
640+ self .entries += list (other )
641+ elif isinstance (other , RSTToc ):
642+ self .entries .append (other .entries )
643+ else :
644+ raise ValueError ("Adding to an RSTDoc with += only supported for str, list, tuple, set, and RSTToc" )
645+ return self
646+
647+ def render (self ,
648+ rst_doc : RSTDocument = None ):
649+ """
650+ Render the toc to an RSTDocument
651+
652+ :param rst_doc: RSTDocument where the table should be rendered in or None if a new document should be created
653+
654+ :return: RSTDocument with the rendered toc
655+ """
656+ rst_doc = rst_doc if rst_doc is not None else RSTDocument ()
657+ rst_doc += rst_doc .newline
658+ rst_doc += ".. toctree::"
659+ rst_doc += rst_doc .newline
660+ if self .caption is not None :
661+ rst_doc += (rst_doc .indent_text (":caption: %s" % self .caption ) + rst_doc .newline )
662+ if self .name is not None :
663+ rst_doc += (rst_doc .indent_text (":name: %s" % self .name ) + rst_doc .newline )
664+ if self .maxdepth is not None :
665+ rst_doc += (rst_doc .indent_text (":maxdepth: %i" % self .maxdepth ) + rst_doc .newline )
666+
667+ # Add all the bool options
668+ bool_options = {
669+ 'titlesonly' : self .titlesonly ,
670+ 'hidden' : self .hidden ,
671+ 'numbered' : self .numbered ,
672+ 'glob' : self .glob ,
673+ 'includehidden' : self .includehidden ,
674+ 'reversed' : self .reversed
675+ }
676+ for option_name , option_value in bool_options .items ():
677+ if option_value :
678+ rst_doc += (rst_doc .indent_text (":%s:" % option_name ) + rst_doc .newline )
679+ rst_doc += rst_doc .newline
680+
681+ # Add all the entries
682+ for entry in self .entries :
683+ rst_doc += (rst_doc .indent_text (entry ) + rst_doc .newline )
684+ rst_doc += rst_doc .newline
685+
686+ # Return the document
687+ return rst_doc
688+
689+
690+ class RSTFigure :
691+ """
692+ Helper class to describe an RST Figure
693+
694+ :ivar image_path: Path to the image to be shown as part of the figure.
695+ :ivar caption: Optional caption for the figure
696+ :ivar legend: Figure legend
697+ :ivar alt: Alternate text. A short description of the image used when the image cannot be displayed.
698+ :ivar height: Integer height of the figure in pixel or string which may include the metric (e.g., 50%)
699+ :ivar width: Integer width of the figure in pixel or string which may include the metric (e.g., 50%)
700+ :ivar scale: Uniform scaling of the figure in %. Default is 100.
701+ :ivar align: Alignment of the figure. One of RTDDocument.ALIGN
702+ :ivar target: Hyperlink to be placed on the image.
703+ """
704+ def __init__ (
705+ self ,
706+ image_path ,
707+ caption = None ,
708+ legend = None ,
709+ alt = None ,
710+ height = None ,
711+ width = None ,
712+ scale = None ,
713+ align = None ,
714+ target = None ):
715+ """
716+
717+ :param image_path: Path to the image to be shown as part of the figure.
718+ :param caption: Optional caption for the figure
719+ :type caption: String or RSTDocument
720+ :param legend: Figure legend
721+ :type legend: String or RST Document
722+ :param alt: Alternate text. A short description of the image used when the image cannot be displayed.
723+ :param height: Integer height of the figure in pixel or string which may include the metric (e.g., 50%)
724+ :param width: Integer width of the figure in pixel or string which may include the metric (e.g., 50%)
725+ :param scale: Uniform scaling of the figure in %. Default is 100.
726+ :param align: Alignment of the figure. One of RTDDocument.ALIGN
727+ :param target: Hyperlink to be placed on the image.
728+ """
729+ self .image_path = image_path
730+ self .caption = caption
731+ self .legend = legend
732+ self .alt = alt
733+ self .height = height
734+ self .width = width
735+ self .scale = scale
736+ self .align = align
737+ self .target = target
738+
739+ def render (self ,
740+ rst_doc : RSTDocument = None ):
741+ """
742+ Render the figure to an RSTDocument
743+
744+ :param rst_doc: RSTDocument where the table should be rendered in or None if a new document should be created
745+
746+ :return: RSTDocument with the rendered figure.
747+ """
748+ rst_doc = rst_doc if rst_doc is not None else RSTDocument ()
749+ rst_doc += rst_doc .newline
750+ rst_doc += ".. figure:: %s" % self .image_path
751+ rst_doc += rst_doc .newline
752+ if self .scale is not None :
753+ rst_doc += (rst_doc .indent_text (':scale: %i' % self .scale ) + ' %' + rst_doc .newline )
754+ if self .alt is not None :
755+ rst_doc += (rst_doc .indent_text (':alt: %s' % self .alt ) + rst_doc .newline )
756+ if self .height is not None :
757+ height_str = self .height if isinstance (self .height , str ) else ("%i px" % self .height )
758+ rst_doc += (rst_doc .indent_text (':height: %s' % height_str ) + rst_doc .newline )
759+ if self .width is not None :
760+ width_str = self .width if isinstance (self .width , str ) else ("%i px" % self .width )
761+ rst_doc += (rst_doc .indent_text (':width: %s' % width_str ) + rst_doc .newline )
762+ if self .align is not None :
763+ if self .align not in self .ALIGN :
764+ raise ValueError ('align not valid. Found %s expected one of %s' % (str (self .align ), str (self .ALIGN )))
765+ rst_doc += (rst_doc .indent_text (':align: %s' % self .align ) + rst_doc .newline )
766+ if self .target is not None :
767+ rst_doc += (rst_doc .indent_text (':target: %s' % self .target ) + rst_doc .newline )
768+ rst_doc += rst_doc .newline
769+ if self .caption is not None :
770+ curr_caption = self .caption if not isinstance (self .caption , RSTDocument ) else self .caption .document
771+ rst_doc += (rst_doc .indent_text (curr_caption ) + rst_doc .newline )
772+ if self .legend is not None :
773+ if self .caption is None :
774+ rst_doc += (rst_doc .indent_text ('.. ' ) + rst_doc .newline + self .default_indent + rst_doc .newline )
775+ curr_legend = self .legend if not isinstance (self .legend , RSTDocument ) else self .legend .document
776+ rst_doc += (rst_doc .indent_text (curr_legend ) + rst_doc .newline )
777+ rst_doc += rst_doc .newline
778+ return rst_doc
779+
780+ def __str__ (self ):
781+ """Render figure as string"""
782+ return self .render (rst_doc = None ).document
0 commit comments