Introduction
I am writing a lot of tutorials explaining some code and I found the best way to explain for example a JavaScript to be:
- Show what it does
- Show the whole script
- Repeat the script intersected by explanations what each part does.
The problem I found is that when you want to change something in the script (for example fix a bug) you'll have to change it both in the script and in the tutorial and many a time this will get out of sync.
This is why I wrote Tutorialbuilder which is a PHP script that does all the work for me:
- It generates the tutorial parts from comments in the script source code.
- It converts the source code to displayable code (encoding it, adding line numbers, allowing for lines to be highlighted)
- It creates a downloadable version of the script with a correct file name
- It creates an executable version of the script without comments to link to with a script element.
- It can minify the script (remove all whitespace to cut down on file size)
Example
As an example let's take a demo script and display it. The final outcome of the steps explained here can be seen in the example.php file. The first thing you need to do is include the Tutorialbuilder code and initialize a new instance with the script url as a parameter:
<?php
include('tutorialbuilder.php');
$docs = new tutorial;
$docs->maketutorial('democode.js');
?>
The script only allows for displaying code in the same folder!
Once you've added these few lines and used the right syntax in the comments of your script all is ready to go. The full script with comments in the right format reads like this:
- 1: /*startmeta
- 2: name: Demo script
- 3: title: This would be the documentation page for the demo script
- 4: date: 11/05/2008
- 5: description: This is just a demo script that shows you all the options you have using Tutorialbuilder
- 6: tags: tag1,tag2,tag3
- 7: version:2.0
- 8: authors:Christian Heilmann (http://wait-till-i.com),John Doe
- 9: license:BSD license (http://wait-till-i.com/license.txt)
- 10: endmeta */
- 11: /*
- 12: We're using the "revealing module pattern":http://www.wait-till-i.com/2007/08/22/again-with-the-module-pattern-reveal-something-to-the-world/ to define the main script. In this case, the main module name will be #helloWorld#.
- 13: */
- 14: helloWorld = function(){
- 15: /*
- 16: You can use both lists and definition lists:
- 17: startdeflist
- 18: - #foo#
- 19: -- this is a bar
- 20: - #CSS#
- 21: -- An object that contains CSS information
- 22: enddeflist
- 23: startlist
- 24: * list item 1
- 25: * list item 2
- 26: * list item 3
- 27: endlist
- 28: Text surrounded by linebreaks will be turned into paragraphs.
- 29: Each word enclosed in hashes will become #code#, words in asterisks will become *strong*.
- 30: */
- 31: var config = {
- 32: foo:'bar',
- 33: CSS:{
- 34: ids:{
- 35: menu:'menu',
- 36: footer:'footer'
- 37: },
- 38: classes:{
- 39: demo:'demo',
- 40: highlight:'current'
- 41: }
- 42: }
- 43: };
- 44: /*
- 45: Any comment in the code will intercept the code display and turned into explanations
- 46: */
- 47: function init(){
- 48: if(window.console){
- 49: console.log('init was here');
- 50: alert('script executed!')
- 51: }
- 52: };
- 53: /*
- 54: If you want to highlight a certain line, add a double slash followed by a star at the end of it.
- 55: */
- 56: function otherStuff(){
- 57: if(window.console){
- 58: console.log('this would be other stuff');
- 59: }
- 60: };
- 61: return {
- 62: init:init
- 63: };
- 64: /*
- 65: You can add links by adding "words in quotes followed by a colon and the url":http://example.com.
- 66: */
- 67: }();
- 68: helloWorld.init();
You need to start with a meta section that contains information about the script.
The meta section
The meta section is enclosed by /*startmeta and endmeta*/ and contains name and value pairs separated by a colon. They are the following, if your instantiation is called docs as in this example here:
Comment syntax
The comments containing the explanations for the different parts of the script need to be enclosed in /* and */ and are by default turned into paragraphs (double line break means a new paragraph). In addition to this you have other special syntax options:
- Words enclosed in hashes will become code samples, for example #code# becomes
code. - Words enclosed in asterisks will become strong, for example *strong* becomes strong.
- Words in quotation marks, followed by a colon and a URL will become a link, for example "example":http://example.com becomes example.
You also have options for lists instead of paragraphs:
startdeflist
- term
-- definition
- term 2
-- definition 2
enddeflist
Gets turned into a definition list:
<dl>
<dt>term</dt>
<dd>definition</dd>
<dt>term 2</dt>
<dd>definition 2</dd>
</dl>
startlist
* foo
* bar
* baz
endlist
Gets turned into an unordered list
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
Displaying the tutorial
Tutorialbuilder offers the script for displaying in several formats: a raw version with all comments and no highlights, a full script with line numbers and highlighted lines, and the tutorial with all the HTML explained above. Regardless of which version you choose, the code portions of the output are converted into an ordered list of code lines preceded by line numbers in span elements inside a pre element. Highlighted lines (the ones ending in // * in the source) will get a class called highlight:
<pre>
<ol>
<li><span>20:</span> function otherStuff(){</li>
<li><span>21:</span> if(window.console){</li>
<li class="highlight"><span>22:</span> console.log('this would be other stuff');</li>
<li><span>23:</span> }</li>
<li><span>24:</span> };</li>
<li><span>25:</span> return {</li>
<li><span>26:</span> init:init</li>
<li><span>27:</span> };</li>
</ol>
</pre>
This gives you plenty of hooks to style the output to your needs.
To display the code or the tutorial you need to echo the right property of your Tutorialbuilder instance:
<?php echo $docs->rawscript;?>
Displays the script as-is - including the comments of Tutorialbuilder.
<?php echo $docs->script;?>
Displays the whole script without comments
<?php echo $docs->documentation;?>
Displays the whole tutorial with code chunks and explanations.
Linking to an executable code version
If you want to offer an example of the script outcome on the tutorial page (which is highly advisable) all you need to do is to link a script element to the tutorialbuilder.php file with a build parameter.
This will remove all the comments of the script and create an executable version.
A executable script link could be:
<script src="tutorialbuilder.php?build&filename=democode.js"></script>
The parameters are:
- build (mandatory)
- prompts the build
- filename (mandatory)
- the file name of the source file
- minified
- This is a boolean, by default the download option minifies the script (removes all whitespace). If you don't want that, set minified to false
Offering a downloadable version
Tutorialbuilder also allows you to offer a downloadable version of the script you document. In order to offer this, you need to link to the tutorialbuilder.php file with some parameters. The builder then sends the script with a "text/javascript" mime type as an attachment to the browser.
A download link could be:
<a href="tutorialbuilder.php?download&filename=source.js&output=scriptv1.js">download</a>
The parameters are:
- download (mandatory)
- prompts the download
- filename (mandatory)
- the file name of the source file
- output
- the file name of the download
- minified
- This is a boolean, by default the download option minifies the script (removes all whitespace). If you don't want that, set minified to false
License and Copyright
The script is copyright Christian Heilmann and licensed under the BSD license. This means you can use it for free - even commercially if you keep my copyright intact.
Download Tutorialbuilder and example code
The following download link contains the Tutorialbuilder script, the example JavaScript, the example page, all the CSS (partly YUI) and this information page.