Skip to content

Instantly share code, notes, and snippets.

@fhpriamo
Last active January 11, 2021 14:36
Show Gist options
  • Save fhpriamo/54cbafe92aab44ff1877fd1a156f6baf to your computer and use it in GitHub Desktop.
Save fhpriamo/54cbafe92aab44ff1877fd1a156f6baf to your computer and use it in GitHub Desktop.
//
// src/lib/html
//
export const DOCTYPE_TAG = `<!DOCTYPE html>`;
const HTML_ESCAPES = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'/': '&#x2F;',
};
const htmlEscaper = /[&<>"'/]/g;
export function escape(text) {
return `${text}`.replace(htmlEscaper, (match) => {
return HTML_ESCAPES[match];
});
}
export function attrs(attributes = {}, pad = false) {
const attrsStr = Object.entries(attributes)
.map(([k, v]) => `${k}="${v}"`)
.join(' ');
return `${' '.repeat(+pad)}${attrsStr}`;
}
export function stag(name, attributes) {
return `<${name}${attrs(attributes, !!attributes)} />`;
}
export function ctag(name, content, attributes) {
return `<${name}${attrs(attributes, !!attributes)}>${content}</${name}>`;
}
export function tag(name, content, attributes) {
return content != null
? ctag(name, content, attributes)
: stag(name, attributes);
}
export function concat(...contents) {
return contents.join('');
}
//
// src/lib/reporters/html-reporter/style.js
//
const REPORT_STYLE = `
table {\
table-layout: fixed;\
width: 100%;\
border-collapse: collapse;\
border: 3px solid purple;\
}\
thead th:nth-child(1) {\
width: 30%;\
}\
thead th:nth-child(2) {\
width: 20%;\
}\
thead th:nth-child(3) {\
width: 15%;\
}\
thead th:nth-child(4) {\
width: 35%;\
}\
th, td {\
padding: 20px;\
}\
html {\
font-family: 'helvetica neue', helvetica, arial, sans-serif;\
}\
th {\
letter-spacing: 2px;\
}\
td {\
letter-spacing: 1px;\
}\
tbody td {\
text-align: center;\
}\
tfoot th {\
text-align: right;\
}\
thead, tfoot {\
background: grey;\
color: white;\
}\
thead th, tfoot th, tfoot td {\
border: 1px solid black;\
}\
tbody tr:nth-child(odd) {\
background-color: white;\
}\
tbody tr:nth-child(even) {\
background-color: #E0E0E0;\
}\
table {\
background-color: white;\
border-width: 0px;\
}`;
//
// src/lib/reporters/html-reporter/html.js
//
function formatTableCols(data) {
return data.map((d) => tag('td', escape(d))).join('');
}
function formatTableRow(data) {
return tag('tr', formatTableCols(data));
}
function formatTableRows(data) {
return data.map((r) => formatTableRow(r)).join('');
}
function formatTableBody(data) {
return tag('tbody', formatTableRows(data));
}
function formatTableHeaderRow(data) {
return tag('tr', formatHeaderCols(data));
}
function formatTableHeader(content) {
return tag('thead', formatTableHeaderRow(content));
}
function formatHeaderCols(data) {
return data.map((d) => tag('th', escape(d))).join('');
}
function formatTable(header, body) {
const content = concat(formatTableHeader(header), formatTableBody(body));
return tag('table', content);
}
function formatBody(data) {
const [header, ...body] = data;
return tag('body', formatTable(header, body));
}
function formatHead(title, style) {
return tag(
'head',
concat(
tag('meta', null, { charset: 'utf-8' }),
tag('title', escape(title)),
tag('style', style)
)
);
}
export function createHtmlReportFormatter({
style = REPORT_STYLE,
title = 'Report',
} = {}) {
return (data) => {
return concat(
DOCTYPE_TAG,
tag('html', concat(formatHead(title, style), formatBody(data)))
);
};
}
//
// Exemplo:
//
const formatHtmlReport = createHtmlReportFormatter({
title: 'Ocorrências 2018-20',
});
/**
* Simulates data coming from a database or some other external source.
*/
function getCrimeData() {
return [
['ANO', 'MÊS', 'OCORRÊNCIA', 'DELEGACIA'],
[2018, 'Jun', 'Atentado ao pudor', 'DP 110-SP'],
[2018, 'Jun', 'Assalto à mão armada', 'DP 235-MG'],
[2019, 'Jul', 'Latrocínio', 'DP 522-MT'],
[2019, 'Ago', 'Latrocínio', 'DP 707-RJ'],
[2020, 'Fev', 'Tentativa de assasinato', 'DP 421-SP'],
[2020, 'Jan', 'Tentativa de assasinato', 'DP 235-MG'],
[2020, 'Out', 'Homicídio culposo', 'DP 002-MT'],
[2020, 'Out', 'Homicídio doloso', 'DP 231-GO'],
[2020, 'Out', 'Furto de veículo', 'DP 231-SP'],
];
}
console.log(formatHtmlReport(getCrimeData()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment