facilmap/utils/src/format.ts

93 wiersze
3.0 KiB
TypeScript
Czysty Zwykły widok Historia

import { marked } from 'marked';
2020-12-24 04:57:46 +00:00
import { Field } from "facilmap-types";
import { normalizeField } from './filter.js';
import { quoteHtml } from './utils.js';
import linkifyStr from 'linkify-string';
2021-03-27 17:17:28 +00:00
import createPurify from 'dompurify';
import { obfuscate } from './obfuscate.js';
import cheerio from 'cheerio';
2021-03-27 17:17:28 +00:00
const purify = createPurify(typeof window !== "undefined" ? window : new (await import("jsdom")).JSDOM("").window);
2020-12-24 04:57:46 +00:00
const markdownOptions: marked.MarkedOptions = {
2021-03-13 23:54:10 +00:00
breaks: true
};
2020-12-24 04:57:46 +00:00
2021-01-23 11:38:26 +00:00
export function formatField(field: Field, value: string): string {
2021-04-04 22:24:05 +00:00
value = normalizeField(field, value);
2020-12-24 04:57:46 +00:00
switch(field.type) {
case "textarea":
return markdownBlock(value);
case "checkbox":
return value == "1" ? "✔" : "✘";
case "dropdown":
2021-03-06 08:11:34 +00:00
return quoteHtml(value) || "";
2020-12-24 04:57:46 +00:00
case "input":
default:
return markdownInline(value);
}
}
export function markdownBlock(string: string): string {
const $ = cheerio.load("<div/>");
const el = $.root();
el.html(purify.sanitize(marked(string, markdownOptions)));
applyMarkdownModifications(el, $);
return el.html()!;
2020-12-24 04:57:46 +00:00
}
export function markdownInline(string: string): string {
const $ = cheerio.load("<div/>");
const el = $.root();
el.html(purify.sanitize(marked(string, markdownOptions)));
$("p", el).replaceWith(function(this: cheerio.Element) { return $(this).contents(); });
applyMarkdownModifications(el, $);
return el.html()!;
2020-12-24 04:57:46 +00:00
}
2021-01-23 11:38:26 +00:00
export function round(number: number, digits: number): number {
2020-12-24 04:57:46 +00:00
const fac = Math.pow(10, digits);
return Math.round(number*fac)/fac;
}
2021-01-23 11:38:26 +00:00
export function formatTime(seconds: number): string {
2020-12-24 04:57:46 +00:00
const hours = Math.floor(seconds/3600);
let minutes: string | number = Math.floor((seconds%3600)/60);
if(minutes < 10)
minutes = "0" + minutes;
return hours + ":" + minutes;
}
2021-05-12 01:13:34 +00:00
function applyMarkdownModifications($el: cheerio.Cheerio, $: cheerio.Root): void {
2020-12-24 04:57:46 +00:00
$("a[href]", $el).attr({
target: "_blank",
rel: "noopener noreferer"
});
2021-02-28 22:17:26 +00:00
2021-05-12 01:13:34 +00:00
obfuscate($el, $);
2020-12-24 04:57:46 +00:00
}
2021-03-13 09:43:32 +00:00
export function renderOsmTag(key: string, value: string): string {
if(key.match(/^wikipedia(:|$)/)) {
return value.split(";").map((it) => {
const m = it.match(/^(\s*)((([-a-z]+):)?(.*))(\s*)$/)!;
const url = "https://" + (m[4] || "en") + ".wikipedia.org/wiki/" + m[5];
return m?.[1] + '<a href="' + quoteHtml(url) + '" target="_blank">' + quoteHtml(m[2]) + '</a>' + m[6];
}).join(";");
} else if(key.match(/^wikidata(:|$)/)) {
return value.split(";").map((it) => {
const m = it.match(/^(\s*)(.*?)(\s*)$/)!;
return m[1] + '<a href="https://www.wikidata.org/wiki/' + quoteHtml(m[2]) + '" target="_blank">' + quoteHtml(m[2]) + '</a>' + m[3];
}).join(";");
} else if(key.match(/^wiki:symbol(:$)/)) {
return value.split(";").map(function(it) {
var m = it.match(/^(\s*)(.*?)(\s*)$/)!;
return m[1] + '<a href="https://wiki.openstreetmap.org/wiki/Image:' + quoteHtml(m[2]) + '" target="_blank">' + quoteHtml(m[2]) + '</a>' + m[3];
}).join(";");
} else {
2021-03-19 21:16:57 +00:00
return linkifyStr(value, {
2023-09-12 11:31:55 +00:00
target: (href: string, type: string) => type === "url" ? "_blank" : ""
2021-03-19 21:16:57 +00:00
});
2021-03-13 09:43:32 +00:00
}
}