Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions examples/html/html_all_elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,7 @@ <h1>Tables</h1>
<caption>
This is a caption for a table
</caption>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Date</th>
<th>Address</th>
</tr>
</thead>

<tfoot>
<tr>
<td>Table footer info</td>
Expand All @@ -472,6 +465,14 @@ <h1>Tables</h1>
<td>999 Spruce Lane, Somewhere, CA 94101</td>
</tr>
</tbody>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Date</th>
<th>Address</th>
</tr>
</thead>
</table>
</section>
<section>
Expand Down
94 changes: 94 additions & 0 deletions examples/html/html_just_table.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

<!-- Set the title of your site here -->
<title>HTML Patterns</title>

<meta name="author" content="mrmrs" />
<meta name="description" content="Common HTML patterns" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<!-- Link to your stylesheet here
<link rel="stylesheet" href="css/i.css">

Favicons and Touch Device Icons
<link rel="shortcut icon" href="favicon.ico">
<link rel="apple-touch-icon" href="touch-icon-iphone-precomposed.png">
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad-precomposed.png">
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone-retina-precomposed.png">
<link rel="apple-touch-icon" sizes="144x144" href="touch-icon-ipad-retina-precomposed.png">
-->
</head>

<body>
<header>
<h1>HTML</h1>
<h2>Every html element in one place. Just waiting to be styled.</h2>
</header>

<section>
<h1>Tables</h1>
<!--
From the HTML spec (http://www.w3.org/TR/html401/struct/tables.html)

TFOOT must appear before TBODY within a TABLE definition so that user agents can
render the foot before receiving all of the (potentially numerous) rows of data.
The following summarizes which tags are required and which may be omitted:

The TBODY start tag is always required except when the table contains only one
table body and no table head or foot sections. The TBODY end tag may always be
safely omitted.

The start tags for THEAD and TFOOT are required when the table head and foot sections
are present respectively, but the corresponding end tags may always be safely
omitted.

Conforming user agent parsers must obey these rules for reasons of backward
compatibility.
-->
<table>
<caption>
This is a caption for a table
</caption>

<tfoot>
<tr>
<td>Table footer info</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>#999-32ac</td>
<td>First Name</td>
<td>13 May, 2013</td>
<td>999 Spruce Lane, Somewhere, CA 94101</td>
</tr>
<tr>
<td>#888-32dd</td>
<td>Sample Name</td>
<td>17 May, 1984</td>
<td>999 Spruce Lane, Somewhere, CA 94101</td>
</tr>
</tbody>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Date</th>
<th>Address</th>
</tr>
</thead>
</table>
</section>
<section>
<h1>Footer</h1>
<footer>
<small>© 2014 Some company name</small>
<address>email@email.com</address>
</footer>
</section>
</body>
</html>
10 changes: 9 additions & 1 deletion jsondoc/convert/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,15 @@ def convert_tr(self, el, convert_as_inline):
"""
Table row
"""
return ConvertOutput(main_object=create_table_row_block())
# Check if this is a header row
is_header = False
is_footer = False
if el.find_parent("thead") or el.find_parent("th"):
is_header = True
# Check if this is a footer row
if el.find_parent("tfoot"):
is_footer = True
return ConvertOutput(main_object=create_table_row_block(isHeader=is_header, isFooter=is_footer))


def html_to_jsondoc(html: str | bytes, **options) -> Page | BlockBase | List[BlockBase]:
Expand Down
33 changes: 26 additions & 7 deletions jsondoc/convert/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ def convert_quote_block(self, block: QuoteBlock, convert_as_inline: bool) -> str
)

def _convert_table_row_block(
self, block: TableRowBlock, convert_as_inline: bool, is_headrow: bool
self, block: TableRowBlock, convert_as_inline: bool, is_headrow: bool, is_footrow: bool
) -> str:
# cells = block.table_row.cells

Expand Down Expand Up @@ -383,18 +383,37 @@ def _convert_table_row_block(
return overline + "|" + text + "\n" + underline

def convert_table_block(self, block: TableBlock, convert_as_inline: bool) -> str:
# TODO: Caption is not at the very bottom after the footer. Fix it.
text = ""

for n, row in enumerate(block.children):
is_headrow = block.table.has_column_header and n == 0

text += self._convert_table_row_block(
is_headrow = block.table.has_column_header and row.isHeader
is_footrow = row.isFooter

textHeader = "\n\n"
textFooter = ""

if is_headrow:
textHeader = self._convert_table_row_block(
row,
convert_as_inline,
is_headrow=is_headrow,
is_footrow=is_footrow,
)

return "\n\n" + text + "\n"
elif is_footrow:
textFooter = self._convert_table_row_block(
row,
convert_as_inline,
is_headrow=is_headrow,
is_footrow=is_footrow,
)
else:
text += self._convert_table_row_block(
row,
convert_as_inline,
is_headrow=is_headrow,
is_footrow=is_footrow,
)
return textHeader + text + textFooter


def jsondoc_to_markdown(jsondoc, **options):
Expand Down
5 changes: 5 additions & 0 deletions jsondoc/convert/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ def create_table_row_block(
cells: List[List[RichTextBase]] = [],
id: str | None = None,
created_time=None,
isHeader: bool = False,
isFooter: bool = False,
) -> TableRowBlock:
if id is None:
id = generate_id()
Expand All @@ -420,6 +422,8 @@ def create_table_row_block(
created_time=created_time,
table_row=TableRow(cells=cells),
has_children=False,
isHeader=isHeader,
isFooter=isFooter,
)


Expand All @@ -430,6 +434,7 @@ def create_table_block(
table_width: int | None = None,
has_column_header: bool = False,
has_row_header: bool = False,
caption: str | None = None,
) -> TableBlock:
if id is None:
id = generate_id()
Expand Down
2 changes: 2 additions & 0 deletions jsondoc/models/block/types/table_row/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ class TableRow(BaseModel):
class TableRowBlock(BlockBase):
type: Literal['table_row'] = 'table_row'
table_row: TableRow
isHeader: bool
isFooter: bool
6 changes: 6 additions & 0 deletions schema/block/types/table_row/table_row_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
},
"required": ["cells"],
"additionalProperties": false
},
"isHeader": {
"type": "boolean"
},
"isFooter": {
"type": "boolean"
}
},
"required": ["type", "table_row"],
Expand Down
16 changes: 12 additions & 4 deletions tests/html_jsondoc_pairs/test_table_basic.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
}
]
]
}
},
"isHeader": true,
"isFooter": false
},
{
"object": "block",
Expand Down Expand Up @@ -90,7 +92,9 @@
}
]
]
}
},
"isHeader": false,
"isFooter": false
},
{
"object": "block",
Expand Down Expand Up @@ -131,7 +135,9 @@
}
]
]
}
},
"isHeader": false,
"isFooter": false
},
{
"object": "block",
Expand Down Expand Up @@ -172,7 +178,9 @@
}
]
]
}
},
"isHeader": false,
"isFooter": false
}
]
}
Expand Down
16 changes: 12 additions & 4 deletions tests/html_jsondoc_pairs/test_table_with_caption.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@
}
]
]
}
},
"isHeader": true,
"isFooter": false
},
{
"object": "block",
Expand Down Expand Up @@ -112,7 +114,9 @@
}
]
]
}
},
"isHeader": false,
"isFooter": false
},
{
"object": "block",
Expand Down Expand Up @@ -163,7 +167,9 @@
}
]
]
}
},
"isHeader": false,
"isFooter": false
},
{
"object": "block",
Expand All @@ -187,7 +193,9 @@
[],
[]
]
}
},
"isHeader": false,
"isFooter": true
}
]
},
Expand Down
12 changes: 12 additions & 0 deletions tests/test_html_to_jsondoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ def test_examples():
print("PASS")


def test():
path = "examples/html/html_just_table.html"
content = open(path, "r").read()
ret = html_to_jsondoc(content)
# print(jsondoc_dump_json(ret, indent=2))

# print("\n\nConverted to markdown:\n\n")
# print(jsondoc_to_markdown(ret[0]))
print(jsondoc_to_markdown(ret))

if __name__ == "__main__":
test_examples()
test_convert_html_all_elements()
# Test for working specifically on tables with caption
# test()
Loading