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;
}