© 2019 Meouzer Consortium

Guide to JSHTML: Displaying JavaScript in HTML

loading
Programmers ask me all the time. Meouzer! How do I display great JavaScript code in HTML that I can be proud of? I say it's just just 50,000 lines of JSHTML that form the basis of every great JavaScript display! Meouzer

Introduction

To allow JSHTML to convert JavaScript in HTML to formatted JavaScript first include JSHTML.js and JSHTML.css in the header.

<link href="../00-Commons/JSHTML.css" rel="stylesheet" type="text/css" />
<script src="../00-Commons/JSHTML.js"   type="text/javascript" id="script"></script>
	

Then call applyJSHTML() after the window or body has loaded, e.g.,

//In some script in the header window.addEventListener("load", function() { applyJSHTML(); });

Then all divs of class codeBox will have their unformatted JavaScript neatly formatted, with appropriate indentations, code numbers, and colorization. A code box is a div with class codeBox.

The previous box shows formatted JavaScript in a code box. Originally, the JavaScript in the code box could look like the following, but JSHTML don't care. It don't give a schmuck! It will format anyway.

		window.addEventListener("load",        function() 
		                          {
			                                          applyJSHTML();							
	  });		
	

As you can see JSHTML respects line breaks in the unformatted code, turning them into HTML breaks <br> in the formatted code.

The Four Types of Indentations

Indentations
function foo (x) { x = func(a,b, // telescoping implicit indents c,d,e, // 1 implicit indent f,g,h, // add another implicit indent i,j,k); // add another implicit indent   // telescoping stops when statement is complete switch(x) { case "cat": x++;

Switch Specialist

loading switch(y) { case 1: z++; /* comment comment */ y++; default: /* comment comment*/ "An oyster met an oyster "; y++; } break; } }

This paragraph mixed in with the JavaScript code introduces the following table, also mixed in with the JavaScript code, explaining the four indentations.

The Four Indentations
IndentationDescriptionDefaultExample
Lines
body indentThe indentation from the left
edge to the main body of code
4 x &nbsp; 1
brace indentThe indentation from a left brace
to subsequent code
4 x &nbsp; 2, 7, 10
case indentThe indentation from a case X:
to subsequent code
5 x &nbsp; 8-9, 11-12,
14-15
implicit indentThe indentation for
uncompleted statements.
4 x &nbsp; 3-5
/* To set your default preferences go to the following code in JSHTML.js and change the values maybe. Then you shouldn't need to pass applyJSHTML() any parameter. */ \numbersRestart const DEFAULT_BODY_INDENT = 4; const DEFAULT_BRACE_INDENT = 4; const DEFAULT_IMPLICIT_INDENT = 4; const DEFAULT_CASE_INDENT = 5; const DO_TELESCOPE_IMPLICIT_INDENT = true; /* For a particular web page you can override the defaults by passing applyJSHTML(p) a parameter that looks like the following. All attributes of p are optional. */ \numbersOff p = {bodyIndent:5, braceIndent:6, implicitIndent:3, caseIndent:5, doTelescope:false}; /* A particular code box can override the two higher level defaults by using the attributes
  1. data-bodyIndent
  2. data-braceIndent
  3. data-ImplicitIndent
  4. data-caseIndent
  5. data-doTelescope
*/

Code Numbers

A code box with attribute data-codeNumbers and value true will have code numbers displayed. Code numbers are displayed only for lines that have code. Displaying numbers for all lines isn't useful and would make the code box look too busy.

<div class="codeBox" data-codeNumbers="true">
	

The Number Shield and Code Listing

To put a shield over the numbers, after the start tag of the code box write an empty div with class numberShield as demonstrated. To give the code box a code listing, which is a number in the top right corner enumerating the code boxes, write an empty div with class codeListing as demonstrated. Both are optional and order of writing doesn't matter.

<div class="codeBox colorLightPink rounded" data-codeNumbers="true">
	<div class="numberShield colorLightBurlywood"></div>
	<div class="codeListing"></div>

		

Number Directives

You can put a number directive on its own line (with nothing else) to turn code numbering off, turn code number back on, or restart code numbering at 1.

Double clicking on a code numbered code box will cause the code numbers to disappear. Double clicking again will bring the code numbers back.

Number Directives
DirectiveDescription
\numbersOffstop subsequent code numbering
\numbersOnturn subsequent code numbering back on
\numbersRestartrestart code numbering at number 1

Fine Tuning Indentation

Use indentation directives to fine tune or change indentations. Only on rare occasions should this be useful. An indentation directive must not be written on its own line. Indentation directives belong at the start of a line of code or at the end of a line of code.

The indentation directives take the form \^xy or \$xy, where x and y are two decimal digits with x usually being zero. At the start or end of a line of code \^xy will move subsequent indentations to the right by xy spaces. At the start or end of a line of code \$xy will move subsequent indentations to the left by xy spaces.

For example the following unformatted JavaScript code

		<div class="codeListing"></div>
		x = func(a,b,
		\^09c,d,e,
		f,g,h,
		i,j,k);\$09	
	
will produce the following formatted JavaScript code.
x = func(a,b, \^09c,d,e, f,g,h, i,j,k);\$09
Compare this with lines 2-5 of code listing 1 to observe the difference.

Turn Telescoping of Implicit Indents on or off

Observe from code listing 2 that the implicit indent telescopes. For each line of code that does not end the statement, the indentation increases by the implicit indent each time. You might prefer a non telescoping implicit indent shown as follows.

x = func(a, b,
         c, d, e,
         f, g, h,
         i, j, k);
	

In JSHTML.js, search for var DO_TELESCOPE_IMPLICIT_INDENT and change it's value to false to make non telescoping implicit indents the default.

Also, for a particular code box you can override the default by setting the data-doTelescope attribute to "true" or "false". You can also override the previous two by using the two directives written on their own lines: \telescopeOff; \telescopeOn.

Comments

You can see from code listing 1 that JSHTML knows how to place block comments so that everything looks nice and neat. Block comments condense white space.

JSHTML also knows how to place EOL comments. EOL comments respect white spaces, both before and after "//", and does not condense them.

Look at the EOL comments in code listing 1. You can align all five comments by using white space before the comment. To align comment 5, which is on its own line, write one hard space &nbsp; at the beginning of the line and then as many soft white spaces as are needed for alignment. Alignment is always done by trial and error when fonts that aren't monospace are used.

The Code Header

In code listing 1, a code header is shown displaying the text "Indentations." The code header comes before any JavaScript code. Here is how it is achieved.

<div class="codeBox colorLightPink rounded" data-codeNumbers="true">
	<div class="numberShield colorLightBurlywood"></div>
	<div class="codeListing"></div>	
	<header class="codeHeader colorLightBurlywood"></div>
		Indentations 		
	</header>	
	

Inside the code header is pure HTML, so the <br> tag is used for line breaks.

The number shield, code listing, and code header are all optional an can be written in any order. The code listing may be placed in the code header.

The Code Section

A code section is a code header for subsequent code, used after some previous code is displayed.

The userType() Function
function userType(x) { if (x === null) return "null"; if (typeof (x) != 'object' && typeof (x) != 'function') return typeof (x); try { x.constructor; } catch(e) { return "CrossOriginObject";} etc; ...; }
Code Section with Code Numbers Restarting at 1
\numbersRestart function foo(){} function bar(){}
function foobar(){};

Here's the pertinent code.

function userType(x) 
{    
	if (x === null) return "null";
	if (typeof (x) != 'object' && typeof (x) != 'function') return typeof (x);
	try { x.constructor; } catch(e) { return "CrossOriginObject";} 
	        
	etc;
	...;       
} 
	    
<header class="codeSection colorLightBurlywood">
	Code Section with Code Numbers Restarting at 1
</header>
       	\numbersRestart
       	
	function foo(){}
	function bar(){}
	<hr>
	function foobar(){};

	

You can also section the code box by using the <hr> tag.

Mixing in HTML with the JavaScript Code

If xyz is any HTML element other than div, then the element displays pure HTML. That is <xyz>...</xyz> is pure HTML even if it contains div elements.

So divs, not in any non-div element, define the structure of the formatted JavaScript, while other elements output pure HTML.

Double Quoted Code

You might want to quote code for eval to operate on.

const ceFactory = function() { return eval("\c(function(" + Object.keys(arguments[0]) + "\c)\ {\ return function(){return eval('('+arguments[0]+')');}\ }).apply(null,Object.keyValues(arguments[0]));"); }

To achieve this effect write \c after beginning quotes as in "\c(function(" and "\c)\.

Default Styling Preferences

Styling of course is done with JSHTML.css. You should be able to tell where it's too dangerous to modify. However, to set the font of the JavaScript code, and also the font of the HTML mixed in with the JavaScript, to your default preferences see the last two lines of JSHTML.css.

Code Tables Using Nested Divs

Simple Facts about Eval
Out of strict mode may declare variable inside eval
 
(function() { function sum(a,b){return a + b;}; eval('var sumCopy = ' + sum); //line 3 bombs if strict mode used alert(sumCopy(1,2)); // alerts 3 })();
In strict mode declare top level variable outside of eval
(function( { 'use strict'; function sum(a,b){return a + b;} var sumCopy; //declare outside eval eval('sumCopy = ' + sum); alert(sumCopy(1,2)); //alerts 3 })();
eval as a string defining function requires
( and ) as prefix and suffix.
(function( { "use strict"; var x = eval('(function(){return a + b;})'); alert(x(1,2)); //alerts 3 })();
may declare variable inside eval if it's nested inside a function string
(function( { "use strict"; var x = eval(function(){var a = 7; alert(a);}); x(); //alerts 7 })();

It's too complicated to display the code that produces this. So just look inside this file. It's named index.html and lies in the 06-JSHTML-Guide directory.

Here's a variant of the code box above.

Simple Facts about Eval
Out of strict mode may declare variable inside eval
 
(function() { function sum(a,b){return a + b;}; eval('var sumCopy = ' + sum); //line 3 bombs if strict mode used alert(sumCopy(1,2)); // alerts 3 })();
In strict mode declare top level variable outside of eval
(function( { 'use strict'; function sum(a,b){return a + b;} var sumCopy; //declare outside eval eval('sumCopy = ' + sum); alert(sumCopy(1,2)); //alerts 3 })();
eval as a string defining function requires
( and ) as prefix and suffix.
(function( { "use strict"; var x = eval('(function(){return a + b;})'); alert(x(1,2)); //alerts 3 })();
may declare variable inside eval if it's nested inside a function string
(function( { "use strict"; var x = eval('(function(){var a = 7;alert(a);})'); x(); //alerts 7 })();