HTML Renderer (Emacs)
Emacs: A non-intrusive browser
An Elisp implementation of HTML rendering using SVG. The browser functionality is an extension of eww. For Javascript, you can use either NodeJS or QuickJS as a JS interpreter.
Developer Note: The entry point is shr-render.
Table
Colspan example |
Rowspan example |
Sample Table
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
</tr>
<tr>
<td>Empire Burlesque</td>
<td>Bob Dylan</td>
</tr>
</table>
</body>
</html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
</tr>
<tr>
<td>Empire Burlesque</td>
<td>Bob Dylan</td>
</tr>
</table>
</body>
</html>
CSS Support
Limited CSS support for following attributes - padding, margin, margin-left, margin-top, border, color, background, background-color, display, width, height, clear, text-align, font, font-size, font-style, font-weight.
Minimal CSS
head {display: none}
body {margin: 8; font-size: 14;}
b {font-weight: bold}
em, i {font-style: italic}
a, em, i, b {display: inline}
hr {height: 1; border: 1; color: grey}
h1, h2, h3, p, ul, li {display: block}
input, button {display: flex; margin: 5; padding: 5; border: 1;}
button {background-color: #adb1b8;}
a {color: blue}
// Break table
body {margin: 8; font-size: 14;}
b {font-weight: bold}
em, i {font-style: italic}
a, em, i, b {display: inline}
hr {height: 1; border: 1; color: grey}
h1, h2, h3, p, ul, li {display: block}
input, button {display: flex; margin: 5; padding: 5; border: 1;}
button {background-color: #adb1b8;}
a {color: blue}
// Break table
table {display: table}
tr {display: table-row}
tr {display: table-row}
// Less used tags
center {display: block; text-align: center;}
big, tt, font {display: inline}
center {display: block; text-align: center;}
big, tt, font {display: inline}
Caching
Static resources like images, JS and CSS are cached by url package based on HTTP 304 (Not Modified) status. Cache expiry is controlled by url-cache-expire-time.
This function might be useful in other scenarios. Use (url-fetch-from-cache url) to retrieve the object.
(defun fetch (url)
(let* ((site (url-generic-parse-url url))
(buf (get-buffer-create (url-cache-create-filename url))))
(with-current-buffer buf
(setq url-current-object site))
(if (not (url-is-cached url))
(url-queue-retrieve
url 'jit--image-fetched
(list buf)
t
(not (shr--use-cookies-p url shr-base))))
))
(let* ((site (url-generic-parse-url url))
(buf (get-buffer-create (url-cache-create-filename url))))
(with-current-buffer buf
(setq url-current-object site))
(if (not (url-is-cached url))
(url-queue-retrieve
url 'jit--image-fetched
(list buf)
t
(not (shr--use-cookies-p url shr-base))))
))
Masonry
Pictures look best when their aspect ratios are maintained. If you are viewing a collection of pictures in a regular grid layout, this results in some jarring whitespace. Masonry layout, like below, provides a more tight fitting view.
<style>
.grid {
display: masonry;
column-count: 3;
}
</style>
<h1>Masonry</h1>
<div class="grid">
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/orange-tree.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/submerged.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/look-out.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/one-world-trade.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/drizzle.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/cat-nose.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/contrail.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/golden-hour.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/flight-formation.jpg" />
</div>
</div>
.grid {
display: masonry;
column-count: 3;
}
</style>
<h1>Masonry</h1>
<div class="grid">
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/orange-tree.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/submerged.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/look-out.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/one-world-trade.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/drizzle.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/cat-nose.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/contrail.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/golden-hour.jpg" />
</div>
<div class="grid-item">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/82/flight-formation.jpg" />
</div>
</div>
Lessons Learnt
- To improve HTML page load performance and to reduce jitters, provide the dimensions for image as much as possible. This takes out any guess work, reflow (causes for jitters) or the need to fetch image for finding the dimensions (cause for delays).
- Margin is the space between elements. First reading of Box model might lead you to believe that margins are additive. However, margin collapse ensures that they don't add up.
- For constant border in table layout, cells must overlap. In contrast, blocks normally don't overlap and are separated by margin.
- In librsvg, 50% of border lies outside the box definition. This is especially important when you're drawing boxes with thick borders.
- Most elements in an HTML page are not rendered - they simply act as a container. Generally speaking, if they don't have a border or background, they need not be drawn. However, they are very important from CSS perspective.
- CSS plays an important role in sizing the elements. Hence it must be loaded before layout calculations.
Comments
Post a Comment