Loading...

Thursday, November 20, 2014

Awesome Asciidoctor: Changing the Grid and Frame of Tables

We can change the frames and grid of tables we define in Asciidoctor. We use the frames attribute to change the outside frame of a table. We can choose between topbot for top and bottom, sides for only a frame at the sides of the table, none if we don't want a frame. The default value all create a frame around our table with top, sides and bottom.

To change the inner grid of a table we use the grids table attribute. The default value all displays a grid for columns and rows inside the table. The value cols only displays a grid between columns, value rows display a grid between rows and with value none there will be no grid inside our table.

The following Asciidoc sample shows the definition of four tables with different values for the cols table attribute:

.Table with top and bottom frame (topbot)
[frame="topbot"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 


.Table with no frame (none)
[frame="none"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 


.Table with only sides frame (sides)
[frame="sides"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 


.Table with default frame (all)
[frame="all"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

When we generate output using the HTML backend we get the following result:

In the next sample we have four tables with different values for the cols attribute:

.Table with no grid (none)
[grid="none", frame="none"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

.Table with only columns grid (cols)
[grid="cols", frame="none"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

.Table with only rows grid (rows)
[grid="rows", frame="none"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

.Table with default rows and columns grid (all)
[grid="all", frame="none"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

And we get the following output when we transform this source to HTML:

Written with Asciidoctor 1.5.1.

Monday, November 17, 2014

Gradle Goodness: Check Task Dependencies With a Dry Run

We can run a Gradle build without any of the task actions being executed. This is a so-called dry run of our build. We can use the dry run of a build to see if the task dependencies we have defined or are defined in a plugin are defined properly. Because all tasks and task dependencies are resolved if we use the dry run mode we can see in the output which tasks are executed.

We define a simple build file with three tasks and some task dependencies:

def printTaskNameAction = {
    println "Running ${it.name}"
}

task first << printTaskNameAction

task second(dependsOn: first) << printTaskNameAction

task third(dependsOn: [first, second]) << printTaskNameAction

To run a Gradle build as a dry run we can use the command line option -m or --dry-run. So let's execute the task third with the dry run command line option:

$ gradle -m third
:first SKIPPED
:second SKIPPED
:third SKIPPED

BUILD SUCCESSFUL

Total time: 2.242 secs
$ 

And we see in the output none of the tasks are really executed, because SKIPPED is shown, but we do see the task names of the tasks that are resolved.

Written with Gradle 2.2.

Wednesday, November 12, 2014

Awesome Asciidoctor: Use Asciidoctor Diagram with Gradle

Since Asciidoctor 1.5.0 we can use extensions when we write AsciiDoc documents. These extensions can be written in Ruby or any JVM language. If we use Gradle and the Asciidoctor Gradle plugin to transform our documents we can use both extensions. Of course an extension written in for example Java or Groovy can be included as a regular dependency in our build configuration. As the extension is on the classpath of the asciidoctor task then it can be used. When the extension is a Ruby extension and available as a Ruby gem we need some more configuration in our build file. To use an Asciidoctor extension written in Ruby in our build we must first make sure that we can download the extension. Then we can configure the asciidoctor task from the Asciidoctor Gradle plugin to use the extension.

Let's start with a sample Asciidoctor document which uses the Asciidoctor Diagram extension. With this extension we can embed diagrams as text in our document and get graphical images as output.

= Sample diagram

:imagesdir: images

== Ditaa

// Sample diagram from Asciidoctor Diagram website
// http://asciidoctor.org/docs/asciidoctor-diagram/

[ditaa, "asciidoctor-diagram-process"]
....
                   +-------------+
                   | Asciidoctor |-------+
                   |   diagram   |       |
                   +-------------+       | PNG out
                       ^                 |
                       | ditaa in        |
                       |                 v
 +--------+   +--------+----+    /---------------\
 |        |---+ Asciidoctor +--->|               |
 |  Text  |   +-------------+    |   Beautiful   |
 |Document|   |   !magic!   |    |    Output     |
 |     {d}|   |             |    |               |
 +---+----+   +-------------+    \---------------/
     :                                   ^
     |          Lots of work             |
     +-----------------------------------+
....

Next we create our Gradle build file. We must apply the Asciidoctor Gradle plugin so we can transform our AsciiDoc documents. And we must apply the JRuby Gradle plugin so we can download Ruby gems and use them from the asciidoctor task. The JRuby plugin adds a gems dependency configuration, which we can use to define the Ruby gems we need. The task jrubyPrepareGems is also added by the plugin and this task will download the gems and extract them in our project build directory. In our asciidoctor task that is added by the Asciidoctor plugin we use the requires property to specify which gem is needed. We also set the gemPath property to the directory which contains the downloaded and extracted Ruby gems. The following build file defines the plugins and configures the tasks we need so we can use Asciidoctor Diagram:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.0'
        classpath 'com.github.jruby-gradle:jruby-gradle-plugin:0.1.5'
    }
}

// Plugin so we can render AsciiDoc documents.
apply plugin: 'org.asciidoctor.gradle.asciidoctor'
// Plugin so we can use Ruby gems when rendering documents.
apply plugin: 'com.github.jruby-gradle.base'


dependencies {
    // gems dependency configuration is added by
    // jruby-gradle-plugin. Here we define
    // the gems we need in our build.
    gems 'rubygems:asciidoctor-diagram:1.2.0'
}

asciidoctorj {
    // We can change the AsciidoctorJ 
    // dependency version.
    version = '1.5.1'
}

asciidoctor {
    // jrubyPrepareGems task is added by the JRuby 
    // plugin and will download Ruby gems we have
    // defined in the gems dependency configuration.
    dependsOn jrubyPrepareGems

    // Asciidoctor task needs the
    // asciidoctor-diagram gem, we installed
    // with the jrubyPrepareGems task and
    // gems dependency configuration.
    requires = ['asciidoctor-diagram']

    // Set path to find gems to directory
    // used by jrubyPrepareGems task.
    gemPath = jrubyPrepareGems.outputDir
}

defaultTasks 'asciidoctor'

To generate our sample document we only have to run $ gradle from the command line. After the documents are generated we can the result in the build/asciidoc directory of our project. The following screenshot shows the generated HTML:

Written with Asciidoctor 1.5.1 and Gradle 2.1.

Monday, November 10, 2014

Awesome Asciidoctor: Styling Columns and Cells in Tables

In a previous post we learned how to use Asciidoc markup in a table. The a character is just one of many styles we can define in our table. In this blog post we see which style options we have. We can either use the cols attribute to define a style for a whole column or specify per cell the style.

We can use the following styles:

  • e: emphasized
  • a: Asciidoc markup
  • m: monospace
  • h: header style, all column values are styled as header
  • s: strong
  • l: literal, text is shown in monospace font and line breaks are kept
  • d: default
  • v: verse, keeps line breaks

The following Asciidoctor source uses the different styles as cols attribute values:

.Table with column style e,a,m
[cols="e,a,m"]
|===
| Emphasized (e) | Asciidoc (a) | Monospaced (m)

| Asciidoctor
| NOTE: *Awesome* way to write documentation
| It is just code

|=== 

.Table with column style h,s,l
[cols="h,s,l"]
|===
| Header (h) | Strong (s) | Literal (l)

| Asciidoctor
| Awesome way to write documentation
| It is 
just code

|=== 


.Table with column style d,v
[cols="d,v"]
|===
| Default (d) | Verse (v)

| Asciidoctor
| Awesome way 
to write 
documentation

|=== 

When we transform this into HTML using the Asciidoctor HTML backend we get the following result:

We can also override a column styling per cell. We must put the correct styling character before the pipe symbol (|), so the contents of the cell is styled differently:

Table with row style e,a,m in second row
|===
| Emphasized | Asciidoc | Monospaced

| Asciidoctor
| NOTE: *Awesome* way to write documentation
| It is just code

e| Asciidoctor
a| NOTE: *Awesome* way to write documentation
m| It is just code

|=== 

And the following HTML is generated when we process this Asciidoctor source:

Written with Asciidoctor 1.5.1.

Awesome Asciidoctor: Using Asciidoc in Tables

When we define a table in Asciidoctor and want to use Asciidoc in a table cell it is not interpreted as Asciidoc by default. The text is literally shown and this might not be what we expect. But we can force Asciidoctor to interpret the cell contents as Asciidoctor.

Let's start with a very simple table. The last cell of the first row contains some Asciidoc markup:

:icons: font

// Simple table where we apply some
// Asciidoc markup in the cell contents.

|===
| Name | Description

| Asciidoctor
| NOTE: *Awesome* way to write documentation

|===

When we transform this Asciidoctor source to HTML we see the following output:

Notice that we don't get a nice image for our NOTE is not shown as image when it used in a table cell.

To change this behavior we can configure the table. We can configure a column to have Asciidoc content that needs to be interpreted or we can configure at cell level we want the contents to be interpreted as Asciidoc. We use the character a in the cols attribute when we define the table. Or we use the character a before the table cell separator (|). In the next sample Asciidoctor file we use both ways to make sure the cell contents is Asciidoc markup that needs to be transformed as well:

:icons: font

// We use the cols attribute for our table
// and specify that the contents of the second
// column is Asciidoc markup.

[cols=",a"]
|===
| Name | Description

| Asciidoctor
| NOTE: *Awesome* way to write documentation

|===


// Or we configure per cell the contents
// is Asciidoc markup.

|===
| Name | Description

| Asciidoctor

// We specify for this specific cell the 
// contents is Asciidoc that needs to 
// be processed.
a| NOTE: *Awesome* way to write documentation

|===

Once we have defined the table we get the following generated HTML:

And this time the cell contents is transformed as well.

Written with Asciidoctor 1.5.1.

Friday, November 7, 2014

Awesome Asciidoctor: Changing Table and Column Width

When we define a table in Asciidoctor the columns all have the same width and the table will the whole width of the page. Of course we can change this when we define the table. We can change the table width with the width attribute. We specify the column width with the cols attribute.

First we will change the width of the columns. We can specify proportional integer values or a percentage to specify the width of a column. In the following sample Asciidoctor file we use proportional values in the first table. The first column has value 1 and the second column value 3. This means the second column should be 3 times as wide as the first column. In the second table the column width is defined with percentage values. The first column should occupy 60% of the table width and the last column the rest.

// Define table with proportional column width.

.Table with relative column widths (1,3)
[cols="1,3"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 


// Define table with column width as percentage values.

.Table with percentage column widths (60%,40%)
[cols="60%,40%"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

When we transform the Asciidoctor source to HTML we get the following result:

We see in the examples that the width of the table is the same as the width of the page. To make a smaller table we set the width attribute for a table. The value must be a percentage. Let's create a sample Asciidoctor file and define a table with a width of 50%:

// Define table with default width for comparison.

.Table full width (default)
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 


// Define new table and set width to 50%.

.Table half width (50%)
[width="50%"]
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

|=== 

And if we look at the generated HTML for example we can see the second table is half the width of the first:

Written with Asciidoctor 1.5.1.

Thursday, November 6, 2014

Awesome Asciidoctor: Table Column and Cell Alignment

Creating a table with Asciidoctor is a breeze. The syntax is very clear and the HTML output shows a very nice looking table. But there is also a lot of configuration we can do when we define a table. For example by default all columns are left aligned, but we can change this to have values centered or right aligned in columns. We can even set the vertical alignment for columns. And if this is not enough we can change the horizontal and vertical alignment per cell.

Let's start with a simple table with three columns. We want the first column to be centered, the middle column to be left aligned and the last column should be right aligned. To achieve this we must configure the cols attribute for our table definition. We use the following symbols to define the alignment:

  • <: left align values (default)
  • >: right align values
  • ^: center values

We create a new Asciidoctor file with the following contents:

// File: table.adoc

// We define a table with 3-columns.
// First column is centered, 
// second column is left aligned and
// third column is right aligned.

[cols="^,<,>", options="header"]
|===

| Name
| Description
| Version

| Asciidoctor
| Awesome way to write documentation
| 1.5.0
|===

When we create HTML output from this source we get the following output:

We have now defined the horizontal alignment. To include vertical alignment we must add dot (.) to the horizontal alignment value and then the vertical alignment value. The following vertical alignment values can be used:

  • <: top align values (default)
  • >: bottom align values
  • ^: center values

In the following sample Asciidoctor file we add vertical alignment configuration to our previous table:

// File: table.adoc

// We define a table with 3-columns.
// First column is centered and bottom aligned, 
// second column is left and top aligned and
// third column is right aligned and centered vertically.

[cols="^.>,<.<,>.^", options="header"]
|===

| Name
| Description
| Version

| Asciidoctor
| Awesome way to write documentation
| 1.5.0
|===

We get the following HTML table when we process that source file:

Finally we can alter the horizontal and vertical alignment per cell. We use the alignment configuration symbols before the pipe symbol (|) of a cell definition. This overrules any alignment configuration set in the cols definition. In the next Asciidoctor file we combine all these settings for a table:

// File: table.adoc

// We define a table with 3-columns.
// The row header has all cell values
// centered.
// The first table row cell is right aligned.
// The last table row cell is horizontal
// and vertical centered.

[cols="3*", options="header"]
|===

^| Name
^| Description
^| Version

>| Asciidoctor
| Awesome way to write documentation
^.^| 1.5.0
|===

And when we look at the output we see all alignment configuration applied to our table:

Written with Asciidoctor 1.5.0.

Wednesday, November 5, 2014

Awesome Asciidoctor: CSV and DSV Tables

With Asciidoctor we can create tables where the header and rows are in CSV (Comma Separated Values) and DSV (Delimiter Separated Values) format. Normally we use a pipe-symbol (|) to separate cell values. This is actually PSV (Prefix Separated Values) :-).

In the following Asciidoctor markup we create a very simple table with a header and two rows using CSV:

= Tables

== CSV table

[format="csv", options="header"]
|===
Writing tools, Awesomeness
Asciidoctor, Oh yeah!
MS Word, No!
|===

We generate this into HTML and we get the following result:

Asciidoctor provides also another way to define the above table:

= Tables

== CSV table

// Define table using CSV syntax. 
// The start and end of the table is defined
// as ,=== instead of |===.
// Also the header row is followed by new line,
// to indicate it is the header row.

,===
Writing tools, Awesomeness

Asciidoctor, Oh yeah!
MS Word, No!
,===


// We can also specify a separator.

[format="csv", separator=";", options="header"]
|===
Name;Description
Asciidoctor;Awesome way to write documentation
|=== 

The previous samples used a comma to separate values, but we can also use colon (:). The next sample contains tables defined with DSV:

== DSV table

[format="dsv", options="header"]
|===
Writing tools:Awesomeness
Asciidoctor:Oh yeah!
MS Word:No!
|===

// Alternative syntax:

:===
Writing tools: Awesomeness

Asciidoctor: Oh yeah!
MS Word: No!
:===

With the include directive we can also include data from an external CSV of DSV file to create a table (of course also the traditional pipe-symbol separated format can be in an external file):

= Table with external data

[format="csv", options="header"]
|===
include::tools.csv[]
|===

The file tools.cv has the following contents:

Writing tools, Awesomeness
Asciidoctor, Oh yeah!
MS Word, No!

Code written with Asciidoctor 1.5.0.

Tuesday, October 28, 2014

Spocklight Notebook is Published

Today Spocklight Notebook is published as a free book. This book is an electronic publication with all Spocklight blog posts about the Spock framework bundled.

The book is published at Leanpub and is available in three formats: PDF, MOBI (for Kindle) and EPUB (for iPad). Updates for the book are also free. So when new Spocklight blog posts will be added to the book you will get those updates for free.

I hope you will enjoy the book and I will keep it up-to-date with new content when I publish new Spocklight blog posts.

Tuesday, October 21, 2014

Gradle Goodness: Changing Name of Default Build File

Gradle uses the name build.gradle as the default name for a build file. If we write our build code in a file build.gradle then we don't have to specify the build filename when we run tasks. We can create build files with a different name other than build.gradle. For example we can define our build logic in a file sample.gradle. To run the tasks from this build file we can use the command line option -b or --build-file followed by the file name. But we can also change the project settings and set a new default build file name for our project. With the changed project settings we do not have to use the command line options -b or --build-file.

Suppose we have the following build file with the name sample.gradle:

// File: sample.gradle
task sample(description: 'Sample task') << {
    println 'Sample task'
}

defaultTasks 'sample'

To run the sample task from the command line we can use the command line options -b or --build-file:

$ gradle -b sample.gradle
:sample
Sample task

BUILD SUCCESSFUL

Total time: 3.168 secs
$ gradle --build-file sample.gradle 
:sample
Sample task

BUILD SUCCESSFUL

Total time: 2.148 secs
$

To change the default build file name for our project we create a file settings.gradle in our project. Inside the settings.gradle file we can change the property buildFileName for rootProject:

// File: settings.gradle
// Change default build file name for this project.
rootProject.buildFileName = 'sample.gradle'

Now we execute the tasks from sample.gradle without the options -b or --build-file:

$ gradle
:sample
Sample task

BUILD SUCCESSFUL

Total time: 3.312 secs
$

Code written with Gradle 2.1.