From bcb4c8df9af560cfa38d59d68a1fc0c85a91463b Mon Sep 17 00:00:00 2001 From: neocotic Date: Thu, 15 Aug 2013 13:15:45 +0000 Subject: [PATCH] roll v3.0.0 --- CHANGES.md | 16 +++++++++---- LICENSE.md | 2 +- dist/md.min.js | 4 ++-- docs/command.html | 10 ++++---- docs/md.html | 60 ++++++++++++++++++++++------------------------- man/html-md.1 | 2 +- 6 files changed, 48 insertions(+), 46 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1705528..eb50862 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,14 @@ -2013.05.06, Version 2.1.1 +## Version 3.0.0, 2013.08.15 + +* [#30](https://github.com/neocotic/html.md/issues/30): Rename command from `md` to `html-md` +* [#31](https://github.com/neocotic/html.md/issues/31): Correct expectations of void elements +* Update versions of dependencies + +## Version 2.1.1, 2013.05.06 * [#24](https://github.com/neocotic/html.md/issues/24): Add `base` option to specify the base URL used to resolve relative URLs -2013.05.03, Version 2.1.0 +## Version 2.1.0, 2013.05.03 * [#18](https://github.com/neocotic/html.md/issues/18): Add support for [bower][] installations * [#20](https://github.com/neocotic/html.md/issues/20): Replace `Cakefile` with new [grunt][] build process @@ -19,16 +25,16 @@ * Replace [optparse][] with [commander][] * Lots of bug fixes and optimizations -2013.02.04, Version 2.0.2 +## Version 2.0.2, 2013.02.04 * [#13](https://github.com/neocotic/html.md/issues/13): Add new man page * [#14](https://github.com/neocotic/html.md/issues/14): Fix bug with `eval` option -2012.12.12, Version 2.0.1 +## Version 2.0.1, 2012.12.12 * [#8](https://github.com/neocotic/html.md/issues/8): Fix incorrect version -2012.12.11, Version 2.0.0 +## Version 2.0.0, 2012.12.11 * [#1](https://github.com/neocotic/html.md/issues/1): Check inline style attribute to see if elements are hidden * [#2](https://github.com/neocotic/html.md/issues/2): Add command line interface diff --git a/LICENSE.md b/LICENSE.md index b784b41..8be6e40 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (C) 2013 Alasdair Mercer, http://neocotic.com/ +Copyright (C) 2013 Alasdair Mercer, http://neocotic.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/dist/md.min.js b/dist/md.min.js index b6242c6..e2b7ef8 100644 --- a/dist/md.min.js +++ b/dist/md.min.js @@ -1,3 +1,3 @@ -/*! html-md v2.1.1 | (c) 2013 Alasdair Mercer | MIT License +/*! html-md v3.0.0 | (c) 2013 Alasdair Mercer | MIT License Make.text v1.5 | (c) 2007 Trevor Jim -*/ (function(){var t,e,i,s,n,r,o,h,a,u,p,l,c,d,f={}.hasOwnProperty,E=this;t={absolute:!1,base:"undefined"!=typeof window&&null!==window?window.document.baseURI:"file://"+process.cwd(),debug:!1,inline:!1},i=this.md,n={"\\\\":"\\\\","\\[":"\\[","\\]":"\\]",">":"\\>",_:"\\_","\\*":"\\*","`":"\\`","#":"\\#","([0-9])\\.(\\s|$)":"$1\\.$2","©":"(c)","®":"(r)","™":"(tm)"," ":" ","·":"\\*"," ":" "," ":" "," ":" ","‘":"'","’":"'","“":'"',"”":'"',"…":"...","–":"--","—":"---"},r=/(display|visibility)\s*:\s*[a-z]+/gi,o=/(none|hidden)\s*$/i,h=/^(APPLET|AREA|AUDIO|BUTTON|CANVAS|COMMAND|DATALIST|EMBED|HEAD|INPUT|KEYGEN|MAP|MENU|METER|NOFRAMES|NOSCRIPT|OBJECT|OPTGROUP|OPTION|PARAM|PROGRESS|RP|RT|RUBY|SCRIPT|SELECT|SOURCE|STYLE|TEXTAREA|TITLE|TRACK|VIDEO)$/,a=/^(ADDRESS|ARTICLE|ASIDE|DIV|FIELDSET|FOOTER|HEADER|NAV|P|SECTION)$/,s=function(){c={};for(u in n)f.call(n,u)&&(c[u]=RegExp(u,"g"));return c}(),l=function(t,e,i){var s,n;if(null==t&&(t=""),null==e&&(e=0),null==i&&(i=" "),!i)return t;for(s=n=0;e>=0?e>n:n>e;s=e>=0?++n:--n)t=i+t;return t},d=function(t){return null==t&&(t=""),t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},e=function(){function e(e,i){var s,n;this.html=null!=e?e:"",this.options=null!=i?i:{},this.atLeft=this.atNoWS=this.atP=!0,this.buffer="",this.exceptions=[],this.order=1,this.listDepth=0,this.inCode=this.inPre=this.inOrderedList=!1,this.last=null,this.left="\n",this.links=[],this.linkMap={},this.unhandled={},"object"!=typeof this.options&&(this.options={});for(u in t)f.call(t,u)&&(s=t[u],this.options[u]===void 0&&(this.options[u]=s));this.win="undefined"!=typeof window&&null!==window?window:null,null==this.win&&(n=require("jsdom").jsdom(null,null,{features:{FetchExternalResources:!1},url:this.options.base}),this.win=n.createWindow())}return e.prototype.append=function(t){return null!=this.last&&(this.buffer+=this.last),this.last=t},e.prototype.attr=function(t,e,i){var s;return null==i&&(i=!0),s=i||"function"!=typeof t.getAttribute?t[e]:t.getAttribute(e),null!=s?s:""},e.prototype.br=function(){return this.append(" "+this.left),this.atLeft=this.atNoWS=!0},e.prototype.code=function(){var t,e=this;return t=this.inCode,this.inCode=!0,function(){return e.inCode=t}},e.prototype.has=function(t,e,i){return null==i&&(i=!0),i||"function"!=typeof t.hasAttribute?t.hasOwnProperty(e):t.hasAttribute(e)},e.prototype.inCodeProcess=function(t){return t.replace(/`/g,"\\`")},e.prototype.isVisible=function(t){var e,i,s,n,h,a,u,p,l;if(h=this.attr(t,"style",!1),s=null!=h?h.match(r):void 0,u=!0,null!=s)for(p=0,l=s.length;l>p;p++)n=s[p],u=!o.test(n);if(u&&"function"==typeof this.win.getComputedStyle)try{h=this.win.getComputedStyle(t,null),"function"==typeof(null!=h?h.getPropertyValue:void 0)&&(e=h.getPropertyValue("display"),a=h.getPropertyValue("visibility"),u="none"!==e&&"hidden"!==a)}catch(c){i=c,this.thrown(i,"getComputedStyle")}return u},e.prototype.li=function(){var t;return t=this.inOrderedList?""+this.order++ +". ":"* ",t=l(t,2*(this.listDepth-1)),this.append(t)},e.prototype.nonPreProcess=function(t){var e;t=t.replace(/\n([ \t]*\n)+/g,"\n"),t=t.replace(/\n[ \t]+/g,"\n"),t=t.replace(/[ \t]+/g," ");for(u in n)f.call(n,u)&&(e=n[u],t=t.replace(s[u],e));return t},e.prototype.ol=function(){var t,e,i=this;return 0===this.listDepth&&this.p(),t=this.inOrderedList,e=this.order,this.inOrderedList=!0,this.order=1,this.listDepth++,function(){return i.inOrderedList=t,i.order=e,i.listDepth--}},e.prototype.output=function(t){return t&&(this.inPre||(t=this.atNoWS?t.replace(/^[ \t\n]+/,""):/^[ \t]*\n/.test(t)?t.replace(/^[ \t\n]+/,"\n"):t.replace(/^[ \t]+/," ")),""!==t)?(this.atP=/\n\n$/.test(t),this.atLeft=/\n$/.test(t),this.atNoWS=/[ \t\n]$/.test(t),this.append(t.replace(/\n/g,this.left))):void 0},e.prototype.outputLater=function(t){var e=this;return function(){return e.output(t)}},e.prototype.p=function(){return this.atP?void 0:(this.atLeft||(this.append(this.left),this.atLeft=!0),this.append(this.left),this.atNoWS=this.atP=!0)},e.prototype.parse=function(){var t,e,i,s,n,r,o,h;if(this.buffer="",!this.html)return this.buffer;if(t=this.win.document.createElement("div"),"string"==typeof this.html?t.innerHTML=this.html:t.appendChild(this.html),this.process(t),this.links.length)for(this.append("\n\n"),h=this.links,e=r=0,o=h.length;o>r;e=++r)i=h[e],i&&this.append("["+e+"]: "+i+"\n");return this.options.debug&&(n=function(){var t,e;t=this.unhandled,e=[];for(s in t)f.call(t,s)&&e.push(s);return e}.call(this).sort(),console.log(n.length?"Ignored tags;\n"+n.join(", "):"No tags were ignored"),console.log(this.exceptions.length?"Exceptions;\n"+this.exceptions.join("\n"):"No exceptions were thrown")),this.append(""),this.buffer=d(this.buffer)},e.prototype.pre=function(){var t,e=this;return t=this.inPre,this.inPre=!0,function(){return e.inPre=t}},e.prototype.process=function(t){var e,i,s,n,r,o,u,p,l,c,d,f,E,y,m,b,g,N,L;if(this.isVisible(t)){if(t.nodeType===this.win.Node.ELEMENT_NODE){l=!1;try{if(h.test(t.tagName))l=!0;else if(/^H[1-6]$/.test(t.tagName))p=parseInt(t.tagName.match(/([1-6])$/)[1]),this.p(),this.output(""+function(){var t,e;for(e=[],u=t=1;p>=1?p>=t:t>=p;u=p>=1?++t:--t)e.push("#");return e}().join("")+" ");else if(a.test(t.tagName))this.p();else switch(t.tagName){case"BODY":case"FORM":break;case"DETAILS":this.p(),this.has(t,"open",!1)||(l=!0,f=t.getElementsByTagName("summary")[0],f&&this.process(f));break;case"BR":this.br();break;case"HR":this.p(),this.output("---"),this.p();break;case"CITE":case"DFN":case"EM":case"I":case"U":case"VAR":this.output("_"),this.atNoWS=!0,e=this.outputLater("_");break;case"DT":case"B":case"STRONG":"DT"===t.tagName&&this.p(),this.output("**"),this.atNoWS=!0,e=this.outputLater("**");break;case"Q":this.output('"'),this.atNoWS=!0,e=this.outputLater('"');break;case"OL":case"UL":e="OL"===t.tagName?this.ol():this.ul();break;case"LI":this.li();break;case"PRE":i=this.pushLeft(" "),s=this.pre(),e=function(){return i(),s()};break;case"CODE":case"KBD":case"SAMP":if(this.inPre)break;this.output("`"),i=this.code(),s=this.outputLater("`"),e=function(){return i(),s()};break;case"BLOCKQUOTE":case"DD":e=this.pushLeft("> ");break;case"A":if(o=this.attr(t,"href",this.options.absolute),!o)break;E=this.attr(t,"title"),E&&(o+=' "'+E+'"'),d=this.options.inline?"("+o+")":"["+(null!=(g=(y=this.linkMap)[o])?g:y[o]=this.links.push(o)-1)+"]",this.output("["),this.atNoWS=!0,e=this.outputLater("]"+d);break;case"IMG":if(l=!0,c=this.attr(t,"src",this.options.absolute),!c)break;this.output("!["+this.attr(t,"alt")+"]("+c+")");break;case"FRAME":case"IFRAME":l=!0;try{(null!=(N=t.contentDocument)?N.documentElement:void 0)&&this.process(t.contentDocument.documentElement)}catch(P){r=P,this.thrown(r,"contentDocument")}break;case"TR":e=this.p;break;default:this.options.debug&&(this.unhandled[t.tagName]=null)}}catch(P){r=P,this.thrown(r,t.tagName)}if(!l)for(L=t.childNodes,m=0,b=L.length;b>m;m++)n=L[m],this.process(n);return null!=e?e.call(this):void 0}return t.nodeType===this.win.Node.TEXT_NODE?this.output(this.inPre?t.nodeValue:this.inCode?this.inCodeProcess(t.nodeValue):this.nonPreProcess(t.nodeValue)):void 0}},e.prototype.pushLeft=function(t){var e,i=this;return e=this.left,this.left+=t,this.atP?this.append(t):this.p(),function(){return i.left=e,i.atLeft=i.atP=!1,i.p()}},e.prototype.replaceLeft=function(t){return this.atLeft?this.last?this.last=this.last.replace(/[ ]{2,4}$/,t):void 0:(this.append(this.left.replace(/[ ]{2,4}$/,t)),this.atLeft=this.atNoWS=this.atP=!0)},e.prototype.thrown=function(t,e){return this.options.debug?this.exceptions.push(""+e+": "+t):void 0},e.prototype.ul=function(){var t,e,i=this;return 0===this.listDepth&&this.p(),t=this.inOrderedList,e=this.order,this.inOrderedList=!1,this.order=1,this.listDepth++,function(){return i.inOrderedList=t,i.order=e,i.listDepth--}},e}(),this.md=p=function(t,i){return new e(t,i).parse()},("undefined"!=typeof module&&null!==module?module.exports:void 0)?module.exports=p:"function"==typeof define&&define.amd&&define("md",function(){return p}),p.version=p.VERSION="2.1.1",p.noConflict=function(){return E.md=i,p}}).call(this); \ No newline at end of file +*/ !function(){var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o={}.hasOwnProperty,p=this;a={absolute:!1,base:"undefined"!=typeof window&&null!==window?window.document.baseURI:"file://"+process.cwd(),debug:!1,inline:!1},c=this.md,e={"\\\\":"\\\\","\\[":"\\[","\\]":"\\]",">":"\\>",_:"\\_","\\*":"\\*","`":"\\`","#":"\\#","([0-9])\\.(\\s|$)":"$1\\.$2","©":"(c)","®":"(r)","™":"(tm)"," ":" ","·":"\\*"," ":" "," ":" "," ":" ","‘":"'","’":"'","“":'"',"”":'"',"…":"...","–":"--","—":"---"},f=/(display|visibility)\s*:\s*[a-z]+/gi,g=/(none|hidden)\s*$/i,h=/^(APPLET|AREA|AUDIO|BUTTON|CANVAS|DATALIST|EMBED|HEAD|INPUT|MAP|MENU|METER|NOFRAMES|NOSCRIPT|OBJECT|OPTGROUP|OPTION|PARAM|PROGRESS|RP|RT|RUBY|SCRIPT|SELECT|STYLE|TEXTAREA|TITLE|VIDEO)$/,i=/^(ADDRESS|ARTICLE|ASIDE|DIV|FIELDSET|FOOTER|HEADER|NAV|P|SECTION)$/,d=function(){m={};for(j in e)o.call(e,j)&&(m[j]=new RegExp(j,"g"));return m}(),l=function(a,b,c){var d,e;if(null==a&&(a=""),null==b&&(b=0),null==c&&(c=" "),!c)return a;for(d=e=0;b>=0?b>e:e>b;d=b>=0?++e:--e)a=c+a;return a},n=function(a){return null==a&&(a=""),a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},b=function(){function b(b,c){var d,e;this.html=null!=b?b:"",this.options=null!=c?c:{},this.atLeft=this.atNoWS=this.atP=!0,this.buffer="",this.exceptions=[],this.order=1,this.listDepth=0,this.inCode=this.inPre=this.inOrderedList=!1,this.last=null,this.left="\n",this.links=[],this.linkMap={},this.unhandled={},"object"!=typeof this.options&&(this.options={});for(j in a)o.call(a,j)&&(d=a[j],"undefined"==typeof this.options[j]&&(this.options[j]=d));this.win="undefined"!=typeof window&&null!==window?window:null,null==this.win&&(e=require("jsdom").jsdom(null,null,{features:{FetchExternalResources:!1},url:this.options.base}),this.win=e.createWindow())}return b.prototype.append=function(a){return null!=this.last&&(this.buffer+=this.last),this.last=a},b.prototype.attr=function(a,b,c){var d;return null==c&&(c=!0),d=c||"function"!=typeof a.getAttribute?a[b]:a.getAttribute(b),null!=d?d:""},b.prototype.br=function(){return this.append(" "+this.left),this.atLeft=this.atNoWS=!0},b.prototype.code=function(){var a,b=this;return a=this.inCode,this.inCode=!0,function(){return b.inCode=a}},b.prototype.has=function(a,b,c){return null==c&&(c=!0),c||"function"!=typeof a.hasAttribute?a.hasOwnProperty(b):a.hasAttribute(b)},b.prototype.inCodeProcess=function(a){return a.replace(/`/g,"\\`")},b.prototype.isVisible=function(a){var b,c,d,e,h,i,j,k,l;if(h=this.attr(a,"style",!1),d=null!=h?h.match(f):void 0,j=!0,null!=d)for(k=0,l=d.length;l>k;k++)e=d[k],j=!g.test(e);if(j&&"function"==typeof this.win.getComputedStyle)try{h=this.win.getComputedStyle(a,null),"function"==typeof(null!=h?h.getPropertyValue:void 0)&&(b=h.getPropertyValue("display"),i=h.getPropertyValue("visibility"),j="none"!==b&&"hidden"!==i)}catch(m){c=m,this.thrown(c,"getComputedStyle")}return j},b.prototype.li=function(){var a;return a=this.inOrderedList?""+this.order++ +". ":"* ",a=l(a,2*(this.listDepth-1)),this.append(a)},b.prototype.nonPreProcess=function(a){var b;a=a.replace(/\n([ \t]*\n)+/g,"\n"),a=a.replace(/\n[ \t]+/g,"\n"),a=a.replace(/[ \t]+/g," ");for(j in e)o.call(e,j)&&(b=e[j],a=a.replace(d[j],b));return a},b.prototype.ol=function(){var a,b,c=this;return 0===this.listDepth&&this.p(),a=this.inOrderedList,b=this.order,this.inOrderedList=!0,this.order=1,this.listDepth++,function(){return c.inOrderedList=a,c.order=b,c.listDepth--}},b.prototype.output=function(a){return a&&(this.inPre||(a=this.atNoWS?a.replace(/^[ \t\n]+/,""):/^[ \t]*\n/.test(a)?a.replace(/^[ \t\n]+/,"\n"):a.replace(/^[ \t]+/," ")),""!==a)?(this.atP=/\n\n$/.test(a),this.atLeft=/\n$/.test(a),this.atNoWS=/[ \t\n]$/.test(a),this.append(a.replace(/\n/g,this.left))):void 0},b.prototype.outputLater=function(a){var b=this;return function(){return b.output(a)}},b.prototype.p=function(){return this.atP?void 0:(this.atLeft||(this.append(this.left),this.atLeft=!0),this.append(this.left),this.atNoWS=this.atP=!0)},b.prototype.parse=function(){var a,b,c,d,e,f,g,h;if(this.buffer="",!this.html)return this.buffer;if(a=this.win.document.createElement("div"),"string"==typeof this.html?a.innerHTML=this.html:a.appendChild(this.html),this.process(a),this.links.length)for(this.append("\n\n"),h=this.links,b=f=0,g=h.length;g>f;b=++f)c=h[b],c&&this.append("["+b+"]: "+c+"\n");return this.options.debug&&(e=function(){var a,b;a=this.unhandled,b=[];for(d in a)o.call(a,d)&&b.push(d);return b}.call(this).sort(),console.log(e.length?"Ignored tags;\n"+e.join(", "):"No tags were ignored"),console.log(this.exceptions.length?"Exceptions;\n"+this.exceptions.join("\n"):"No exceptions were thrown")),this.append(""),this.buffer=n(this.buffer)},b.prototype.pre=function(){var a,b=this;return a=this.inPre,this.inPre=!0,function(){return b.inPre=a}},b.prototype.process=function(a){var b,c,d,e,f,g,j,k,l,m,n,o,p,q,r,s,t,u,v;if(this.isVisible(a)){if(a.nodeType===this.win.Node.ELEMENT_NODE){l=!1;try{if(h.test(a.tagName))l=!0;else if(/^H[1-6]$/.test(a.tagName))k=parseInt(a.tagName.match(/([1-6])$/)[1]),this.p(),this.output(""+function(){var a,b;for(b=[],j=a=1;k>=1?k>=a:a>=k;j=k>=1?++a:--a)b.push("#");return b}().join("")+" ");else if(i.test(a.tagName))this.p();else switch(a.tagName){case"BODY":case"FORM":break;case"DETAILS":this.p(),this.has(a,"open",!1)||(l=!0,o=a.getElementsByTagName("summary")[0],o&&this.process(o));break;case"BR":this.br();break;case"HR":this.p(),this.output("---"),this.p();break;case"CITE":case"DFN":case"EM":case"I":case"U":case"VAR":this.output("_"),this.atNoWS=!0,b=this.outputLater("_");break;case"DT":case"B":case"STRONG":"DT"===a.tagName&&this.p(),this.output("**"),this.atNoWS=!0,b=this.outputLater("**");break;case"Q":this.output('"'),this.atNoWS=!0,b=this.outputLater('"');break;case"OL":case"UL":b="OL"===a.tagName?this.ol():this.ul();break;case"LI":this.li();break;case"PRE":c=this.pushLeft(" "),d=this.pre(),b=function(){return c(),d()};break;case"CODE":case"KBD":case"SAMP":if(this.inPre)break;this.output("`"),c=this.code(),d=this.outputLater("`"),b=function(){return c(),d()};break;case"BLOCKQUOTE":case"DD":b=this.pushLeft("> ");break;case"A":if(g=this.attr(a,"href",this.options.absolute),!g)break;p=this.attr(a,"title"),p&&(g+=' "'+p+'"'),n=this.options.inline?"("+g+")":"["+(null!=(t=(q=this.linkMap)[g])?t:q[g]=this.links.push(g)-1)+"]",this.output("["),this.atNoWS=!0,b=this.outputLater("]"+n);break;case"IMG":if(l=!0,m=this.attr(a,"src",this.options.absolute),!m)break;this.output("!["+this.attr(a,"alt")+"]("+m+")");break;case"FRAME":case"IFRAME":l=!0;try{(null!=(u=a.contentDocument)?u.documentElement:void 0)&&this.process(a.contentDocument.documentElement)}catch(w){f=w,this.thrown(f,"contentDocument")}break;case"TR":b=this.p;break;default:this.options.debug&&(this.unhandled[a.tagName]=null)}}catch(w){f=w,this.thrown(f,a.tagName)}if(!l)for(v=a.childNodes,r=0,s=v.length;s>r;r++)e=v[r],this.process(e);return null!=b?b.call(this):void 0}return a.nodeType===this.win.Node.TEXT_NODE?this.output(this.inPre?a.nodeValue:this.inCode?this.inCodeProcess(a.nodeValue):this.nonPreProcess(a.nodeValue)):void 0}},b.prototype.pushLeft=function(a){var b,c=this;return b=this.left,this.left+=a,this.atP?this.append(a):this.p(),function(){return c.left=b,c.atLeft=c.atP=!1,c.p()}},b.prototype.replaceLeft=function(a){return this.atLeft?this.last?this.last=this.last.replace(/[ ]{2,4}$/,a):void 0:(this.append(this.left.replace(/[ ]{2,4}$/,a)),this.atLeft=this.atNoWS=this.atP=!0)},b.prototype.thrown=function(a,b){return this.options.debug?this.exceptions.push(""+b+": "+a):void 0},b.prototype.ul=function(){var a,b,c=this;return 0===this.listDepth&&this.p(),a=this.inOrderedList,b=this.order,this.inOrderedList=!1,this.order=1,this.listDepth++,function(){return c.inOrderedList=a,c.order=b,c.listDepth--}},b}(),this.md=k=function(a,c){return new b(a,c).parse()},("undefined"!=typeof module&&null!==module?module.exports:void 0)?module.exports=k:"function"==typeof define&&define.amd&&define("md",function(){return k}),k.version=k.VERSION="3.0.0",k.noConflict=function(){return p.md=c,k}}.call(this); \ No newline at end of file diff --git a/docs/command.html b/docs/command.html index 21778e5..f23e0dc 100644 --- a/docs/command.html +++ b/docs/command.html @@ -48,9 +48,9 @@ the print option was enabled.

    if program.print then console.log output
     else if file     then writeMarkdown file, output, root
   catch err

An error occured while parsing input, so stop processing all sources and exit, while also -letting the user know why.

    exit 1, err

Parse the options that could have been provided at runtime.

parseOptions = ->

Parse the specified options/switches/flags/whatever.

  program
+letting the user know why.

    exit 1, err

Parse the options that could have been provided at runtime.

parseOptions = ->

Parse the specified options/switches/flags/whatever.

  program
     .version(md.version)
-    .usage('Usage: md [options] [ -e html | <file ...> ]')
+    .usage('[options] [ -e html | <file ...> ]')
     .option('-a, --absolute',     'always use absolute URLs for links and images')
     .option('-b, --base <url>',   'set base URL to resolve relative URLs from')
     .option('-d, --debug',        'print additional debug information')
@@ -62,14 +62,14 @@
     .parse process.argv

Ensure that the longer Markdown file extension is used if/when the associated option is enabled.

  extension = '.markdown' if program.longExt

All left-over arguments are considered potential HTML source files/input and will be handled as such.

  sources   = program.args[..]

No additional arguments were specified? Then simply print out the usage as the user might not -know how to use this command.

  program.help() unless sources.length

Write the markdown converted from source to its relative output file.

writeMarkdown = (source, markdown, root) ->

Derive the best output file path based on the name of the source file.

  mdPath = outputPath source, root
+know how to use this command.

  program.help() unless sources.length

Write the markdown converted from source to its relative output file.

writeMarkdown = (source, markdown, root) ->

Derive the best output file path based on the name of the source file.

  mdPath = outputPath source, root
   mdDir  = path.dirname mdPath

Write markdown to its corresponding output file.

  write = (err) ->
     throw err if err

Ensure something is always written in the file.

    markdown = ' ' if markdown.length <= 0
     fs.writeFile mdPath, markdown, (err) ->
       throw err if err

If the target files parent directory doesn't already exists, create it before writing to the file itself.

  fs.exists mdDir, (exists) ->
-    if exists then do write else fs.mkdirs mdDir, write

Public API

Handle the runtime arguments accordingly.

exports.run = ->

Try to ensure graceful exits whenever possible.

  unless process.platform is 'win32'
-    process.on 'SIGTERM', ->
+    if exists then do write else fs.mkdirs mdDir, write

Public API

Handle the runtime arguments accordingly.

exports.run = ->

Try to ensure graceful exits whenever possible.

  unless process.platform is 'win32'
+    process.on 'SIGTERM', ->
       do exit
 
   try

Parse the arguments passed in at runtime as options/switches.

    do parseOptions
diff --git a/docs/md.html b/docs/md.html
index f162db4..4936cd7 100644
--- a/docs/md.html
+++ b/docs/md.html
@@ -33,18 +33,16 @@
   '\u2026':            '...'
   '\u2013':            '--'
   '\u2014':            '---'

Regular expression to extract all display and visibility CSS properties from an inline style -attribute.

R_HIDDEN_STYLES   = /(display|visibility)\s*:\s*[a-z]+/gi

Regular expression to check for hidden values of CSS properties.

R_HIDDEN_VALUE    = /(none|hidden)\s*$/i

Regular expression to identify elements to be generally ignored, along with their children.

R_IGNORE_CHILDREN = /// ^ (
+attribute.

R_HIDDEN_STYLES   = /(display|visibility)\s*:\s*[a-z]+/gi

Regular expression to check for hidden values of CSS properties.

R_HIDDEN_VALUE    = /(none|hidden)\s*$/i

Regular expression to identify elements to be generally ignored, along with their children.

R_IGNORE_CHILDREN = /// ^ (
     APPLET
   | AREA
   | AUDIO
   | BUTTON
   | CANVAS
-  | COMMAND
   | DATALIST
   | EMBED
   | HEAD
   | INPUT
-  | KEYGEN
   | MAP
   | MENU
   | METER
@@ -60,13 +58,11 @@
   | RUBY
   | SCRIPT
   | SELECT
-  | SOURCE
   | STYLE
   | TEXTAREA
   | TITLE
-  | TRACK
   | VIDEO
-) $ ///

Regular expression to identify elements to be parsed as simple paragraphs.

R_PARAGRAPH_ONLY  = /// ^ (
+) $ ///

Regular expression to identify elements to be parsed as simple paragraphs.

R_PARAGRAPH_ONLY  = /// ^ (
     ADDRESS
   | ARTICLE
   | ASIDE
@@ -80,10 +76,10 @@
 ) $ ///

Create a map of regular expressions for all of the special Markdown characters to simplify access.

REGEX             = (
   result = {}
-  result[key] = new RegExp key, 'g' for own key of REPLACEMENTS
+  result[key] = new RegExp key, 'g' for own key of REPLACEMENTS
   result
 )

Helper functions

Left pad str with the given padding string for the specified number of times.

padLeft = (str = '', times = 0, padStr = ' ') ->
-  return str unless padStr
+  return str unless padStr
 
   str = padStr + str for i in [0...times]
   str

Remove whitespace from both ends of str.
@@ -101,9 +97,9 @@ @links = [] @linkMap = {} @unhandled = {} - @options = {} if typeof @options isnt 'object'

Copy all default option values across to options only where they were not specified.

    for own key, defaultValue of DEFAULT_OPTIONS
+    @options    = {} if typeof @options isnt 'object'

Copy all default option values across to options only where they were not specified.

    for own key, defaultValue of DEFAULT_OPTIONS
       @options[key] = defaultValue if typeof @options[key] is 'undefined'

Create a DOM if window doesn't exist (i.e. when running in node).

    @win = window ? null
-    unless @win?
+    unless @win?
       doc  = require('jsdom').jsdom null, null,
         features: FetchExternalResources: no
         url:      @options.base
@@ -115,9 +111,9 @@
     else
       ele.getAttribute attribute
 
-    value ? ''

Append a Markdown line break to the buffer string.

  br: ->
+    value ? ''

Append a Markdown line break to the buffer string.

  br: ->
     @append "  #{@left}"
-    @atLeft = @atNoWS = yes

Prepare the parser for a code element.

  code: ->
+    @atLeft = @atNoWS = yes

Prepare the parser for a code element.

  code: ->
     old     = @inCode
     @inCode = yes
 
@@ -142,7 +138,7 @@
       catch err
         @thrown err, 'getComputedStyle'
 
-    visible

Append a Markdown list item based on the context of the current list.

  li: ->
+    visible

Append a Markdown list item based on the context of the current list.

  li: ->
     str = if @inOrderedList then "#{@order++}. " else '* '
     str = padLeft str, (@listDepth - 1) * 2
 
@@ -150,8 +146,8 @@
     str = str.replace /\n([ \t]*\n)+/g, '\n'
     str = str.replace /\n[ \t]+/g,      '\n'
     str = str.replace /[ \t]+/g,        ' '
-    str = str.replace REGEX[key], value for own key, value of REPLACEMENTS
-    str

Prepare the parser for an ol element.

  ol: ->
+    str = str.replace REGEX[key], value for own key, value of REPLACEMENTS
+    str

Prepare the parser for an ol element.

  ol: ->
     do @p if @listDepth is 0
 
     inOrderedList  = @inOrderedList
@@ -164,7 +160,7 @@
       @inOrderedList = inOrderedList
       @order         = order
       @listDepth--

Append str to the buffer string.

  output: (str) ->
-    return unless str

Strip leading whitespace when code blocks accordingly.

    unless @inPre
+    return unless str

Strip leading whitespace when code blocks accordingly.

    unless @inPre
       str = if @atNoWS
         str.replace /^[ \t\n]+/, ''
       else if /^[ \t]*\n/.test str
@@ -178,25 +174,25 @@
     @append str.replace /\n/g, @left

Create a function that can be called later to append str to the buffer string while keeping the parser in context.
This function is just a lazy shorthand.

  outputLater: (str) ->
-    => @output str

Append a Markdown paragraph section to the buffer string.

  p: ->
+    => @output str

Append a Markdown paragraph section to the buffer string.

  p: ->
     return if @atP
 
-    unless @atLeft
+    unless @atLeft
       @append @left
       @atLeft = yes
 
     @append @left
-    @atNoWS = @atP = yes

Parse the configured HTML into valid Markdown.

  parse: ->
+    @atNoWS = @atP = yes

Parse the configured HTML into valid Markdown.

  parse: ->
     @buffer = ''
 
-    return @buffer unless @html

Create a wrapper element to insert the configured HTML into.

    container = @win.document.createElement 'div'
+    return @buffer unless @html

Create a wrapper element to insert the configured HTML into.

    container = @win.document.createElement 'div'
     if typeof @html is 'string'
       container.innerHTML = @html
     else
       container.appendChild @html

Process the contents (i.e. the preconfigured HTML) of the wrapper element.

    @process container

Ensure all link references are correctly appended to be end of the buffer string.

    if @links.length
       @append '\n\n'
       @append "[#{i}]: #{link}\n" for link, i in @links when link

This isn't nice and I wouldn't really recommend users use this option but, when debug is -enabled, output all debug information either to the console (e.g. stdout in node).

    if @options.debug

List any tags that were ignored during processing.

      unhandledTags = (tag for own tag of @unhandled).sort()
+enabled, output all debug information either to the console (e.g. stdout in node).

    if @options.debug

List any tags that were ignored during processing.

      unhandledTags = (tag for own tag of @unhandled).sort()
       console.log if unhandledTags.length
         """
           Ignored tags;
@@ -210,11 +206,11 @@
         """
       else
         'No exceptions were thrown'

End the buffer string cleanly and we're done!

    @append ''
-    @buffer = trim @buffer

Prepare the parser for a pre element.

  pre: ->
+    @buffer = trim @buffer

Prepare the parser for a pre element.

  pre: ->
     old    = @inPre
     @inPre = yes
 
-    => @inPre = old

Parse the specified element and append the generated Markdown to the buffer string.

  process: (ele) ->

Only visible elements are processed. Doing our best to identify those that are hidden.

    return unless @isVisible ele
+    => @inPre = old

Parse the specified element and append the generated Markdown to the buffer string.

  process: (ele) ->

Only visible elements are processed. Doing our best to identify those that are hidden.

    return unless @isVisible ele
 
     if ele.nodeType is @win.Node.ELEMENT_NODE

Handle typical node elements (e.g. <span>foo bar</span>).

      skipChildren = no

Determine the best way (if any) to handle ele.

      try
         if R_IGNORE_CHILDREN.test ele.tagName

Don't process the element or any of its children.

          skipChildren = yes
@@ -228,7 +224,7 @@
 we don't want to process anything other than the first nested summary element.

            when 'DETAILS'
               do @p
 
-              unless @has ele, 'open', no
+              unless @has ele, 'open', no
                 skipChildren = yes
                 summary      = ele.getElementsByTagName('summary')[0]
                 @process summary if summary

Easiest of the bunch... just a Markdown line break.

            when 'BR' then do @br

Insert a horizontal ruler padded on before and after.

            when 'HR'
@@ -254,7 +250,7 @@
               after1 = @pushLeft '    '
               after2 = do @pre
 
-              after  = ->
+              after  = ->
                 do after1
                 do after2

Inline code elements translate pretty easily but we need to make sure we don't do anything dumb inside a pre element.

            when 'CODE', 'KBD', 'SAMP'
@@ -265,14 +261,14 @@
               after1 = do @code
               after2 = @outputLater '`'
 
-              after  = ->
+              after  = ->
                 do after1
                 do after2

Block quotes (and similar elements) are relatively straight forward.

            when 'BLOCKQUOTE', 'DD' then after = @pushLeft '> '

Links on the other hand are probably the trickiest.

            when 'A'

Extract the link URL from ele.
Links with no URLs are treated just like text-containing elements (e.g. span).
a.href always returns an absolute URL while a.getAttribute('href') always returns the exact value of the href attribute. For this reason we need to be sure that we extract the URL correctly based on the state of the absolute option.

              href = @attr ele, 'href', @options.absolute
-              break unless href

Be sure to include the title after each link reference that will be displayed at + break unless href

Be sure to include the title after each link reference that will be displayed at the end of the Markdown output, where possible.

              title  = @attr ele, 'title'
               href  += " \"#{title}\"" if title

Determine what style the link should be generated in (i.e. inline or reference) depending on the state of the inline option.

              suffix = if @options.inline

Inline style means all links have their URLs (and possible titles) included @@ -293,7 +289,7 @@ returns the exact value of the src attribute. For this reason we need to be sure that we extract the URL correctly based on the state of the absolute option.

              skipChildren = yes
               src          = @attr ele, 'src', @options.absolute
-              break unless src
+              break unless src
 
               @output "![#{@attr ele, 'alt'}](#{src})"

Frames are HELL (fact!), but we'll do our best to support their contents.

            when 'FRAME', 'IFRAME'
               skipChildren = yes
@@ -306,7 +302,7 @@
 any children it has.

            else
               @unhandled[ele.tagName] = null if @options.debug
       catch err
-        @thrown err, ele.tagName

Process all child elements of ele if it has any and we've not been told to ignore them.

      @process childNode for childNode in ele.childNodes unless skipChildren

Ensure any callback are invoked being proceeding if they are specified.

      after?.call this
+        @thrown err, ele.tagName

Process all child elements of ele if it has any and we've not been told to ignore them.

      @process childNode for childNode in ele.childNodes unless skipChildren

Ensure any callback are invoked being proceeding if they are specified.

      after?.call this
     else if ele.nodeType is @win.Node.TEXT_NODE

Handle simple text nodes (e.g. "foo bar") according to the current context.

      @output if @inPre
         ele.nodeValue
       else if @inCode
@@ -323,14 +319,14 @@
       @atLeft = @atP = no
 
       do @p

Replace the left indent with str.

  replaceLeft: (str) ->
-    unless @atLeft
+    unless @atLeft
       @append @left.replace /[ ]{2,4}$/, str
 
       @atLeft = @atNoWS = @atP = yes
     else if @last
       @last   = @last.replace /[ ]{2,4}$/, str

Ensure that the exception and the corresponding message is logged if the debug option is enabled.

  thrown: (exception, message) ->
-    @exceptions.push "#{message}: #{exception}" if @options.debug

Prepare the parser for a ul element.

  ul: ->
+    @exceptions.push "#{message}: #{exception}" if @options.debug

Prepare the parser for a ul element.

  ul: ->
     do @p if @listDepth is 0
 
     inOrderedList  = @inOrderedList
@@ -346,7 +342,7 @@
   new HtmlParser(html, options).parse()

Export md for NodeJS and CommonJS.

if module?.exports
   module.exports = md
 else if typeof define is 'function' and define.amd
-  define 'md', -> md

Public constants

Current version of html.md.

md.version = md.VERSION = '2.1.1'

Public functions

Run html.md in noConflict mode, returning the md variable to its previous owner.
+ define 'md', -> md

Public constants

Current version of html.md.

md.version = md.VERSION = '3.0.0'

Public functions

Run html.md in noConflict mode, returning the md variable to its previous owner.
Returns a reference to our md.

md.noConflict = =>
   @md = PREVIOUS_MD
   md
diff --git a/man/html-md.1 b/man/html-md.1
index 7d1eb11..0bfa98a 100644
--- a/man/html-md.1
+++ b/man/html-md.1
@@ -1,4 +1,4 @@
-.TH HTML\-MD 1 "May 2013" "" "General Commands Manual"
+.TH HTML\-MD 1 "August 2013" "" "General Commands Manual"
 
 .SH NAME
 .B html\-md