pydocmaker 2.2.7__tar.gz → 2.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {pydocmaker-2.2.7/src/pydocmaker.egg-info → pydocmaker-2.2.8}/PKG-INFO +1 -1
  2. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/__init__.py +1 -1
  3. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/baseformatter.py +43 -2
  4. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_docx.py +3 -1
  5. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_html.py +32 -0
  6. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_ipynb.py +4 -0
  7. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_markdown.py +32 -4
  8. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_redmine.py +35 -33
  9. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/ex_tex.py +57 -0
  10. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/core.py +56 -0
  11. {pydocmaker-2.2.7 → pydocmaker-2.2.8/src/pydocmaker.egg-info}/PKG-INFO +1 -1
  12. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/tests/test_ex_html.py +14 -0
  13. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/LICENSE +0 -0
  14. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/README.md +0 -0
  15. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/setup.cfg +0 -0
  16. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/setup.py +0 -0
  17. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/__init__.py +0 -0
  18. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/mdx_latex.py +0 -0
  19. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/pandoc_api.py +0 -0
  20. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/backend/pdf_maker.py +0 -0
  21. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/templating.py +0 -0
  22. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker/util.py +0 -0
  23. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker.egg-info/SOURCES.txt +0 -0
  24. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker.egg-info/dependency_links.txt +0 -0
  25. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker.egg-info/requires.txt +0 -0
  26. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/src/pydocmaker.egg-info/top_level.txt +0 -0
  27. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/tests/test_backend_pandoc.py +0 -0
  28. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/tests/test_convert_all.py +0 -0
  29. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/tests/test_core.py +0 -0
  30. {pydocmaker-2.2.7 → pydocmaker-2.2.8}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pydocmaker
3
- Version: 2.2.7
3
+ Version: 2.2.8
4
4
  Summary: a minimal document maker to make docx, markdown, html, textile, redmine, and tex documents from python. Written in pure python.
5
5
  Home-page: https://github.com/TobiasGlaubach/pydocmaker
6
6
  Author: Tobias Glaubach
@@ -1,4 +1,4 @@
1
- __version__ = '2.2.7'
1
+ __version__ = '2.2.8'
2
2
 
3
3
  from pydocmaker.core import DocBuilder, construct, constr, buildingblocks, print_to_pdf, get_latex_compiler, set_latex_compiler, make_pdf_from_tex, show_pdf
4
4
  from pydocmaker.util import upload_report_to_redmine, bcolors, txtcolor, colors_dc
@@ -31,7 +31,7 @@ class BaseFormatter(abc.ABC):
31
31
  default_linebreak = '\n\n'
32
32
 
33
33
  def digest_iterator(self, **kwargs):
34
- content = kwargs.get('content', kwargs.get('children'))
34
+ content = kwargs.get('children', kwargs.get('content'))
35
35
  return f''.join([self.digest(c) for c in content])
36
36
 
37
37
  def digest_str(self, el):
@@ -46,6 +46,10 @@ class BaseFormatter(abc.ABC):
46
46
  def digest_meta(self, **kwargs):
47
47
  return '' # meta element will not influence the rendering and is just ignored
48
48
 
49
+ @abc.abstractmethod
50
+ def digest_table(self, children=None, **kwargs) -> str:
51
+ pass
52
+
49
53
  @abc.abstractmethod
50
54
  def digest_markdown(self, children='', **kwargs) -> str:
51
55
  pass
@@ -65,13 +69,14 @@ class BaseFormatter(abc.ABC):
65
69
  def digest(self, children, **kwargs) -> str:
66
70
  try:
67
71
 
68
-
69
72
  if not children:
70
73
  ret = ''
71
74
  elif isinstance(children, str):
72
75
  ret = self.digest_str(children)
73
76
  elif isinstance(children, dict) and children.get('typ', None) == 'meta':
74
77
  ret = self.digest_meta(children=children, **kwargs)
78
+ elif isinstance(children, dict) and children.get('typ', None) == 'table':
79
+ ret = self.digest_table(**children, **kwargs)
75
80
  elif isinstance(children, dict) and children.get('typ', None) == 'iter':
76
81
  ret = self.digest_iterator(children=children, **kwargs)
77
82
  elif isinstance(children, list) and children:
@@ -103,9 +108,11 @@ class BaseFormatter(abc.ABC):
103
108
  linebreak = tmp
104
109
 
105
110
  ret += linebreak
111
+
106
112
  return ret
107
113
 
108
114
  except Exception as err:
115
+ raise
109
116
  return self.handle_error(err, children)
110
117
 
111
118
 
@@ -131,3 +138,37 @@ class BaseFormatter(abc.ABC):
131
138
 
132
139
 
133
140
 
141
+ def _map_table2mat(self, children=None, **kwargs) -> str:
142
+ if children is None:
143
+ children = [[]]
144
+
145
+ assert isinstance(children, (list, tuple)), f'children must be of type list! but was {type(children)=} {children=}'
146
+ header = kwargs.get('header', None)
147
+ header = list(header) if header else []
148
+
149
+ assert isinstance(header, (list, tuple)), f'header must be of type list! but was {type(header)=} {header=}'
150
+ data = list(children)
151
+ wrong_rows = [row for row in children if not isinstance(row, (list, tuple))]
152
+ assert not wrong_rows, f'all rows must be of type list! but found {wrong_rows=}'
153
+
154
+ n_rows = kwargs.get('n_rows', None)
155
+ if n_rows is None:
156
+ n_rows = len(data)
157
+ n_cols = kwargs.get('n_cols', None)
158
+ if n_cols is None:
159
+ n_cols = max(len(header), max([len(row) for row in data]))
160
+
161
+ head = [self.digest(el) for el in header]
162
+ if len(head) < n_cols:
163
+ head += ['']*(n_cols-len(head))
164
+
165
+ mat = []
166
+ for i in range(n_rows):
167
+ mat.append(['']*n_cols)
168
+
169
+ for irow, row in enumerate(data):
170
+ for icol, el in enumerate(row):
171
+ mat[irow][icol] = self.digest(el)
172
+
173
+ return head, mat
174
+
@@ -98,7 +98,9 @@ class docx_renderer(BaseFormatter):
98
98
  return [self.digest(val, *args, **kwargs) for val in children]
99
99
  return []
100
100
 
101
-
101
+ def digest_table(self, children=None, **kwargs) -> str:
102
+ self.handle_error(NotImplementedError(f'exporter of type {type(self)} can not handle tables'))
103
+
102
104
  def digest_image(self, children, *args, **kwargs):
103
105
 
104
106
  image_width = Inches(max(1, kwargs.get('width', 0.8)*5))
@@ -225,3 +225,35 @@ class html_renderer(BaseFormatter):
225
225
  children += [f'<div style="width: 100%; text-align: center;"><span style="min-width:100;display: inline-block;"><b>caption: </b>{caption}</span></div>']
226
226
 
227
227
  return '\n\n'.join(children)
228
+
229
+ def digest_table(self, children=None, **kwargs) -> str:
230
+ borders = kwargs.pop('borders', None)
231
+ if borders is None:
232
+ borders = True
233
+ caption = kwargs.pop('caption', '')
234
+ if not caption:
235
+ caption = ''
236
+
237
+ head, mat = self._map_table2mat(children=children, **kwargs)
238
+ lines = []
239
+ st = ' style="border: 1px solid black;"' if borders else ''
240
+
241
+ lines.append('<table style="border-collapse: collapse; margin-left: auto; margin-right: auto;">')
242
+ lines.append(" <tr>")
243
+ lines += [f" <th{st}>{h}</th>" for h in head]
244
+ lines.append(" </tr>")
245
+ for row in mat:
246
+ lines.append(" <tr>")
247
+ lines += [f" <td{st}>{cell}</td>" for cell in row]
248
+ lines.append(" </tr>")
249
+
250
+ lines.append("</table>")
251
+
252
+ body = '\n'.join(lines)
253
+ txt = f'<div>{body}</div>'
254
+
255
+ if caption:
256
+ txt += f'\n<div style="text-align: center;"><span style="min-width:100;display: inline-block;"><b>Caption: </b>{caption}</span></div>'
257
+
258
+ return txt
259
+
@@ -191,6 +191,10 @@ class ipynb_renderer(BaseFormatter):
191
191
  self.cells += [make_markdown(content)]
192
192
  return ''
193
193
 
194
+ def digest_table(self, children=None, **kwargs) -> str:
195
+ self.handle_error(NotImplementedError(f'exporter of type {type(self)} can not handle tables'))
196
+
197
+
194
198
  def digest_image(self,imageblob=None, children='', width=0.8, caption="", **kwargs):
195
199
 
196
200
  if imageblob is None:
@@ -23,6 +23,29 @@ class DocumentMarkdownFormatter(BaseFormatter):
23
23
  def digest_markdown(self, children='', **kwargs) -> list:
24
24
  return children
25
25
 
26
+ def digest_table(self, children=None, **kwargs) -> str:
27
+ borders = kwargs.pop('borders', None)
28
+ if borders is None:
29
+ borders = True
30
+ caption = kwargs.pop('caption', '')
31
+ if not caption:
32
+ caption = ''
33
+
34
+ head, mat = self._map_table2mat(children=children, **kwargs)
35
+ striprow = lambda x: [str(xx).strip() for xx in x]
36
+
37
+ header = '| ' + ' | '.join(striprow(head)) + ' |'
38
+ separator = '|' + (' --- |' if borders else ' ---:|') * len(head)
39
+ rows = ['| ' + ' | '.join(striprow(row)) + ' |' for row in mat]
40
+ body = '\n'.join([header, separator] + rows)
41
+
42
+ if caption:
43
+ body += f'\n\n**Caption:** {caption}\n'
44
+
45
+ return body
46
+
47
+
48
+
26
49
  def digest_image(self, **kwargs) -> list:
27
50
 
28
51
  filename = kwargs.get('filename')
@@ -49,18 +72,23 @@ class DocumentMarkdownFormatter(BaseFormatter):
49
72
  lines.append('')
50
73
 
51
74
  # HACK: handle non PNG type properly!
75
+ if imageblob.startswith('data:image/png;base64,'):
76
+ i = imageblob
77
+ else:
78
+ i = 'data:image/png;base64,' + str(imageblob)
79
+
52
80
  if self.embed_images:
53
- lines.append(f'![{description}](data:image/png;base64,{imageblob})')
81
+ lines.append(f'![{description}]({i})')
54
82
  else:
55
- i = imageblob[:20] + f'... (n={len(imageblob)-20} more chars hidden))' if len(imageblob) > 20 else imageblob
56
- lines.append(f'#[{description}](data:image/png;base64,{i}')
83
+ i = i[:35] + f'... (n={len(i)-35} more chars hidden))' if len(i) > 35 else i
84
+ lines.append(f'#[{description}]({i}')
57
85
  lines.append('')
58
86
 
59
87
  if caption:
60
88
  lines.append(f'*caption:* {filename}')
61
89
  lines.append('')
62
90
 
63
- return lines
91
+ return '\n'.join(lines)
64
92
 
65
93
 
66
94
  def digest_verbatim(self, children='', **kwargs) -> list:
@@ -5,7 +5,12 @@ try:
5
5
  from pydocmaker.backend.baseformatter import BaseFormatter
6
6
  except Exception as err:
7
7
  from .baseformatter import BaseFormatter
8
-
8
+
9
+ try:
10
+ from pydocmaker.backend.pandoc_api import can_run_pandoc, pandoc_convert
11
+ except Exception as err:
12
+ from .pandoc_api import can_run_pandoc, pandoc_convert
13
+
9
14
 
10
15
  def convert(doc:List[dict], with_attachments=True, aformat_redmine=False):
11
16
 
@@ -89,12 +94,16 @@ class DocumentRedmineFormatter(BaseFormatter):
89
94
 
90
95
  @handle_color
91
96
  def digest_markdown(self, children='', **kwargs) -> str:
92
- return children
97
+ if can_run_pandoc():
98
+ return pandoc_convert(children, 'markdown', 'textile')
99
+ else:
100
+ return children
93
101
 
94
102
  @handle_color
95
103
  def digest_text(self, children='', **kwargs) -> str:
96
104
  return children
97
105
 
106
+
98
107
  def digest_image(self, **kwargs) -> str:
99
108
  filename, content = im2file(kwargs)
100
109
  attachment = im2attachment(kwargs, filename, content)
@@ -110,8 +119,11 @@ class DocumentRedmineFormatter(BaseFormatter):
110
119
  return s
111
120
 
112
121
  def digest_latex(self, children='', **kwargs) -> str:
113
- return self.digest_verbatim(children=children, **kwargs)
114
-
122
+ if can_run_pandoc():
123
+ return pandoc_convert(children, 'latex', 'textile')
124
+ else:
125
+ return self.digest_verbatim(children=children, **kwargs)
126
+
115
127
  @handle_color
116
128
  def digest_verbatim(self, children='', **kwargs) -> str:
117
129
  if isinstance(children, str):
@@ -123,33 +135,23 @@ class DocumentRedmineFormatter(BaseFormatter):
123
135
  return s
124
136
 
125
137
 
126
- def parse_md2html(self, s) -> str:
127
- return markdown.markdown(s, extensions=['extra', 'toc'])
128
-
129
- def parse_md2textile_line(self, line):
130
- r = re.match(r'([ \t]*)#+', line)
131
- n = r.group().count('#') if r else None
132
- if n:
133
- line = re.sub(r'([ \t]*)#+', rf'\1h{n}. ', line)
134
-
135
- r = re.match(r'^([ \t]*-{1}[ ]{1})', line)
136
- if r:
137
- g = r.group()
138
- line = line.replace(g, ('*'*len(g)) + ' ')
139
-
140
- return line
141
-
142
-
143
-
144
- def parse_md2textile(self, s) -> str:
145
- f = self.parse_md2textile_line
146
- lines = [f(line) for line in s.split('\n')]
147
- s = '\n'.join(lines)
148
- # code blocks
149
- s = re.sub(r"(```)([\s\S]*?)(?=```)(```)", r'<pre>\2</pre>', s)
150
-
151
- # links
152
- s = re.sub(r"(\[)([\s\S]*?)(?=\])(\])(\()([\s\S]*?)(?=\))(\))", r'"\2":\5', s)
138
+ def digest_table(self, children=None, **kwargs) -> str:
139
+ borders = kwargs.pop('borders', None)
140
+ if borders is None:
141
+ borders = True
142
+ caption = kwargs.pop('caption', '')
143
+ if not caption:
144
+ caption = ''
145
+
146
+ head, mat = self._map_table2mat(children=children, **kwargs)
147
+ striprow = lambda x: [str(xx).strip() for xx in x]
148
+
149
+ header = '|_.' + ' |_.'.join(striprow(head)) + ' |'
153
150
 
154
- return s
155
-
151
+ rows = ['| ' + ' |'.join(striprow(row)) + ' |' for row in mat]
152
+ body = '\n'.join([header] + rows)
153
+ if caption:
154
+ body += f'\n\nCaption: {caption}\n'
155
+ return body
156
+
157
+
@@ -427,3 +427,60 @@ class LatexElementFormatter(BaseFormatter):
427
427
  def digest_line(self, children:str, **kwargs):
428
428
  return replace_bcolors(str(children))
429
429
 
430
+
431
+ def digest_table(self, children=None, **kwargs) -> str:
432
+ borders = kwargs.pop('borders', None)
433
+ if borders is None:
434
+ borders = True
435
+
436
+ caption = kwargs.pop('caption', '')
437
+ if not caption:
438
+ caption = ''
439
+
440
+ head, mat = self._map_table2mat(children=children, **kwargs)
441
+ if not head and not mat[0]:
442
+ return ''
443
+
444
+
445
+ striprow = lambda x: [str(xx).strip() for xx in x]
446
+ bold = lambda x: '\\textbf{' + str(x).strip() + '}'
447
+
448
+ n_cols = len(head) if head else len(mat[0])
449
+
450
+ lines = []
451
+ if borders:
452
+ lines.append(r'\hline')
453
+
454
+ if head:
455
+ lines.append(' & '.join([bold(hh) for hh in head]) + r' \\')
456
+ if borders:
457
+ lines.append(r'\hline')
458
+ for row in mat:
459
+ lines.append(' & '.join(striprow(row)) + r' \\')
460
+ if borders:
461
+ lines.append(r'\hline')
462
+
463
+ if not borders:
464
+ d = ' '.join(['c'] * n_cols)
465
+ else:
466
+ d = '|' + '|'.join(['c'] * n_cols) + '|'
467
+
468
+ if caption:
469
+ caption = '\\caption{%s}' % (escape(caption))
470
+
471
+ txt = '''\\begin{table}[h!]
472
+ \centering
473
+ \\begin{tabular}{ %s }
474
+ %s
475
+ \end{tabular}
476
+ %s
477
+ \end{table}''' % (d, '\n'.join(lines), caption)
478
+ else:
479
+ txt = '''\\begin{center}
480
+ \\begin{tabular}{ %s }
481
+ %s
482
+ \end{tabular}
483
+ \end{center}''' % (d, '\n'.join(lines))
484
+
485
+ return txt
486
+
@@ -144,6 +144,15 @@ class constr():
144
144
  'end': end
145
145
  }
146
146
 
147
+ @staticmethod
148
+ def line(children='', color='', end=None):
149
+ return {
150
+ 'typ': 'line',
151
+ 'children': children,
152
+ 'color': color,
153
+ 'end': '\n' if end is None else end
154
+ }
155
+
147
156
  @staticmethod
148
157
  def latex(children='', color='', end=None):
149
158
  return {
@@ -172,6 +181,20 @@ class constr():
172
181
  'end': end
173
182
  }
174
183
 
184
+ @staticmethod
185
+ def table(children:list=None, color='', end=None, header=None, caption=None, n_cols=None, n_rows=None, borders=True):
186
+ return {
187
+ 'typ': 'table',
188
+ 'children': children,
189
+ 'n_cols': n_cols,
190
+ 'n_rows': n_rows,
191
+ 'borders': borders,
192
+ 'header': header,
193
+ 'caption': caption,
194
+ 'color': color,
195
+ 'end': end,
196
+ }
197
+
175
198
  @staticmethod
176
199
  def image(imageblob='', caption='', children='', width=0.8, color='', end=None):
177
200
 
@@ -789,7 +812,29 @@ class DocBuilder(UserList):
789
812
  self.add(construct('markdown', children=children, color=color, end=end, **kwargs), index=index, chapter=chapter)
790
813
  return self
791
814
 
815
+ def add_table(self, children=None, index=None, chapter=None, color='', end=None, header=None, caption='', n_rows=None, n_cols=None, borders=True, **kwargs):
816
+ """add a table element to this document
792
817
 
818
+ Args:
819
+ children (list of lists): the "children" for this element. Must be a matrix (list of lists) with formatable elements in it.
820
+ index (int, optional): The index where to insert the part. If None, appends to the end.
821
+ chapter (str | int, optional): The chapter name or index where to insert the part. If None, appends to the end.
822
+ color (str, optional): any color which can be rendered by html or latex. Empty string for default.
823
+ end (str, optional): If you want to insert a different line ending (than the default) for this element set this argument to any string. None for default.
824
+ header (list, optional): The header row for the table. If given it must be a list with formatable elements in it.
825
+ caption (str, optional): The caption to place at/under the table. Empty for no caption.
826
+ n_rows (int, optional): The number of rows to give this table. If not given it will be determined from the number of rows in children.
827
+ n_cols (int, optional): The number of columns to give this table. If not given it will be determined from the max number of columns in all rows in children.
828
+ borders (bool, optional): Whether or not the table should have lines between its cells.
829
+ """
830
+ if header: kwargs['header'] = header
831
+ if n_rows: kwargs['n_rows'] = n_rows
832
+ if n_cols: kwargs['n_cols'] = n_cols
833
+ if borders: kwargs['borders'] = borders
834
+ if caption: kwargs['caption'] = caption
835
+ self.add(constr.table(children=children, color=color, end=end, **kwargs), index=index, chapter=chapter)
836
+ return self
837
+
793
838
  def add_pre(self, children=None, index=None, chapter=None, color='', end=None, **kwargs):
794
839
  """add a verbaim (pre formatted) document part to this document
795
840
 
@@ -1495,6 +1540,17 @@ function metamorphose(protagonist,author){
1495
1540
  }
1496
1541
  """)
1497
1542
  doc.add_tex("\\textit{This is some dummy LaTeX text.}")
1543
+
1544
+ doc.add_md("this is how to embed a table:")
1545
+
1546
+ header = ['Name', 'Age', 'City']
1547
+ table = [
1548
+ ['John Doe', "30", 'New York'],
1549
+ ['Jane Smith', "25", 'Los Angeles'],
1550
+ ['Mike Johnson', "35", 'Chicago']
1551
+ ]
1552
+ doc.add_table(table, header=header, borders=True, caption='This is my example table')
1553
+
1498
1554
  doc.add('And this is how to embed an Image:')
1499
1555
  doc.add_image(image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAUCAAAAAAVAxSkAAABrUlEQVQ4y+3TPUvDQBgH8OdDOGa+oUMgk2MpdHIIgpSUiqC0OKirgxYX8QVFRQRpBRF8KShqLbgIYkUEteCgFVuqUEVxEIkvJFhae3m8S2KbSkcFBw9yHP88+eXucgH8kQZ/jSm4VDaIy9RKCpKac9NKgU4uEJNwhHhK3qvPBVO8rxRWmFXPF+NSM1KVMbwriAMwhDgVcrxeMZm85GR0PhvGJAAmyozJsbsxgNEir4iEjIK0SYqGd8sOR3rJAGN2BCEkOxhxMhpd8Mk0CXtZacxi1hr20mI/rzgnxayoidevcGuHXTC/q6QuYSMt1jC+gBIiMg12v2vb5NlklChiWnhmFZpwvxDGzuUzV8kOg+N8UUvNBp64vy9q3UN7gDXhwWLY2nMC3zRDibfsY7wjEkY79CdMZhrxSqqzxf4ZRPXwzWJirMicDa5KwiPeARygHXKNMQHEy3rMopDR20XNZGbJzUtrwDC/KshlLDWyqdmhxZzCsdYmf2fWZPoxCEDyfIvdtNQH0PRkH6Q51g8rFO3Qzxh2LbItcDCOpmuOsV7ntNaERe3v/lP/zO8yn4N+yNPrekmPAAAAAElFTkSuQmCC")
1500
1556
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pydocmaker
3
- Version: 2.2.7
3
+ Version: 2.2.8
4
4
  Summary: a minimal document maker to make docx, markdown, html, textile, redmine, and tex documents from python. Written in pure python.
5
5
  Home-page: https://github.com/TobiasGlaubach/pydocmaker
6
6
  Author: Tobias Glaubach
@@ -32,6 +32,19 @@ class TestHtmlRenderer(unittest.TestCase):
32
32
  result = self.formatter.digest({'typ': 'verbatim'})
33
33
  self.assertIsInstance(result, str)
34
34
 
35
+ def test_digest_table(self):
36
+ result = self.formatter.digest([['element1', 'element2']])
37
+ self.assertIsInstance(result, str)
38
+
39
+ dc = {
40
+ 'children': [['element1', 'element2']],
41
+ 'header': ['h1', 'h2'],
42
+ 'n_cols': 3,
43
+ 'typ': 'table'
44
+ }
45
+ result = self.formatter.digest(dc)
46
+ self.assertIsInstance(result, str)
47
+
35
48
  def test_digest_iterator(self):
36
49
  result = self.formatter.digest(['element1', 'element2'])
37
50
  self.assertIsInstance(result, str)
@@ -62,6 +75,7 @@ class TestHtmlRenderer(unittest.TestCase):
62
75
  self.assertIsInstance(res, str)
63
76
  self.assertTrue(res)
64
77
 
78
+
65
79
  if __name__ == '__main__':
66
80
  unittest.main()
67
81
 
File without changes
File without changes
File without changes
File without changes