Skip to content

Commit 53050fa

Browse files
committed
keywords; highlighting; url & inline code formatting
1 parent 7eccc72 commit 53050fa

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

server.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,46 @@ function formatDate(timestamp)
3434
}
3535

3636
// format a massege for code blocks
37-
function formatMessage(string)
37+
function formatMessage(string, keywords)
3838
{
39-
const regex = /\`\`\`(([a-z]+)\n)?\n*([\s\S]*?)\n*\`\`\`/g;
40-
const s = string.replace(regex, (match, p1, p2, p3, offset, string) =>
39+
const regex = /\`\`\`(([a-zA-Z]+)\n)?\n*([\s\S]*?)\n*\`\`\`/g;
40+
var s = string.replace(regex, (match, p1, p2, p3, offset, string) =>
4141
`<div class="code">${p2 ? `<span class="lang">#${p2}</span><br />` : ""}${p3.replace(/\n/g, "<br />")}</div>`);
42-
// also parse inline `code` and urls
42+
43+
const inlineRegex = /\`([^\`]+)\`/g;
44+
s = s.replace(inlineRegex, (match, p1) => `<span class="inlineCode">${p1}</span>`);
45+
46+
const urlRegex = /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*))/g;
47+
s = s.replace(urlRegex, (match, p1) => `<a href="${p1}">${p1}</a>`);
48+
49+
keywords.filter(word => word.length).forEach(word => s = s.replace(new RegExp(word, "g"), `<span class="keyword">${word}</span>`));
4350
return s;
4451
}
4552

4653
// make html output for a message
47-
function makeMessagePage(rows)
54+
function makeMessagePage(rows, keywords)
4855
{
4956
const body = rows.map(row => `
5057
<a class="perma" href="/code?msgId=${row.msgId}">permalink</a><br />
5158
Author: ${row.author}<br />
5259
Channel: ${row.channel}<br />` + row.revisions.map(revision => `
5360
<span class="timestamp">${formatDate(revision.date)}</span>
54-
<div class="messageBody">${formatMessage(revision.fullMessage)}</div>
61+
<div class="messageBody">${formatMessage(revision.fullMessage, keywords)}</div>
5562
`).join("<br /><br />")).join("<br /><br />");
5663

5764
return `
5865
<style>
66+
.inlineCode
67+
{
68+
font-family: monospace;
69+
color: #EEE;
70+
background-color: #555;
71+
}
72+
.keyword
73+
{
74+
background-color: yellow;
75+
color: black;
76+
}
5977
.perma
6078
{
6179
font-size: small;
@@ -119,6 +137,8 @@ frontend.get("/", (request, response) => {
119137
{
120138
response.send(`
121139
<form action="/code/">
140+
<label for="keywords">Keywords</label>
141+
<input id="keywords" name="keywords"><br />
122142
<label for="author">Author</label>
123143
<select id="author" name="author">
124144
<option value="">*</option>
@@ -152,6 +172,11 @@ function strtotime(string)
152172
return new Date(string).getTime();
153173
}
154174

175+
function containsKeywords(string, keywords)
176+
{
177+
return keywords.reduce((acc, word) => word === "" ? acc : acc && (string.indexOf(word) != -1), true);
178+
}
179+
155180
// filter messages query
156181
frontend.get("/code/", (request, response) => {
157182
var sql = `SELECT * FROM Message`;
@@ -186,6 +211,7 @@ frontend.get("/code/", (request, response) => {
186211
if(e) exit(`Error querying database: ${e}`);
187212
else
188213
{
214+
const keywords = request.query.keywords ? request.query.keywords.split(" ") : [];
189215
var rows = messageRows;
190216
rows = rows.map(row => {
191217
row.revisions = contentRows
@@ -197,8 +223,10 @@ frontend.get("/code/", (request, response) => {
197223
rows = rows.filter(row => row.revisions[0].date >= strtotime(request.query.from));
198224
if(request.query.to)
199225
rows = rows.filter(row => row.revisions[0].date < strtotime(request.query.to));
226+
if(request.query.keywords)
227+
rows = rows.filter(row => row.revisions.reduce((acc, revision) => containsKeywords(revision.fullMessage, keywords), true));
200228
if(request.query.as === "json") response.send(rows);
201-
else response.send(makeMessagePage(rows));
229+
else response.send(makeMessagePage(rows, keywords));
202230
};
203231
});
204232
};

0 commit comments

Comments
 (0)