You can write CoffeeScript inside Markdown document because the compiler, coffee
, ignores everything outside code blocks.
Here are two equivalent codes in CoffeScript (.coffee
) and Literate CoffeeScript (.litcoffee
).
CoffeeScript
FactoryMethod.coffee
###
# Factory Method Example in CoffeeScript
## Introduction
This example of the factory method pattern is a part of a [Tic-tac-toe](http://en.wikipedia.org/wiki/Tic-tac-toe) application. See [Wikipedia](http://en.wikipedia.org/wiki/File:Factory_Method_UML_class_diagram.svg) for the UML diagram of the factory method pattern.
This example has four classes: Grid, GridCell, Board and Space.
Grid and GridCell are general purpose classes. Suppose they are provided by an external library.
Grid (Creator) doesn't know Space (ConcreteProduct) because Grid is an external library class:
###
class Grid # <<Creator>>
@cells = []
@row = 0
@column = 0
constructor: (@rows, @columns) ->
size = @rows * @columns
@cells = new Array(size)
for row in [0...@rows]
for column in [0...@columns]
cell = this.newGridCell(row, column)
this.cellAt row, column, cell
newGridCell: () -> # returns GridCell
throw "abstract method"
cellAt: (row, column, val = null) ->
i = (row * @columns) + column
if val == null
@cells[i]
else
@cells[i] = val
cells: () ->
@cells
eachCellsInRow: (row, callback) ->
for column in [0...@columns]
callback this.cellAt(row, column)
eachCellsInColumn: (column, callback) ->
for row in [0...@rows]
callback this.cellAt(row, column)
each: (callback) ->
callback cell, index for index, cell of @cells
# GridCell is an abstract grid cell, used by Grid. GridCell (Product) doesn't know Board (ConcreteCreator) because GridCell is an external library class:
class GridCell # <<Product>>
constructor: (@row, @column) ->
# Board is a subclass of Grid. It overrides `#newGridCell` factory method:
class Board extends Grid # <<ConcreteCreator>>
constructor: (@rows, @columns) ->
super @rows, @columns
newGridCell: (row, column) ->
new Space(row, column)
# Space is a concrete GridCell, used by Board:
class Space extends GridCell # <<ConcreteProduct>>
constructor: (@row, @column) ->
@type = "Space"
# Here is an example:
board = new Board(3, 3)
#board.each (cell, index) ->
# console.log cell
console.log 'each cells in row 1:'
board.eachCellsInRow 1,
(cell, index) -> console.log cell
console.log 'each cells in columns 1:'
board.eachCellsInColumn 1,
(cell, index) -> console.log cell
###
# Result
$ coffee FactoryMethod.litcoffee
each cells in row 1:
{ row: 1, column: 0, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 1, column: 2, type: 'Space' }
each cells in columns 1:
{ row: 0, column: 1, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 2, column: 1, type: 'Space' }
###
Literate CoffeeScript
FactoryMethod.litcoffee
# Factory Method Example in CoffeeScript
## Introduction
This example of the factory method pattern is a part of a [Tic-tac-toe](http://en.wikipedia.org/wiki/Tic-tac-toe) application. See [Wikipedia](http://en.wikipedia.org/wiki/File:Factory_Method_UML_class_diagram.svg) for the UML diagram of the factory method pattern.
This example has four classes: Grid, GridCell, Board and Space.
Grid and GridCell are general purpose classes. Suppose they are provided by an external library.
## Code
Grid (Creator) doesn't know Space (ConcreteProduct) because Grid is an external library class:
class Grid # <<Creator>>
@cells = []
@row = 0
@column = 0
constructor: (@rows, @columns) ->
size = @rows * @columns
@cells = new Array(size)
for row in [0...@rows]
for column in [0...@columns]
cell = this.newGridCell(row, column)
this.cellAt row, column, cell
newGridCell: () -> # returns GridCell
throw "abstract method"
cellAt: (row, column, val = null) ->
i = (row * @columns) + column
if val == null
@cells[i]
else
@cells[i] = val
cells: () ->
@cells
eachCellsInRow: (row, callback) ->
for column in [0...@columns]
callback this.cellAt(row, column)
eachCellsInColumn: (column, callback) ->
for row in [0...@rows]
callback this.cellAt(row, column)
each: (callback) ->
callback cell, index for index, cell of @cells
GridCell is an abstract grid cell, used by Grid. GridCell (Product) doesn't know Board (ConcreteCreator) because GridCell is an external library class:
class GridCell # <<Product>>
constructor: (@row, @column) ->
Board is a subclass of Grid. It overrides `#newGridCell` factory method:
class Board extends Grid # <<ConcreteCreator>>
constructor: (@rows, @columns) ->
super @rows, @columns
newGridCell: (row, column) ->
new Space(row, column)
Space is a concrete GridCell, used by Board:
class Space extends GridCell # <<ConcreteProduct>>
constructor: (@row, @column) ->
@type = "Space"
Here is an example:
board = new Board(3, 3)
#board.each (cell, index) ->
# console.log cell
console.log 'each cells in row 1:'
board.eachCellsInRow 1,
(cell, index) -> console.log cell
console.log 'each cells in columns 1:'
board.eachCellsInColumn 1,
(cell, index) -> console.log cell
This is a result:
###
$ coffee FactoryMethod.litcoffee
each cells in row 1:
{ row: 1, column: 0, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 1, column: 2, type: 'Space' }
each cells in columns 1:
{ row: 0, column: 1, type: 'Space' }
{ row: 1, column: 1, type: 'Space' }
{ row: 2, column: 1, type: 'Space' }
###
Discussion
I want to write in literate style but there isn't enough support by editors and viewers. For example, I can't find Sublime Text 2 module for syntax highlighting. This website and its editor, Qiita and Kobito, is another example.
Who write code in Literate CoffeeScript?