import m from 'mithril' import render from './lib/mithril-node-render' import fetch from './fetch' import { tidyOptions, youtubeKey } from './constants' import isNode from 'detect-node' let tidy if (!isNode) { tidy = require('exports?tidy_html5!tidy-html5') } else { tidy = require('tidy-html5').tidy_html5 } export function cleanMarkup (html) { if (!html) { return Promise.resolve('') } return new Promise((resolve, reject) => { // fix center tags html = html.replace(/
/g, '

') html = html.replace(/<\/center>/g, '

') // replace HTML non-breaking spaces with normal spaces html = html.replace(/ /g, ' ') html = fixParagraphIndent(html) html = fixDoubleSpacing(html) // Fix links pointing to pages on fimfiction // Example: djazz let matchLink = /()/g html = html.replace(matchLink, (match, head, url, tail) => { if (url.substring(0, 1) !== '#' && url.substring(0, 2) !== '//' && url.substring(0, 4) !== 'http') { if (url.substring(0, 1) === '/') { url = 'http://www.fimfiction.net' + url } else { // do something else } } return head + url + tail }) let cache = new Map() let completeCount = 0 function getYoutubeInfo (ids) { fetch('https://www.googleapis.com/youtube/v3/videos?id=' + ids + '&part=snippet&maxResults=50&key=' + youtubeKey).then((raw) => { let data try { data = JSON.parse(raw).items } catch (e) { } data.forEach((video) => { cache.set(video.id, video.snippet) completeCount++ }) if (completeCount === cache.size) { continueParsing() } }) } let matchYoutube = /
(.+?)<\/div>/g for (let ma; (ma = matchYoutube.exec(html));) { let youtubeId = ma[1].match(/src="https:\/\/www.youtube.com\/embed\/(.+?)"/)[1] cache.set(youtubeId, null) } if (cache.size === 0) { continueParsing() } else { getYoutubeInfo([...cache.keys()]) } function continueParsing () { html = html.replace(matchYoutube, (match, contents) => { // console.log(match, contents) let youtubeId = contents.match(/src="https:\/\/www.youtube.com\/embed\/(.+?)"/)[1] let thumbnail = 'http://img.youtube.com/vi/' + youtubeId + '/hqdefault.jpg' let youtubeUrl = 'https://youtube.com/watch?v=' + youtubeId let title = 'Youtube Video' let caption = '' let data = cache.get(youtubeId) if (data) { thumbnail = (data.thumbnails.standard || data.thumbnails.high || data.thumbnails.medium || data.thumbnails.default).url title = data.title caption = data.title + ' on YouTube' } return render(m('figure.youtube', [ m('a', {href: youtubeUrl}, m('img', {src: thumbnail, alt: title}) ), m('figcaption', m('a', {href: youtubeUrl}, caption)) ])) }) html = html.replace('
', '
') html = html.replace('
', '
') html = tidy(html, tidyOptions).trim() resolve(html) } }) } export function fixDoubleSpacing (html) { // from FimFictionConverter by Nyerguds html = html.replace(/\s\s+/g, ' ') // push spaces to the closed side of tags html = html.replace(/\s+(<[a-z][^>]*>)\s+/g, ' $1') html = html.replace(/\s+(<\/[a-z][^>]*>)\s+/g, '$1 ') return html } export function fixParagraphIndent (html) { // from FimFictionConverter by Nyerguds let fixIndent = 2 if (fixIndent > 0) { // only trigger indenting when finding as many whitespace characters in a row as indicated by the FixIndent setting. // Add indented class, with the search keeping into account that there could be opening tags behind the p tag. html = html.replace(new RegExp('

((<([^>]+)>)*)\\s{' + fixIndent + '}\\s*', 'g'), '

$1') html = html.replace(new RegExp('

((<([^>]+)>)*)\\s{' + fixIndent + '}\\s*', 'g'), '

$3') // Cleanup of remaining start whitespace in already indented paragraphs: html = html.replace(/]*)>((<[^>]+>)*)\\s+/g, '$2') } return html }