JCite By Example
This is a quick demo of JCite. You can use it to cite fragments of Java source code in HTML documentation. This is especially useful if the cited fragments are part of automated tests, thus ensuring their correctness.
Citing Entire Blocks
Using JCite, you can cite entire blocks, such as methods, classes, etc., including, if desired, their JavaDoc comments. Let’s, for example, cite an entire method:
/** * This is a <b>sample</b> method. Just like {@link #sampleCode()}. * * @author Peter Arrenbrecht */ void sampleMethod() { // This is a quick test of JCite. sampleMethod(); if ("a" == "b") System.out.println( "Oops!" ); try { int a = 1; System.out.println( a ); } finally { System.out.println( "Done." ); } }
This was produced by the following JCite instruction in the source HTML document:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleMethod]
The part ch.arrenbrecht.jcite.examples.JCiteSampleCode
tells JCite what Java class’s source to cite from. The part ---- sampleMethod
tells it what fragment to cite. You surround citable fragments with special comments in the source code:
// ---- sampleMethod /** * This is a <b>sample</b> method. Just like {@link #sampleCode()}. * * @author Peter Arrenbrecht */ void sampleMethod() { // This is a quick test of JCite. sampleMethod(); if ("a" == "b") System.out.println( "Oops!" ); try { int a = 1; System.out.println( a ); } finally { System.out.println( "Done." ); } } // ---- sampleMethod
The part ---- sampleMethod
is freely choosable. It must simply match the respective comment in the source file.
Style Sheet
The formatting of the generated output is controlled by a CSS style sheet.
Note
In the following examples, I shall simply put the JCite instruction for the source HTML document directly above the respective sample output.
Individual Snippets
You can also cite smaller fragments of code if you annotate your source code accordingly. Here’s an example of such annotated source code:
void sampleCode() { // This is not part of the sample. int a; // ---- fragment1 if (1 == 2) a = 0; else a = 1; // ---- fragment1 int b; // ---- fragment2 // Part 1 if (a == 1) { b = 0; } else { b = 1; } // ---- fragment2 int c; // ---- fragment2 // Part 2 c = a + b; // ---- fragment2 System.out.println( c ); System.out./* -lineFragment- */println( "Hello, world!" )/* -lineFragment- */; }
From this, we can cite a fragment of two lines:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- fragment1]
if (1 == 2) a = 0; else a = 1;
Or a fragment consisting of multiple snippets of code taken from the source file:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- fragment2]
// Part 1 if (a == 1) { b = 0; } else { b = 1; } // Part 2 c = a + b;
We can also display line fragments:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:-lineFragment-]
println( "Hello, world!" )
Highlighting
With JCite you can highlight parts of the cited code. Given the following source code:
void sampleHighlighting() { // ---- sampleHighlighting int a = 0; // -hl- int b = 1; // -hl- int c = a + 2 /* -hl- */* b/* -hl- */; System.out.println( c ); // ---- sampleHighlighting }
We highlight an entire line and a line fragment:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleHighlighting; highlight -hl-]
int a = 0; int b = 1; int c = a + 2 * b; System.out.println( c );
If you just want to highlight line fragments, there is an even shorter version. You simply surround each part in the source code which JCite should highlight with /**/.../**/
, as in:
void simpleHighlighting() { int b = 1; // ---- simpleHighlighting int c = 2 /**/* b/**/; System.out.println( c ); // ---- simpleHighlighting }
Then you can cite the fragment without needing to tell JCite what to highlight (no highlight
part in the jc
instruction).
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- simpleHighlighting]
int c = 2 * b; System.out.println( c );
Eclipse’s code formatter sometimes removes spaces around JCite’s highlighting comments, like so:
abstract class Foo { // ---- fixedHighlighting abstract/**/int/**/bar(); abstract/**/int[]/**/baz(); abstract/**/Collection<String>/**/duh(); void doh() { int /**/var/**/= 0; } // ---- fixedHighlighting }
JCite therefore inserts spaces around highlights if otherwise a highlighted and a non-highlighted letter or digit or =
sign would be adjacent. It also handles spacing for closing })]>,;
characters. Here’s an example:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- fixedHighlighting]
abstract int bar(); abstract int[] baz(); abstract Collection<String> duh(); void doh() { int var = 0; }
Omissions
You can omit parts from cited fragments, too. This can be used to show the buildup of a method. Given the following source:
void sampleOmission() { // ---- sampleOmission int a = 0; // -try- try { // -try- something(); // -try- } finally { cleanup(); } // -try- System.out.println( a ); // ---- sampleOmission }
We first show the method without the try-finally block (note that JCite does not currently support correcting indentation levels; this is a planned feature):
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleOmission; omit -try-]
int a = 0; something(); System.out.println( a );
Then, including the block, highlighted:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleOmission; highlight -try-]
int a = 0; try { something(); } finally { cleanup(); } System.out.println( a );
Or, including the block, without highlighting:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleOmission; strip -try-]
int a = 0; try { something(); } finally { cleanup(); } System.out.println( a );
You can strip multiple internal markers:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- fragmentSrc; strip ---- fragment1; strip ---- fragment2; strip -lineFragment-]
void sampleCode() { // This is not part of the sample. int a; if (1 == 2) a = 0; else a = 1; int b; // Part 1 if (a == 1) { b = 0; } else { b = 1; } int c; // Part 2 c = a + b; System.out.println( c ); System.out.println( "Hello, world!" ); }
Hint
If you forget to specify strip -try-
, you get the block with internal marker comments left intact:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- sampleOmission]
int a = 0; // -try- try { // -try- something(); // -try- } finally { cleanup(); } // -try- System.out.println( a );
Showing /**/
Markers
Not that you’d need to, but for the sake of completeness, here’s how to cite code with the internal highlighting markers of the form /**/
left intact:
[jc:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- simpleHighlighting;show]
int c = 2 /**/* b/**/; System.out.println( c );
Citing Entire Files
Sometimes you simply want to cite entire class files. This can be done as follows:
[jc:ch.arrenbrecht.jcite.examples.AdderTest]
/* * Copyright (c) 2006 Peter Arrenbrecht * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - The names of the contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Contact information: * Peter Arrenbrecht * http://www.arrenbrecht.ch/jcite */ package ch.arrenbrecht.jcite.examples; import junit.framework.TestCase; public class AdderTest extends TestCase { public void testAddTo() throws Exception { // -- useCase Adder ten = new Adder( 10 ); int result = ten.addTo( 5 ); // -- useCase assertEquals( 15, result ); } public void testAdd() throws Exception { // -- add int sum = Adder.add( 1, 2 ); // -- add assertEquals( 3, sum ); } // ---- fullPathTarget public void testGetAddend() throws Exception { // -- getAddend Adder one = new Adder( 1 ); int addend = one.getAddend(); assertEquals( 1, addend ); // -- getAddend } // ---- fullPathTarget }
Formatting Inline Blocks
While I don’t recommend it for hand-written examples, sometimes you may want to highlight source code generated during test runs. For this, JCite supports inlined blocks. You enclose them in pre
blocks with the jcite="..."
attribute, where ...
is the markup for the citelet to use. jc
is the markup for the Java source code citelet. Example:
<pre jcite="jc">public void /**/foo/**/() { bar(); }</pre>
public void foo() { bar(); }
Citing Without Syntax Highlighting
All of the above also works for citations without syntax highlighting. Just use a jcp:
prefix instead of jc:
(where the “p” stands for plain). So:
[jcp:ch.arrenbrecht.jcite.examples.JCiteSampleCode:---- fixedHighlighting]
abstract int bar(); abstract int[] baz(); abstract Collection<String> duh(); void doh() { int var = 0; }