├── .gitignore ├── ABOUT.mdown ├── LICENSE.mdown ├── README.mdown ├── TEMPLATE.mdown ├── TOC.mdown ├── jodoc └── samples ├── TOC_SAMPLE.mdown ├── css ├── doc.css └── docbody.css ├── index.html └── template.html /.gitignore: -------------------------------------------------------------------------------- 1 | html/ 2 | -------------------------------------------------------------------------------- /ABOUT.mdown: -------------------------------------------------------------------------------- 1 | About joDoc 2 | =========== 3 | 4 | JavaScript is an extremely expressive language which is often difficult to 5 | describe in terms of meta data and fields. Often, important information that 6 | needs to be documented just doesn't fit into a neat, tidy spot. 7 | 8 | joDoc uses markdown as its core to provide simple, human-readable docs which 9 | it converts to HTML. 10 | 11 | 12 | Autolinker 13 | ========== 14 | 15 | Basically, anything that ends up in an `

` tag becomes a keyword that: 16 | 17 | - appears in the keyword index 18 | - is turned into a link wherever it is used in your documentation text 19 | - resolves in the TOC into links 20 | 21 | 22 | Injecting HTML Snippets 23 | ======================= 24 | 25 | Markdown supports inline HTML, so your code comments and markdown files may 26 | have arbitrary bits of HTML in them. 27 | 28 | joDoc *also* supports HTML files, so you can use it to bring together docs 29 | built from other tools. The autolink feature works at the HTML level, so by 30 | just including HTML files in your doc project, they become linkable from other 31 | document pages automatically. 32 | 33 | 34 | Comparison 35 | ========== 36 | 37 | vs. jsdoc 38 | --------- 39 | 40 | jsdoc in its various incarnations and some of its spawn like yuidoc take the approach 41 | that "what is good for Java is good for JavaScript". All these flavors are based on 42 | javadoc formatting, and have been in use for some time. 43 | 44 | Aside from the regimented markup being a bit odd to read (admit it, even Java developers 45 | don't _love_ it), it suffers from an inflexibility with regard to all the coding 46 | patterns available with JavaScript. Basically, it fails due for the same reason that all 47 | JavaScript libraries which attempt to subvert JavaScript's natural object model fail. 48 | These solutions, while influential in the idea that _some_ form consistent coding 49 | approach could help us make better code, are not in the spirit of embracing JavaScript. 50 | 51 | Why then do so many developers continue to use a _documentation_ tool which was born 52 | of the same well-meaning yet misguided logic of "let's pretend JavaScript is Java"? 53 | 54 | vs. Natural Docs 55 | ---------------- 56 | 57 | Excellent effort, but complex to set up and also tries to make a regimented system for 58 | documenting source code. It is extendable, but again, we have a documentation solution 59 | which is trying to force JavaScript into a more limited set of features. 60 | 61 | 62 | joDoc Process 63 | ============= 64 | 65 | For those who want more insight into how the documentation is created: 66 | 67 | for each markdown file in your project, 68 | convert to an HTML file 69 | 70 | for each source file, 71 | produce a markdown file from all text between `/**` and `*/` comments 72 | convert the markdown file into an HTML file 73 | 74 | for each HTML file, 75 | for each `h1` tag, 76 | add an `id` field based on the contents of the `h1` tag 77 | add contents to a `file.html#id` keyword index 78 | 79 | for each HTML file, 80 | for each keyword in our index, 81 | intelligently wrap the keyword with an `a` tag 82 | that points to the `file.html#id` from our keyword index 83 | 84 | produce an index: 85 | sort the keyword index 86 | save the keyword index as an HTML file 87 | save the keyword index as a JSON file 88 | 89 | produce a table of contents: 90 | build sections based on directory names 91 | retain sorted directory order 92 | save as a JSON file 93 | save as a formatted HTML file 94 | 95 | concat all html files into one document: 96 | structure: 97 | header 98 | table of contents 99 | contents from all html files, in order 100 | sorted keyword index 101 | footer 102 | convert all fixed paths to local references: 103 | (e.g. `filename.html#about` becomes simply `#about`) 104 | 105 | This produces a bundle of files which can be used a couple of ways: 106 | 107 | 1. A loose set of files which is used by the joDoc application (written 108 | using the jo library, of course) 109 | 110 | 2. An alternative "single page" view of all the documentation (which some 111 | people really like) 112 | 113 | 3. Your own collection of files with some other organization means (which 114 | is trivial to do with pre-rendered HTML and the JSON document 115 | structure). 116 | 117 | -------------------------------------------------------------------------------- /LICENSE.mdown: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | Copyright 2010 Dave Balmer, Jr. All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, are 7 | permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this list of 10 | conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 | of conditions and the following disclaimer in the documentation and/or other materials 14 | provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY DAVE BALMER, JR. "AS IS" AND ANY EXPRESS OR IMPLIED 17 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVE BALMER, JR. OR 19 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | The views and conclusions contained in the software and documentation are those of the 27 | authors and should not be interpreted as representing official policies, either expressed 28 | or implied, of Dave Balmer, Jr. 29 | 30 | - - - 31 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | joDoc 2 | ===== 3 | 4 | joDoc is a plain text code documentation scheme for JavaScript. It was created out of 5 | frustration felt working with various documentation systems available. joDoc does not 6 | attempt to perform any special automation other than generating links, table of 7 | contents, an index, and of course rendered HTML for your documentation. 8 | 9 | Source code formatting 10 | ---------------------- 11 | 12 | This is a simple example of what you can do in your source documentation. This is all 13 | free-form markdown text. 14 | 15 | /** 16 | myClass 17 | ======= 18 | 19 | This is my class. It rocks, and this is its _description_, which also 20 | rocks. 21 | 22 | Extends 23 | ------- 24 | 25 | - someOtherClass 26 | 27 | Methods 28 | ------- 29 | 30 | - setName(name) 31 | 32 | Where `name` is a `String`. 33 | 34 | Use 35 | --- 36 | // here is some sample code which shows how to use this class 37 | var x = new myClass(name); 38 | 39 | > Note: use of the `name` reserved word is probaly a bad idea. 40 | */ 41 | 42 | 43 | Comment placement 44 | ----------------- 45 | 46 | You can put your comments for your code either: 47 | 48 | 1. in your source code (anywhere and in as many pieces as you want) denoted with 49 | `/** ... */` multiline-comment blocks 50 | 51 | 2. separate markdown (`*.mdown`) files, probably (tho not necessarily) named to 52 | match your JavaScript files 53 | 54 | Can't get much more flexible than that. 55 | 56 | 57 | Requirements 58 | ------------ 59 | 60 | 1. perl 5.8 or greater (*YMMV with older perl versions*) 61 | 2. [Markdown.pl](http://daringfireball.net/projects/markdown/) (or compatible parser) 62 | 3. [SmartyPants.pl](http://daringfireball.net/projects/smartypants/) (*optional*) 63 | 64 | > Windows users should get some suggestions for installing ActiveState or cygwin 65 | 66 | 67 | Use 68 | --- 69 | 70 | jodoc [--output path] [--title string] [--toc file] [--template file] [--markdown file] [-s] [--smartypants file] [filespec] 71 | 72 | - `--output path` 73 | 74 | specify a path to where you want doc files placed 75 | 76 | - `--toc file` 77 | 78 | joDoc will work with a table of contents structure defined in a markdown 79 | file. Your TOC file can be completely manual, just a list of atuo-linked 80 | terms (or markdown or even HTML style links), but joDoc will do do more 81 | if you want it. For example: 82 | 83 | Developer Guide 84 | --------------- 85 | 86 | - {ABOUT.mdown} 87 | - {README.mdown} 88 | - {docs/} 89 | - {LICENSE.mdown} 90 | 91 | API Reference 92 | ------------- 93 | 94 | ### Core 95 | - {js/core} 96 | 97 | ### Data 98 | - {js/data} 99 | 100 | ### User Interface 101 | - {js/ui} 102 | 103 | You can put a file path inside the {} pairs, and joDoc will attempt to find 104 | and sort all the headers from the files which match that pattern. 105 | 106 | > NOTE: the TOC is not a replacement for the `filespec` in the command line. 107 | > You need to make sure to tell joDoc what directorie(s) to parse. The TOC is 108 | > a semi-automated document which can be useful but is not required. 109 | 110 | - `--markdown file` 111 | 112 | tells joDoc to use a specific markdown parser. 113 | 114 | - `--title string` 115 | 116 | is an optional title which will appear on your HTML output. 117 | 118 | - `--template file` 119 | 120 | tells joDoc to use a custom HTML file as a template, a simple example: 121 | 122 | $title 123 | $body 124 | 125 | - `--smartypants` 126 | 127 | tells joDoc to use a specific smartypants prettifier. 128 | 129 | - `-s` 130 | 131 | tells joDoc to filter output through SmartyPants. 132 | 133 | - `tidy` 134 | 135 | tells joDoc to use the HTMLTidy prettifier. 136 | 137 | - `htmltidy string` 138 | 139 | tells joDoc to use a specific HTMLTidy compatible prettifier 140 | 141 | - `filespec` 142 | 143 | is one or more files to parse. Directories will be recursively handled. 144 | > Note: No support for STDIN input at the moment. Use named pipes for now. 145 | Also, block devices like `/dev/random` are totally untested. 146 | 147 | 148 | Examples 149 | -------- 150 | 151 | Simple case: 152 | 153 | jodoc 154 | 155 | By default, joDoc will start in the current directory and recursively look for 156 | `*.mdown`, `.*.js` and `*.css` files to build documentation. Unless directed 157 | otherwise, joDoc will print a unified HTML file on standard out with all the 158 | documentation output, and an index of all `

` tags. 159 | 160 | Specifying an output base directory: 161 | 162 | jodoc --output /var/www/html/docs 163 | 164 | Specifying files to parse: 165 | 166 | jodoc ABOUT.mdown *.js *.css 167 | 168 | Defining a table of contents structure: 169 | 170 | jodoc --toc ~/release.toc 171 | 172 | Building joDoc's documentation with joDoc: 173 | 174 | jodoc --output html -s --toc samples/TOC_SAMPLE.mdown *.mdown 175 | cp samples/css/* html/ 176 | cp samples/index.html html/ 177 | 178 | Note that the css and index.html step is specific to this documentation set; it is not necessarily required for the docs in your project. 179 | -------------------------------------------------------------------------------- /TEMPLATE.mdown: -------------------------------------------------------------------------------- 1 | HTML Template 2 | ============= 3 | 4 | joDoc allows for setting an HTML template to wrap around the text from the markdown blocks. 5 | 6 | Variables 7 | --------- 8 | 9 | Currently, the only variables supported in the HTML template are `$body` and `$title`. 10 | 11 | The `$body` tag will be replaced with the body of the HTML output, and `$title` will be replaced with whatever 12 | 13 | is given to the `--title` option for joDoc, or "JoDoc" by default. 14 | 15 | By default, a "non-terrible" template is used, linking to the css stylesheets in the `samples/css` folder. 16 | 17 | Examples 18 | -------- 19 | 20 | A simple example of a joDoc compatible template can be found in `samples/template.html`. 21 | 22 | $title$body 23 | 24 | The default template of joDoc is a little more advanced, and depends on `doc.css` and `docbody.css`, which can be found in `samples/css/`. 25 | 26 | 27 | 28 | 29 | 30 | $title 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | $body 39 | 40 | 41 | -------------------------------------------------------------------------------- /TOC.mdown: -------------------------------------------------------------------------------- 1 | Table of Contents 2 | ================= 3 | 4 | joDoc can create an optional Table of Contents file from a markdown file. 5 | To use the Table of Contents option, you must specify an output directory. 6 | > See README for more information about the output directory. 7 | 8 | Syntax 9 | ------ 10 | 11 | The Table of Contents file is expected to be in markdown format, but with the addition of an autogeneration marker, `{}`. 12 | 13 | Example 14 | ------- 15 | 16 | Using the following table of contents file: 17 | 18 | Core 19 | ---- 20 | - Blah 21 | - {js} 22 | 23 | With files `foo/js/blah.js, foo/js/bar.js` will result in a postprocess file 24 | 25 | ... 26 |

Core

27 | \n"; 157 | } 158 | $index .= "\n

$letter

\n"; 159 | $index .= "\n
\n\n"; 171 | return $index; 172 | } 173 | 174 | # Pipe stuff through markdown for parsing 175 | sub markdown_pipe { 176 | my $in = shift; 177 | my @out = (); 178 | 179 | # Use pipes instead of temp files 180 | # The magic here is what you expect open(HANDLE, "| $markdown_bin |") to do. 181 | my $pid = open2( my $chld_out, my $chld_in, $markdown_bin ) or die $!; 182 | print $chld_in $in; 183 | close $chld_in or die $!; 184 | while (<$chld_out>) { 185 | push( @out, $_ ); 186 | } 187 | close $chld_out or die $!; 188 | 189 | # We don't leave a process behind! 190 | waitpid( $pid, 0 ); 191 | return join( "", @out ); 192 | } 193 | 194 | sub smartypants_pipe { 195 | my $in = shift; 196 | my @out = (); 197 | my $pid = open2( my $chld_out, my $chld_in, "$smartypants_bin" ) 198 | or die $!; 199 | print $chld_in $in; 200 | close $chld_in or die $!; 201 | while (<$chld_out>) { 202 | push( @out, $_ ); 203 | } 204 | close $chld_out or die $!; 205 | 206 | # We don't leave a process behind! 207 | waitpid( $pid, 0 ); 208 | return join( "", @out ); 209 | } 210 | 211 | sub tidy_pipe { 212 | my $in = shift; 213 | my @out = (); 214 | my $pid = open2( my $chld_out, my $chld_in, "$tidy_bin" ) 215 | or die $!; 216 | print $chld_in $in; 217 | close $chld_in or die $!; 218 | while (<$chld_out>) { 219 | push( @out, $_ ); 220 | } 221 | close $chld_out or die $!; 222 | 223 | # We don't leave a process behind! 224 | waitpid( $pid, 0 ); 225 | return join( "", @out ); 226 | } 227 | 228 | # Find all the h1tags for all files 229 | sub h1finder { 230 | %h1s = (); 231 | %files_to_h1s = (); 232 | for my $file ( keys %processed ) { 233 | my @h1 = $processed{$file} =~ m{\([^\<]+)\}g; 234 | $h1s{$_} = $file for @h1; 235 | $files_to_h1s{$file} = \@h1; 236 | } 237 | return; 238 | } 239 | 240 | # Expand {} blocks in table of contents 241 | sub toclinker { 242 | my $indent = shift; 243 | my $pathpart = shift; 244 | my @matching_files = keys %files_to_h1s; 245 | @matching_files = grep { m{$pathpart} } @matching_files; 246 | my @matching_h1s = (); 247 | push( @matching_h1s, @{ $files_to_h1s{$_} } ) for @matching_files; 248 | @matching_h1s = sort { lc($a) cmp lc($b) } @matching_h1s; 249 | $_ = $indent . '* ' . $_ . "\n" for @matching_h1s; 250 | 251 | # escape _ characters to make markdown happy 252 | my $match = join( "", @matching_h1s ); 253 | $match =~ s/\_/\\_/g; 254 | return $match; 255 | } 256 | 257 | # munge output file names 258 | sub munge { 259 | my %munged_processed = (); 260 | for my $file ( keys %processed ) { 261 | $munged_processed{munge_filename($file)} = $processed{$file}; 262 | } 263 | %processed = %munged_processed; 264 | return; 265 | } 266 | 267 | sub munge_filename { 268 | my $file = shift; 269 | 270 | my @path_parts = split( m{/}, $file ); 271 | s{^\.+}{}g for @path_parts; 272 | 273 | # Remove empty path parts, looks prettier that way 274 | @path_parts = grep { $_ ne "" } @path_parts; 275 | my $path = join( '_', @path_parts ); 276 | my $munged = $path . '.html'; 277 | 278 | return $munged; 279 | } 280 | 281 | # Create a JSON output of the index 282 | sub index_to_json { 283 | my @keywords = keys %h1s; 284 | @keywords = sort { lc($a) cmp lc($b) } @keywords; 285 | $_ = qq({"term":"$_","url":"$h1s{$_}"}) for @keywords; 286 | return '[' . join( ',', @keywords ) . ']'; 287 | } 288 | 289 | sub main { 290 | 291 | # If not specified, find a markdown parser in the path 292 | chomp( $markdown_bin = qx(which markdown) ) unless $markdown_bin; 293 | chomp( $smartypants_bin = qx(which smartypants) ) unless $smartypants_bin; 294 | chomp( $tidy_bin = qx(which tidy) ) unless $tidy_bin; 295 | 296 | # We can't do anything if we can't call markdown 297 | die "Markdown parser not found!\n" unless ( -x $markdown_bin ); 298 | die "Smartypants prettifier not found!\n" 299 | if ( $use_smartypants && !( -x $smartypants_bin ) ); 300 | die "HTMLTidy prettifier not found!\n" 301 | if ( $use_tidy && !( -x $tidy_bin ) ); 302 | 303 | # Slurp all the files and process them 304 | # recurse current directory if no input arguments 305 | my @files = @ARGV; 306 | @files = glob("./*") unless ( $ARGV[0] ); 307 | for my $file (@files) { 308 | unless ( -e $file ) { 309 | warn "$file not found!\n"; 310 | next; 311 | } 312 | 313 | # recurse 314 | if ( -d $file ) { 315 | my @subdir = glob("$file/*"); 316 | push( @files, @subdir ); 317 | next; 318 | } 319 | 320 | if ( $file =~ m{\.(js|css|mdown|html|md|markdown|htm)$}i ) { 321 | my $content = read_file($file); 322 | 323 | # javascript and css files get "cleaned" 324 | if ( $file =~ m{\.(js|css)$} ) { 325 | $content = docker($content); 326 | } 327 | 328 | # pure htmlfiles don't have markdown applied 329 | unless ( $file =~ m{\.html$} ) { 330 | $content = markdown_pipe($content); 331 | } 332 | $processed{$file} = $content; 333 | push(@fileset, munge_filename($file)); 334 | } 335 | } 336 | 337 | #TODO: This is a nasty hack, but it works. Fix when times are better. 338 | if ($toc) { 339 | h1finder; 340 | my @toclinked; 341 | open( my $fh, '<', $toc ) or die $!; 342 | my @content = <$fh>; 343 | close $fh or die $!; 344 | for my $line (@content) { 345 | if ( $line =~ m/(\s*).\s*{(.+)}/ ) { 346 | $line = toclinker( $1, $2 ); 347 | } 348 | push( @toclinked, $line ); 349 | } 350 | $processed{_content} = markdown_pipe( join( "", @toclinked ) ); 351 | } 352 | munge; 353 | h1finder; 354 | autolink; 355 | 356 | # Print docs to separate files in the same hierarchy as the input 357 | if ($outputdir) { 358 | $processed{"_index.html"} = indexer; 359 | mkdir $outputdir; 360 | for my $file ( keys %processed ) { 361 | 362 | # if the processed output doesn't have at least ONE WORD CHARACTER, then it's blank. 363 | if ( $processed{$file} =~ m{\w} ) { 364 | 365 | # Don't wrap html files with tags 366 | unless ( $file =~ m{\.htm[l]?\.html$}i ) { 367 | $processed{$file} = html_head( $processed{$file} ); 368 | } 369 | if ($use_tidy) { 370 | $processed{$file} = tidy_pipe( $processed{$file} ); 371 | } 372 | if ($use_smartypants) { 373 | $processed{$file} = smartypants_pipe( $processed{$file} ); 374 | } 375 | write_file( $outputdir . '/' . $file, $processed{$file} ); 376 | } 377 | else { 378 | warn "File $file contained no content, not creating file\n"; 379 | } 380 | } 381 | write_file( $outputdir . '/_index.json', index_to_json ); 382 | } 383 | 384 | # Print to stdout 385 | else { 386 | my $tempout = ''; 387 | 388 | for my $i (@fileset) { 389 | $tempout .= $processed{$i}; 390 | } 391 | # my $tempout = join( "", values %processed ); 392 | $tempout = html_head($tempout) . indexer; 393 | if ($use_tidy) { 394 | $tempout = tidy_pipe($tempout); 395 | } 396 | if ($use_smartypants) { 397 | $tempout = smartypants_pipe($tempout); 398 | } 399 | print $tempout; 400 | } 401 | return; 402 | } 403 | 404 | main; 405 | 406 | # default html template, mobile compatible 407 | __DATA__ 408 | 409 | 410 | 411 | 412 | $title 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | $body 421 | 422 | 423 | -------------------------------------------------------------------------------- /samples/TOC_SAMPLE.mdown: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | joDoc Documentation 12 | ------------------- 13 | 14 | - {ABOUT.mdown} 15 | - {README.mdown} 16 | - {TEMPLATE.mdown} 17 | - {TOC.mdown} 18 | - License 19 | 20 | [Keyword Index](./_index.html) 21 | -------------------------------------------------------------------------------- /samples/css/doc.css: -------------------------------------------------------------------------------- 1 | /** 2 | doc.css 3 | ======= 4 | 5 | Requires `docbody.css`, which is split with the intention of using 6 | documentation in a jo app without messing with the `body` definition 7 | in the app. 8 | 9 | Support for printed media is included for generating nice PDF files. 10 | */ 11 | p { 12 | text-align: left; 13 | } 14 | 15 | .crunch p, .crunch ul, .crunch blockquote, 16 | .crunch h3, .crunch h2, .crunch hr, .crunch pre { 17 | display: none; 18 | } 19 | 20 | .crunch h1 { 21 | font-size: 20px; 22 | } 23 | 24 | /* using `` for pretty titles */ 25 | cite { 26 | position: relative; 27 | line-height: .9; 28 | background: #07c7c3; 29 | display: block; 30 | text-align: right; 31 | font-size: 120px; 32 | color: #fff; 33 | font-style: normal; 34 | margin: 0; 35 | padding: 20px 30px 20px 20px; 36 | letter-spacing: -10px; 37 | overflow: hidden; 38 | } 39 | 40 | cite>cite { 41 | letter-spacing: 0; 42 | margin: 0; 43 | padding: 0; 44 | font-size: 25%; 45 | margin-right: -10px; 46 | font-style: italic; 47 | background: transparent; 48 | overflow: visible; 49 | } 50 | 51 | cite a[href] { 52 | background: inherit; 53 | padding: 0; 54 | } 55 | 56 | em { 57 | font-weight: normal; 58 | font-style: italic; 59 | } 60 | 61 | blockquote em { 62 | font-weight: bold; 63 | } 64 | 65 | ul > li { 66 | list-style: disc; 67 | } 68 | 69 | ul { 70 | margin-right: 50px; 71 | } 72 | 73 | img { 74 | display: block; 75 | margin: 2em auto; 76 | max-width: 100%; 77 | } 78 | 79 | blockquote { 80 | font-style: italic; 81 | color: #9e9fa3; 82 | position: relative; 83 | margin: 1.5em 30px; 84 | padding: 10px 10px 0 10px; 85 | } 86 | blockquote:before { 87 | font-style: normal; 88 | content: '\201C'; 89 | font-size: 60px; 90 | position: absolute; 91 | top: -15px; 92 | left: -35px; 93 | color: #e5e6e7; 94 | } 95 | blockquote:after { 96 | font-style: normal; 97 | content: '\201E'; 98 | font-size: 60px; 99 | position: absolute; 100 | bottom: -20px; 101 | right: -35px; 102 | color: #e5e6e7; 103 | } 104 | 105 | blockquote p { 106 | margin: 0 0 10px 0; 107 | } 108 | 109 | blockquote code { 110 | font-style: normal; 111 | } 112 | 113 | h1 { 114 | margin-top: 0; 115 | color: #07c7c3; 116 | font-size: 38px; 117 | font-weight: normal; 118 | margin-bottom: 0; 119 | margin-left: -1px; 120 | letter-spacing: -1px; 121 | } 122 | 123 | h2 { 124 | margin-left: -1px; 125 | margin-top: 1em; 126 | color: #0d0d0d; 127 | font-size: 18px; 128 | font-weight: normal; 129 | } 130 | h2:after, h3:after { 131 | content: ":"; 132 | } 133 | 134 | h3 { 135 | font-size: 16px; 136 | font-weight: normal; 137 | } 138 | 139 | code { 140 | color: #3b5998; 141 | color: #314484; 142 | font: normal 86% "Monaco", "Courier New", "Courier"; 143 | } 144 | 145 | pre { 146 | display: block; 147 | background: #f5f6f7; 148 | margin: 1.5em 20px; 149 | padding: 10px 1.5em; 150 | -webkit-border-radius: 4px; 151 | -moz-border-radius: 4px; 152 | border-radius: 4px; 153 | white-space: pre-wrap; 154 | } 155 | 156 | pre code { 157 | color: #3b5998; 158 | color: #314484; 159 | font: normal 86% "Monaco", "Courier New", "Courier"; 160 | } 161 | 162 | a[href] { 163 | white-space: nowrap; 164 | text-decoration: none; 165 | color: inherit; 166 | padding: 1px .6em; 167 | background: #f5f6f7; 168 | background: rgba(0, 0, 0, .05); 169 | -webkit-border-radius: .6em; 170 | -moz-border-radius: .6em; 171 | border-radius: .6em; 172 | -webkit-transition: background .2s ease-out, -webkit-box-shadow .1s ease-out, color .15s ease-out; 173 | -moz-transition: background .2s ease-out, -webkit-box-shadow .1s ease-out, color .15s ease-out; 174 | -o-transition: background .2s ease-out, -webkit-box-shadow .1s ease-out, color .15s ease-out; 175 | } 176 | 177 | /* puts an * after external links, jodoc designates with .external */ 178 | a[href].external:after { 179 | content: "*"; 180 | font-style: super; 181 | opacity: .5; 182 | } 183 | 184 | a[href]:hover { 185 | background: rgba(0, 0, 0, .6); 186 | color: #fff; 187 | } 188 | 189 | pre code a[href], code a[href] { 190 | padding: 1px 0; 191 | -webkit-border-radius: 0; 192 | -moz-border-radius: 0; 193 | border-radius: 0; 194 | } 195 | 196 | /* 197 | vanilla markdown doesn't support tables, but since you can 198 | pass HTML through it, may as well put some nice styling for 199 | them in the CSS. 200 | */ 201 | table { 202 | width: 100%; 203 | margin: 1em auto; 204 | border-top: 1px solid #0d0d0d; 205 | border-left: 1px solid #0d0d0d; 206 | padding: 0; 207 | border-spacing: 0; 208 | text-align: center; 209 | } 210 | th { 211 | background: #36D2CF; 212 | background: #00a9a7; 213 | background: #07c7c3; 214 | padding: 5px; 215 | color: #fff; 216 | text-align: center; 217 | border-right: 1px solid #0d0d0d; 218 | border-bottom: 1px solid #0d0d0d; 219 | font-weight: bold; 220 | } 221 | 222 | th:first { 223 | border-left: 1px solid #0d0d0d; 224 | } 225 | 226 | td { 227 | padding: 5px; 228 | border-right: 1px solid #0d0d0d; 229 | border-bottom: 1px solid #0d0d0d; 230 | } 231 | 232 | td:first { 233 | border-left: 1px solid #0d0d0d; 234 | } 235 | 236 | /*
is used as a page separator in markdown */ 237 | hr { 238 | border: none; 239 | height: 70px; 240 | } 241 | hr:before { 242 | content: "\2026"; 243 | font-size: 50px; 244 | color: #e5e6e7; 245 | text-align: center; 246 | display: block; 247 | } 248 | 249 | #index { 250 | -webkit-column-width: 170px; 251 | -webkit-column-rule-width: 10px; 252 | -moz-column-width: 170px; 253 | -moz-column-rule-width: 10px; 254 | column-width: 170px; 255 | column-rule-width: 10px; 256 | column-width: 170px; 257 | column-rule-width: 10px; 258 | } 259 | #index h2:after, #index h3:after { content:""; } 260 | #index h2 { margin-left: 0; } 261 | #index>h2 { 262 | margin-top: 0; 263 | } 264 | #index { padding: 10px 1px; } 265 | #index ul { 266 | padding: 0; 267 | } 268 | #index ul li { 269 | list-style: none; 270 | } 271 | 272 | /* pretty printing */ 273 | @media print { 274 | body { 275 | max-width: none; 276 | margin: 0; 277 | font-size: 89%; 278 | } 279 | 280 | h1, h2 { 281 | page-break-after: avoid; 282 | } 283 | 284 | h1>p, h2>p{ 285 | page-break-before: avoid; 286 | } 287 | 288 | pre { 289 | page-break-before: auto; 290 | page-break-inside: avoid; 291 | } 292 | 293 | blockquote { 294 | page-break-inside: avoid; 295 | } 296 | 297 | hr { 298 | page-break-before: always; 299 | font-size: inherit; 300 | height: auto; 301 | } 302 | hr:before { 303 | height: auto; 304 | content: ""; 305 | font-size: inherit; 306 | } 307 | 308 | a[href] { 309 | background: none; 310 | padding: 0; 311 | -webkit-border-radius: none; 312 | -moz-border-radius: none; 313 | border-radius: none; 314 | } 315 | 316 | #index { 317 | display: none; 318 | } 319 | } 320 | 321 | -------------------------------------------------------------------------------- /samples/css/docbody.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fff; 3 | font: normal 100% "Georgia", "Palatino", "Times New Roman", "Times"; 4 | /* font: normal 100% "Gill Sans", "Verdana", "Arial"; */ 5 | line-height: 1.6; 6 | padding: 0 1em; 7 | color: #383838; 8 | font-size: 15px; 9 | margin: 0 auto; 10 | max-width: 700px; 11 | } 12 | -------------------------------------------------------------------------------- /samples/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | joDoc Simple Frame Test 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/template.html: -------------------------------------------------------------------------------- 1 | 2 | $title$body 3 | --------------------------------------------------------------------------------