doc: update style for iojs

* updates the styling for the iojs docs
* pulls the processing step for markdown files into
  a separate module
* adds the ability to insert comments into the markdown

PR-URL: https://github.com/iojs/io.js/pull/297
Fixes: https://github.com/iojs/iojs.github.io/issues/23
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Chris Dickinson 2015-01-11 21:40:45 -08:00
parent 3a85eac4ec
commit 9120f2b1fd
7 changed files with 327 additions and 388 deletions

View File

@ -1,3 +1,5 @@
@// NB(chrisdickinson): if you move this file, be sure to update tools/doc/html.js to
@// point at the new location.
* [About these Docs](documentation.html) * [About these Docs](documentation.html)
* [Synopsis](synopsis.html) * [Synopsis](synopsis.html)
* [Assertion Testing](assert.html) * [Assertion Testing](assert.html)

View File

@ -9,16 +9,17 @@
} }
.sh_sourceCode .sh_keyword { .sh_sourceCode .sh_keyword {
color: #c96; color: #338;
} }
.sh_sourceCode .sh_string, .sh_sourceCode .sh_string,
.sh_sourceCode .sh_regexp, .sh_sourceCode .sh_regexp,
.sh_sourceCode .sh_number, .sh_sourceCode .sh_number,
.sh_sourceCode .sh_specialchar { .sh_sourceCode .sh_specialchar {
color: #690; color: #E54305;
} }
.sh_sourceCode .sh_comment { .sh_sourceCode .sh_comment {
color: #666; color: #666;
font-weight: lighter;
} }

View File

@ -4,91 +4,100 @@ html {
} }
body { body {
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
font-size: 14px; font-size: 62.5%;
line-height: 180%; margin: 0;
color: black; padding: 0;
background-color: white; color: #3a3a3a;
margin: 0; padding: 49px 0 0 0; background: #fcfefa;
border-top: 6px #8CC84B solid; }
#content {
font-size: 1.8em;
} }
a { a {
color: #480; color: #FE5210;
text-decoration: underline; text-decoration: none;
} }
a:visited { a:visited {
color: #46483e; color: #FE7110;
text-decoration: underline;
} }
a:hover, a:hover,
a:focus { a:focus {
text-decoration: none; color: #FFA158;
}
strong {
font-weight: 700;
} }
code a:hover { code a:hover {
background: none; background: none;
color: #b950b7;
} }
#changelog #gtoc { #changelog #gtoc {
display: none; display: none;
} }
#gtoc {
font-size: 0.8em;
}
#gtoc p { #gtoc p {
margin: 0;
font-size: 18px;
line-height: 30px;
} }
#gtoc a { #gtoc a {
font-family: Georgia, FreeSerif, Times, serif;
text-decoration: none;
color: #46483e;
} }
#gtoc a:hover { #gtoc a:hover {
color: #669900;
text-decoration: underline;
} }
.notice { .api_stability_0,
display: block; .api_stability_1,
padding: 1em; .api_stability_2,
margin: 1.4667em 0 2.9334em; .api_stability_3,
background: #FFF6BF; .api_stability_4,
color: #514721; .api_stability_5 {
border: 1px solid #FFD324; color: white !important;
margin: 0em 0 1.0em 0;
font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
font-weight: 700;
} }
.notice p { .api_stability_0 *,
margin: 0; .api_stability_1 *,
.api_stability_2 *,
.api_stability_3 *,
.api_stability_4 *,
.api_stability_5 * {
color: white !important;
} }
.api_stability_0 { .api_stability_0 {
border-color: #D60027; background-color: #D60027;
} }
.api_stability_1 { .api_stability_1 {
border-color: #EC5315; background-color: #EC5315;
} }
.api_stability_2 { .api_stability_2 {
border-color: #FFD700; background-color: #FFA000;
} }
.api_stability_3 { .api_stability_3 {
border-color: #AEC516; background-color: #AEC516;
} }
.api_stability_4 { .api_stability_4 {
border-color: #009431; background-color: #009431;
} }
.api_stability_5 { .api_stability_5 {
border-color: #0084B6; background-color: #0084B6;
} }
ul.plain { ul.plain {
@ -100,14 +109,20 @@ abbr {
} }
p { p {
margin: 0 0 1.4667em 0;
position: relative; position: relative;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
margin: 0 0 1em 0;
line-height: 1.5em;
}
#apicontent > *:last-child {
margin-bottom: 0;
padding-bottom: 2.0em;
} }
table { table {
border-collapse: collapse; border-collapse: collapse;
margin: 0 0 1.4667em 0; margin: 0 0 1.5em 0;
} }
th, td { th, td {
@ -115,23 +130,14 @@ th, td {
} }
table p { table p {
margin: 0 1ex;
} }
th { th {
text-align:left; text-align:left;
} }
.apidoc #apicontent p,
.apidoc #apicontent li {
font-size: 15px;
line-height: 22px;
color: #000;
font-family: Georgia, FreeSerif, Times, serif;
}
ol, ul, dl { ol, ul, dl {
margin: 0 0 1em 0; margin: 0 0 0.6em 0;
padding: 0; padding: 0;
} }
@ -141,12 +147,6 @@ dl ul, dl ol, dl dl {
margin-bottom: 0; margin-bottom: 0;
} }
ol p:first-child,
ul p:first-child,
dl p:first-child {
margin-bottom: 0;
}
ul, ol { ul, ol {
margin-left: 2em; margin-left: 2em;
} }
@ -166,25 +166,20 @@ dd + dt.pre {
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
font-family: Helvetica, Arial, sans-serif; color: #301004;
color: #000;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
font-weight: 700;
position: relative; position: relative;
margin-bottom: 0.5em;
} }
header h1 { header h1 {
font-family: Georgia, FreeSerif, Times, serif; line-height: 2.0em;
font-size: 30px; margin: 0;
font-weight: normal;
line-height: 36px;
color: #480;
margin: 15px 0 11px;
} }
h1 { #apicontent {
font-size: 29px; padding-top: 1.0em;
line-height: 33px;
margin: 2em 0 15px;
} }
#toc + h1 { #toc + h1 {
@ -193,9 +188,8 @@ h1 {
} }
h2 { h2 {
font-size: 1.4em; font-size: 1.5em;
line-height: 1.0909em; margin: 1.0em 0 0.5em;
margin: 1.5em 0 0.5em;
} }
h2 + h2 { h2 + h2 {
@ -203,9 +197,8 @@ h2 + h2 {
} }
h3 { h3 {
font-size: 1.3em; font-size: 1.0em;
line-height: 1.1282em; margin: 1.5em 0 0.5em;
margin: 2.2em 0 0.5em;
} }
h3 + h3 { h3 + h3 {
@ -218,7 +211,6 @@ h2, h3, h4 {
} }
h1 span, h2 span, h3 span, h4 span { h1 span, h2 span, h3 span, h4 span {
font-size: 25px;
position: absolute; position: absolute;
display: block; display: block;
top: 0; top: 0;
@ -234,19 +226,9 @@ h1 span a, h2 span a, h3 span a, h4 span a {
font-size: 0.8em; font-size: 0.8em;
color: #000; color: #000;
text-decoration: none; text-decoration: none;
font-family: Helvetica, Arial, sans-serif;
font-weight: bold; font-weight: bold;
} }
h1 span a.top, h2 span a.top, h3 span a.top, h4 span a.top {
/* XXX Get an image and clean up these two links
* so that they look nice next to one another.
* http://www.chrisglass.com/work/nodejs/website/v05/docs.html
* -isaacs
*/
display: none;
}
h5 { h5 {
font-size: 1.125em; font-size: 1.125em;
line-height: 1.4em; line-height: 1.4em;
@ -258,28 +240,29 @@ h6 {
} }
pre, tt, code { pre, tt, code {
font-size: 14px; line-height: 1.5em;
line-height: 1.5438em;
font-family: Monaco, Consolas, "Lucida Console", monospace; font-family: Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0; margin: 0; padding: 0;
} }
.pre { .pre {
font-family: Monaco, Consolas, "Lucida Console", monospace; font-family: Monaco, Consolas, "Lucida Console", monospace;
line-height: 1.5438em; line-height: 1.5em;
font-size: 0.95em; font-size: 1.2em;
} }
pre { pre {
padding: 1em 1.6em 1em 1.2em; padding: 1.0em 1.5em;
vertical-align: top; vertical-align: top;
background: #f8f8f8; background: #f2f5f0;
border: 1px solid #e8e8e8; margin: 0.166666em -4.0em 1.0em 0em;
border-width: 1px 1px 1px 6px;
margin: -0.5em 0 1.1em;
overflow-x: auto; overflow-x: auto;
} }
pre > code {
font-size: 0.8em;
}
pre + h3 { pre + h3 {
margin-top: 2.225em; margin-top: 2.225em;
} }
@ -289,76 +272,77 @@ code.pre {
} }
#intro { #intro {
width: 775px; margin-top: 1.25em;
margin: 0 auto; margin-left: 1.0em;
text-align: center;
color: #d2d8ba;
/* preload platform-icons.png */
background-image: url(http://nodejs.org/images/platform-icons.png);
background-repeat: no-repeat;
background-position: -999em -999em;
} }
#intro.interior #logo { #intro a {
margin-left: -298px; color: #333;
border: 0; font-size: 1.25em;
font-weight: bold;
} }
hr { hr {
background: none; background: none;
border: medium none; border: medium none;
border-bottom: 1px solid #ccc; border-bottom: 1px solid #7a7a7a;
margin: 1em 0; margin: 0em 0em 1em 0;
} }
#toc { #toc {
font-size: 15px;
line-height: 1.5em;
line-height: 22px;
padding-top: 4px;
} }
#toc h2 { #toc h2 {
font-size: 15px; color: #C73E09;
line-height: 21px; margin-top: 0;
margin: 0 0 0.5em; font-size: 1.0em;
line-height: 0;
margin: 1.5em 0;
} }
#toc h2 a { #toc ul {
float: right; font-size: 0.8125em;
} }
#toc hr { #toc ul ul { font-size: 1.0em; }
margin: 1em 0 2em;
}
#toc ul,
#api-section-index #apicontent ul li,
#api-section-index #apicontent ul {
font-family: Georgia, FreeSerif, Times, serif;
color: #666 !important;
}
#toc ul a { #toc ul a {
text-decoration: none; text-decoration:none;
border-bottom: 1px dotted #480; }
#toc ul li {
margin-bottom: 0.6666em;
list-style: square outside;
}
#toc li > ul {
margin-top: 0.6666em;
} }
#toc ul a:hover, #toc ul a:hover,
#toc ul a:focus { #toc ul a:focus {
border-bottom: 1px dotted #fff; }
color: #000;
#apicontent li {
margin-bottom: 0.5em;
}
#apicontent li:last-child {
margin-bottom: 0;
} }
p tt, p tt,
p code, span.type { p code,
background: #f8f8ff; li code {
border: 1px solid #dedede; font-size: 0.9em;
padding: 0 0.2em; color: #040404;
}
span.type {
color: #222;
} }
#content { #content {
width: 953px;
margin: 0 auto; margin: 0 auto;
overflow: visible; overflow: visible;
clear: both; clear: both;
@ -366,197 +350,73 @@ p code, span.type {
} }
#column1.interior { #column1.interior {
width: 749px; width: 702px;
float: right; border-left: 13em solid #f2f5f0;
padding-top: 7px; padding-left: 2.0em;
padding-top: 11px;
font-size: 18px;
} }
#column2.interior { #column2.interior {
width: 140px; width: 234px;
float: left; float: left;
margin-top: -55px;
overflow: visible;
} }
#column2.interior ul { #column2 ul {
margin-left: 0; list-style: none;
margin-left: 0em;
margin-top: 1.25em;
background: #f2f5f0;
margin-bottom: 0;
padding-bottom: 2.5em;
} }
#column2.interior li { #column2 ul li {
list-style-type: none; padding-left: 1.4em;
margin-bottom: 0.5em;
padding-bottom: 0.5em;
font-size: 0.8em;
} }
#column2.interior li a { #column2 ul li:last-child {
display: block; margin-bottom: 0;
padding: 0 0 0 35px;
color: #878b78;
text-transform: uppercase;
text-decoration: none;
font-size: 11px;
line-height: 23px;
} }
#column2.interior li a.home { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px 3px; } #column2 ul li a {
#column2.interior li a.download { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -21px; } color: #7a7a7a;
#column2.interior li a.about { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -45px; }
#column2.interior li a.npm { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -69px; }
#column2.interior li a.docs { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -93px; }
#column2.interior li a.blog { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -117px; }
#column2.interior li a.community { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -141px; }
#column2.interior li a.logos { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -165px; }
#column2.interior li a.jobs { background: url(http://nodejs.org/images/icons-interior.png) no-repeat -156px -189px; }
#column2.interior li a.home.current { background-position: 2px 3px; }
#column2.interior li a.download.current { background-position: 2px -21px; }
#column2.interior li a.about.current { background-position: 2px -45px; }
#column2.interior li a.npm.current { background-position: 2px -69px; }
#column2.interior li a.docs.current { background-position: 2px -93px; }
#column2.interior li a.blog.current { background-position: 2px -117px; }
#column2.interior li a.community.current { background-position: 2px -141px; }
#column2.interior li a.logos.current { background-position: 2px -165px; }
#column2.interior li a.jobs.current { background-position: 2px -189px; }
#column2.interior li a.home:hover { background-position: -331px 3px; }
#column2.interior li a.download:hover { background-position: -331px -21px; }
#column2.interior li a.about:hover { background-position: -331px -45px; }
#column2.interior li a.npm:hover { background-position: -331px -69px; }
#column2.interior li a.docs:hover { background-position: -331px -93px; }
#column2.interior li a.blog:hover { background-position: -331px -117px; }
#column2.interior li a.community:hover { background-position: -331px -141px; }
#column2.interior li a.logos:hover { background-position: -331px -165px; }
#column2.interior li a.jobs:hover { background-position: -331px -189px; }
#column2.interior li a.current {
color: #8cc84b;
font-weight: bold;
} }
#column2.interior li a:hover { #column2 ul li a.active {
color: #000000; color: #533;
text-decoration: none; border-bottom: 1px solid #533;
}
#column2.interior li + li {
border-top: 1px solid #c1c7ac;
}
#column2.interior p.twitter {
padding-top: 20px;
}
#column2.interior p.twitter a {
background: url(http://nodejs.org/images/twitter-bird.png) no-repeat 0 4px;
padding-left: 37px;
text-decoration: none;
}
#column2.interior p.twitter a:hover {
text-decoration: underline;
}
a.totop {
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
font-weight: bold;
text-indent: -9999999px;
background: url(http://nodejs.org/images/anchor.png) no-repeat top left;
margin-right: 7px;
display: block;
width: 13px;
border-bottom: 1px solid #cccccc;
}
a.anchor {
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
font-weight: bold;
text-indent: -9999999px;
background: url(http://nodejs.org/images/anchor.png) no-repeat top right;
display: block;
width: 13px;
border-bottom: 1px solid #cccccc;
} }
#footer { #footer {
width: 942px;
margin: 150px auto 55px auto;
padding: 0; padding: 0;
min-height: 300px;
background: #333;
color: white;
} }
#footer .joyent-logo { span > .mark,
display:block; span > .mark:visited {
position:absolute; font-size: 18px;
overflow:hidden; color: #ccc;
text-indent:-999em; position: absolute;
height:100px; top: 0px;
width:190px; right: 0px;
z-index:999;
} }
#footer p { span > .mark:hover {
font-size: 11px; color: #FE7110;
line-height: 1em;
padding: 0 0 0 195px;
color: #666;
} }
#footer p, th, td {
#footer li { padding: 0.75em 1.0em 0.75em 1.0em;
font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; vertical-align: top;
} }
#footer a { th > *:last-child,
text-decoration: none; td > *:last-child {
border: none; margin-bottom: 0;
color: #480;
}
#footer a:hover {
color: #000;
}
#footer p a {
border-bottom: 1px dotted #480;
color: #878b78;
}
#footer ul {
background: url(http://nodejs.org/images/footer-logo-alt.png) left 17px no-repeat;
padding: 23px 0 0 195px;
height: 26px;
margin-left: -1px;
border-top: 1px solid #626557;
}
#footer ul li {
list-style-type: none;
float: left;
font-size: 12px;
margin: 0 !important;
padding: 0;
height: 12px;
}
#footer ul li a {
margin: 0;
padding: 0 6px 0 0;
display: block;
height: 12px;
line-height: 12px;
}
#footer ul li + li {
margin-left: 3px;
}
#footer ul li + li a {
padding: 0 6px 0 6px;
border-left: 1px solid #878b78;
}
#footer ul li a.twitter {
background: url(http://nodejs.org/images/twitter-bird.png) no-repeat 5px 0px;
padding-left: 25px;
} }
/* simpler clearfix */ /* simpler clearfix */
@ -567,3 +427,40 @@ a.anchor {
clear: both; clear: both;
visibility: hidden; visibility: hidden;
} }
@media only screen and (max-width: 1024px) {
#content {
font-size: 2.1em;
}
#column1.interior {
border-left: 0;
padding-left: 0.5em;
padding-right: 0.5em;
width: auto;
}
pre {
margin-right: 0;
}
#column2 {
display: none;
}
}
@media only screen and (max-width: 1024px) and (orientation: portrait) {
#content {
font-size: 2.4em;
}
#column1.interior {
border-left: 0;
padding-left: 0.5em;
padding-right: 0.5em;
width: auto;
}
pre {
margin-right: 0;
}
#column2 {
display: none;
}
}

View File

@ -2,36 +2,26 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>__SECTION__ Node.js __VERSION__ Manual &amp; Documentation</title> <title>__SECTION__ io.js __VERSION__ Manual &amp; Documentation</title>
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="assets/style.css"> <link rel="stylesheet" href="assets/style.css">
<link rel="stylesheet" href="assets/sh.css"> <link rel="stylesheet" href="assets/sh.css">
<link rel="canonical" href="http://nodejs.org/api/__FILENAME__.html"> <link rel="canonical" href="http://iojs.org/api/__FILENAME__.html">
</head> </head>
<body class="alt apidoc" id="api-section-__FILENAME__"> <body class="alt apidoc" id="api-section-__FILENAME__">
<div id="intro" class="interior">
<a href="/" title="Go back to the home page">
<img id="logo" src="http://nodejs.org/images/logo-light.png" alt="node.js">
</a>
</div>
<div id="content" class="clearfix"> <div id="content" class="clearfix">
<div id="column2" class="interior"> <div id="column2" class="interior">
<ul> <div id="intro" class="interior">
<li><a href="/" class="home">Home</a></li> <a href="/" title="Go back to the home page">
<li><a href="/download/" class="download">Download</a></li> io.js (1)
<li><a href="/about/" class="about">About</a></li> </a>
<li><a href="http://npmjs.org/" class="npm">npm Registry</a></li> </div>
<li><a href="http://nodejs.org/api/" class="docs current">Docs</a></li> __GTOC__
<li><a href="http://blog.nodejs.org" class="blog">Blog</a></li>
<li><a href="/community/" class="community">Community</a></li>
<li><a href="/logos/" class="logos">Logos</a></li>
<li><a href="http://jobs.nodejs.org/" class="jobs">Jobs</a></li>
</ul>
<p class="twitter"><a href="http://twitter.com/nodejs">@nodejs</a></p>
</div> </div>
<div id="column1" class="interior"> <div id="column1" data-id="__ID__" class="interior">
<header> <header>
<h1>Node.js __VERSION__ Manual &amp; Documentation</h1> <h1>io.js __VERSION__ Documentation</h1>
<div id="gtoc"> <div id="gtoc">
<p> <p>
<a href="index.html" name="toc">Index</a> | <a href="index.html" name="toc">Index</a> |
@ -53,34 +43,10 @@
</div> </div>
</div> </div>
<div id="footer"> <div id="footer">
<a href="http://joyent.com" class="joyent-logo">Joyent</a>
<ul class="clearfix">
<li><a href="/">Node.js</a></li>
<li><a href="/download/">Download</a></li>
<li><a href="/about/">About</a></li>
<li><a href="http://npmjs.org/">npm Registry</a></li>
<li><a href="http://nodejs.org/api/">Docs</a></li>
<li><a href="http://blog.nodejs.org">Blog</a></li>
<li><a href="/community/">Community</a></li>
<li><a href="/logos/">Logos</a></li>
<li><a href="http://jobs.nodejs.org/">Jobs</a></li>
<li><a href="http://twitter.com/nodejs" class="twitter">@nodejs</a></li>
</ul>
<p>Copyright <a href="http://joyent.com/">Joyent, Inc</a>, Node.js is a <a href="/trademark-policy.pdf">trademark</a> of Joyent, Inc. View <a href="https://raw.github.com/joyent/node/__VERSION__/LICENSE">license</a>.</p>
</div> </div>
<script src="../sh_main.js"></script> <script src="../sh_main.js"></script>
<script src="../sh_javascript.min.js"></script> <script src="../sh_javascript.min.js"></script>
<script>highlight(undefined, undefined, 'pre');</script> <script>highlight(undefined, undefined, 'pre');</script>
<script>
window._gaq = [['_setAccount', 'UA-10874194-2'], ['_trackPageview']];
(function(d, t) {
var g = d.createElement(t),
s = d.getElementsByTagName(t)[0];
g.src = '//www.google-analytics.com/ga.js';
s.parentNode.insertBefore(g, s);
}(document, 'script'));
</script>
</body> </body>
</html> </html>

View File

@ -20,6 +20,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
var processIncludes = require('./preprocess.js');
var marked = require('marked'); var marked = require('marked');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
@ -52,48 +53,10 @@ console.error('Input file = %s', inputFile);
fs.readFile(inputFile, 'utf8', function(er, input) { fs.readFile(inputFile, 'utf8', function(er, input) {
if (er) throw er; if (er) throw er;
// process the input for @include lines // process the input for @include lines
processIncludes(input, next); processIncludes(inputFile, input, next);
}); });
var includeExpr = /^@include\s+([A-Za-z0-9-_]+)(?:\.)?([a-zA-Z]*)$/gmi;
var includeData = {};
function processIncludes(input, cb) {
var includes = input.match(includeExpr);
if (includes === null) return cb(null, input);
var errState = null;
console.error(includes);
var incCount = includes.length;
if (incCount === 0) cb(null, input);
includes.forEach(function(include) {
var fname = include.replace(/^@include\s+/, '');
if (!fname.match(/\.markdown$/)) fname += '.markdown';
if (includeData.hasOwnProperty(fname)) {
input = input.split(include).join(includeData[fname]);
incCount--;
if (incCount === 0) {
return cb(null, input);
}
}
var fullFname = path.resolve(path.dirname(inputFile), fname);
fs.readFile(fullFname, 'utf8', function(er, inc) {
if (errState) return;
if (er) return cb(errState = er);
processIncludes(inc, function(er, inc) {
if (errState) return;
if (er) return cb(errState = er);
incCount--;
includeData[fname] = inc;
input = input.split(include+'\n').join(includeData[fname]+'\n');
if (incCount === 0) {
return cb(null, input);
}
});
});
});
}
function next(er, input) { function next(er, input) {

View File

@ -22,17 +22,63 @@
var fs = require('fs'); var fs = require('fs');
var marked = require('marked'); var marked = require('marked');
var path = require('path'); var path = require('path');
var preprocess = require('./preprocess.js');
module.exports = toHTML; module.exports = toHTML;
// TODO(chrisdickinson): never stop vomitting / fix this.
var gtocPath = path.resolve(path.join(__dirname, '..', '..', 'doc', 'api', '_toc.markdown'));
var gtocLoading = null;
var gtocData = null;
function toHTML(input, filename, template, cb) { function toHTML(input, filename, template, cb) {
var lexed = marked.lexer(input); if (gtocData) {
fs.readFile(template, 'utf8', function(er, template) { return onGtocLoaded();
if (er) return cb(er); }
render(lexed, filename, template, cb);
if (gtocLoading === null) {
gtocLoading = [onGtocLoaded];
return loadGtoc(function(err, data) {
if (err) throw err;
gtocData = data;
gtocLoading.forEach(function(xs) {
xs();
});
});
}
if (gtocLoading) {
return gtocLoading.push(onGtocLoaded);
}
function onGtocLoaded() {
var lexed = marked.lexer(input);
fs.readFile(template, 'utf8', function(er, template) {
if (er) return cb(er);
render(lexed, filename, template, cb);
});
}
}
function loadGtoc(cb) {
fs.readFile(gtocPath, 'utf8', function(err, data) {
if (err) return cb(err);
preprocess(gtocPath, data, function(err, data) {
if (err) return cb(err);
data = marked(data).replace(/<a href="(.*?)"/gm, function(a, m) {
return '<a class="nav-' + toID(m) + '" href="' + m + '"';
});
return cb(null, data);
});
}); });
} }
function toID(filename) {
return filename.replace('.html', '').replace(/[^\w\-]/g, '-').replace(/-+/g, '-');
}
function render(lexed, filename, template, cb) { function render(lexed, filename, template, cb) {
// get the section // get the section
var section = getSection(lexed); var section = getSection(lexed);
@ -46,10 +92,17 @@ function render(lexed, filename, template, cb) {
buildToc(lexed, filename, function(er, toc) { buildToc(lexed, filename, function(er, toc) {
if (er) return cb(er); if (er) return cb(er);
var id = toID(path.basename(filename));
template = template.replace(/__ID__/g, id);
template = template.replace(/__FILENAME__/g, filename); template = template.replace(/__FILENAME__/g, filename);
template = template.replace(/__SECTION__/g, section); template = template.replace(/__SECTION__/g, section);
template = template.replace(/__VERSION__/g, process.version); template = template.replace(/__VERSION__/g, process.version);
template = template.replace(/__TOC__/g, toc); template = template.replace(/__TOC__/g, toc);
template = template.replace(
/__GTOC__/g,
gtocData.replace('class="nav-' + id, 'class="nav-' + id + ' active')
);
// content has to be the last thing we do with // content has to be the last thing we do with
// the lexed tokens, because it's destructive. // the lexed tokens, because it's destructive.

57
tools/doc/preprocess.js Normal file
View File

@ -0,0 +1,57 @@
module.exports = preprocess;
var path = require('path');
var fs = require('fs');
var includeExpr = /^@include\s+([A-Za-z0-9-_]+)(?:\.)?([a-zA-Z]*)$/gmi;
var includeData = {};
function preprocess(inputFile, input, cb) {
input = stripComments(input);
processIncludes(inputFile, input, function (err, data) {
if (err) return cb(err);
cb(null, data);
});
}
function stripComments(input) {
return input.replace(/^@\/\/.*$/gmi, '');
}
function processIncludes(inputFile, input, cb) {
var includes = input.match(includeExpr);
if (includes === null) return cb(null, input);
var errState = null;
console.error(includes);
var incCount = includes.length;
if (incCount === 0) cb(null, input);
includes.forEach(function(include) {
var fname = include.replace(/^@include\s+/, '');
if (!fname.match(/\.markdown$/)) fname += '.markdown';
if (includeData.hasOwnProperty(fname)) {
input = input.split(include).join(includeData[fname]);
incCount--;
if (incCount === 0) {
return cb(null, input);
}
}
var fullFname = path.resolve(path.dirname(inputFile), fname);
fs.readFile(fullFname, 'utf8', function(er, inc) {
if (errState) return;
if (er) return cb(errState = er);
preprocess(inputFile, inc, function(er, inc) {
if (errState) return;
if (er) return cb(errState = er);
incCount--;
includeData[fname] = inc;
input = input.split(include+'\n').join(includeData[fname]+'\n');
if (incCount === 0) {
return cb(null, input);
}
});
});
});
}