Commit af2b20d7 authored by Isabella Skořepová's avatar Isabella Skořepová

Clean up in markdown.js and some unit tests

1. More robust href parameter parsing
2. Split youtube-related code (except html) to separate file
3. Unit tests for 1 and 2
4. Heading "Hello - world" now generates "hello-world" anchor instead of
   "hello---world" (no more duplicated hyphens in urls)
parent 2b3f1677
......@@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- sitegin/test/ --recursive -R spec -u exports -t 60000"
"test": "./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- sitegin/tests/ --recursive -R spec -u exports -t 60000"
},
"author": "",
"license": "UNSPECIFIED",
......
......@@ -8,6 +8,7 @@ var renderer = new marked.Renderer();
var highlightjs = require('highlight.js');
var path = require('path');
var jobs = require('./jobs');
var youtube = require('./utils/youtube.js');
var toURL = function(url) {
return jobs.run('toURL', url);
......@@ -30,49 +31,68 @@ renderer.paragraph = function(text) {
else return '<p>'+text+'</p>\n';
}
var renderImage = function(href, title, text, curFilename) {
var parseParams = function(params) {
for(let param of params.split(',')) {
param = param.trim();
// 123x or x123 or 123x123
if(param.match(/[0-9]*x[0-9]+/) || param.match(/[0-9]+x[0-9]*/)) {
options.size = param.split('x');
if(options.size !== undefined) {
if(options.size[0].length > 0) {
options.width = options.size[0];
}
if(options.size.length > 1 && options.size[1].length > 0) {
options.height = options.size[1];
}
}
} else if(param == 'nolightbox') {
options.nolightbox = true;
var paramInHrefParser = function(href) {
var sepIndex = href.indexOf(' =');
var ret = {
href: href,
options: {}
}
if(sepIndex < 0) {
return ret;
} else {
ret.href = href.substr(0, sepIndex);
var options = href.substr(sepIndex+2);
options = options // split by ',' but not '\,'
.replace('a,','\u0007')
.split(',')
.map(function(e) {return e.replace('\u0007','a,')});
options.forEach(function(option) {
var index = option.indexOf('=');
if(index < 0) {
ret.options[option] = true;
} else {
var key = option.substr(0,index);
var value = option.substr(index+1);
ret.options[key] = value;
}
}
});
return ret;
}
}
href = href.split(path.sep).join('/');
href = href.split(' =');
var params = href[1];
var options = {};
var renderYoutube = function(href, options) {
var info = youtube.info(href);
let out = '<div class="video-container"><div class="videodiv">';
out += '<iframe src="https://www.youtube.com/embed/'+info.videoid+
'?modestbranding&start='+info.time+'" frameborder="0" allowfullscreen></iframe>'
out += '</div></div>'
if(params) {
parseParams(params);
}
href = href[0];
if(href.match('//(www.)?youtube.com/watch') || href.match('//youtu.be/')) {
var id;
if(href.match('//youtube.com/watch')) {
id = href.substr(href.indexOf('v=')+2).split('&')[0];
} else {
id = href.substr(href.indexOf('.be/')+4).split('?')[0];
}
return out;
}
let out = '<div class="video-container"><div class="videodiv">';
out += '<iframe src="https://www.youtube.com/embed/'+id+'" frameborder="0" allowfullscreen></iframe>'
out += '</div></div>'
var renderImage = function(href, title, text, curFilename) {
var parsed = paramInHrefParser(href);
href = parsed.href;
var options = parsed.options;
for(let option in options) {
if( !options.hasOwnProperty(option) ) continue;
if(option.match(/x[0-9]+/) || option.match(/[0-9]+x[0-9]*/)) { // 123x or x123 or 123x123
options.size = option.split('x');
if(options.size !== undefined) {
if(options.size[0].length > 0) {
options.width = options.size[0];
}
if(options.size.length > 1 && options.size[1].length > 0) {
options.height = options.size[1];
}
}
}
}
return out;
if(youtube.isVideo(href)) {
return renderYoutube(href, options);
} else {
var rel = path.relative(process.cwd(),path.resolve(curFilename,href));
......@@ -147,3 +167,9 @@ module.exports = function(obj) {
});
return Promise.resolve(obj);
}
module.exports._test = {
renderImage: renderImage,
paramInHrefParser: paramInHrefParser,
renderYoutube: renderYoutube
};
require('should');
var o = require('../markdown')._test;
describe('Markdown', function() {
it('paramInHrefParser image.png =option,option2=123', function() {
o.paramInHrefParser('image.png =option,option2=123').should.be.eql({
href: 'image.png',
options: {
option: true,
option2: '123'
}
})
})
})
'use strict';
/*jshint expr: true*/
require('should');
var youtube = require('../utils/youtube.js');
describe('Youtube', function() {
let links = {
'https://www.youtube.com/watch?v=QH2-TGUlwu4': true,
'http://www.youtube.com/watch?v=QH2-TGUlwu4': true,
'https://youtu.be/QH2-TGUlwu4': true,
'https://youtu.be/QH2-TGUlwu4?t=3m30s': true,
'https://www.youtube.com/watch?t=3m30s&v=QH2-TGUlwu4': true,
'https://www.youtube.cz/watch?t=3m30s&v=QH2-TGUlwu4': true,
'https://www.youtube.com/watch?app=desktop&gl=CZ&v=QH2-TGUlwu4&hl=cs&v=cTa1Q2mBeJE': true,
'https://www.youtube.com/': false,
'https://www.youtube.com/channel/UCzNxmbk_LA1jXvYgivCCkpw': false,
'youtube.png': false
}
function testLink(link, val) {
it('isVideo '+link+' => '+val,function() {
youtube.isVideo(link).should.be.equal(val);
})
}
for(let link in links) {
if(!links.hasOwnProperty(link)) continue;
testLink(link, links[link]);
}
it('info https://youtu.be/wZZ7oFKsKzY?t=3h30m30s', function() {
var info = youtube.info('https://youtu.be/wZZ7oFKsKzY?t=3h30m30s');
info.should.be.object;
info.time.should.be.eql(3*3600+30*60+30);
info.videoid.should.be.eql('wZZ7oFKsKzY');
})
it('info https://youtu.be/QH2-TGUlwu4', function() {
var info = youtube.info('https://youtu.be/QH2-TGUlwu4');
info.should.be.object;
info.time.should.be.eql(0);
info.videoid.should.be.eql('QH2-TGUlwu4');
})
it('info https://www.youtube.com/watch?t=3m30s&v=QH2-TGUlwu4', function() {
var info = youtube.info('https://www.youtube.com/watch?t=3m30s&v=QH2-TGUlwu4');
info.should.be.object;
info.time.should.be.eql(3*60+30);
info.videoid.should.be.eql('QH2-TGUlwu4');
})
})
......@@ -7,5 +7,5 @@ var latinise = function(l){return l.replace(/[^A-Za-z0-9\[\] ]/g,function(a){ret
module.exports = function(tag) {
if(tag === undefined) return undefined;
return latinise(tag.toLowerCase()).replace(/ /g,'-');
return latinise(tag.toLowerCase()).replace(/ /g,'-').replace(/-+/g,'-');
}
'use strict';
var url = require('url');
var querystring = require('querystring');
module.exports.isVideo = function(href) {
var o = url.parse(href);
if(!o.host) return false;
if(o.host == 'youtu.be') {
return o.pathname.length > 1;
}
// not youtube link
if(!o.host.match('youtube.[a-zA-Z]+$')) return false;
var query = querystring.parse(o.query);
// not youtube video
if(!query.v) return false;
return true;
}
module.exports.info = function(href) {
href = url.parse(href);
var query = querystring.parse(href.query);
var info = {
videoid: false,
time: 0
}
if(href.host == 'youtu.be') {
if(href.pathname.length < 2) throw new Error(href+' is not video link');
info.videoid = href.pathname.substr(1);
} else if(href.host.match('youtube.[a-zA-Z]+$')) {
if(Array.isArray(query.v))
info.videoid = query.v[0];
else
info.videoid = query.v;
} else {
throw new Error(href+' is not youtube url');
}
if(query.t) {
var units = query.t.split(/[0-9]+/);
units.splice(0,1);
var values = query.t.split(/[^0-9]/);
values.splice(-1,1);
if(units.length != values.length) throw new Error('Youtube: Wrong time specifier: '+query.t);
for(let i = 0; i < units.length; i++) {
if(units[i] == 'h') info.time += Number(values[i])*3600;
else if(units[i] == 'm') info.time += Number(values[i])*60;
else if(units[i] == 's') info.time += Number(values[i]);
else throw new Error('Youtube: Wrong time specifier: '+query.t);
}
}
return info;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment