123 lines
3.0 KiB
CoffeeScript
123 lines
3.0 KiB
CoffeeScript
###
|
|
Crafting Guide - string_builder.coffee
|
|
|
|
Copyright (c) 2015 by Redwood Labs
|
|
All rights reserved.
|
|
###
|
|
|
|
########################################################################################################################
|
|
|
|
module.exports = class StringBuilder
|
|
|
|
constructor: (options={})->
|
|
options.indent ?= 0
|
|
options.indentString ?= ' '
|
|
|
|
@context = options.context
|
|
|
|
@_initialIndent = options.indent
|
|
@_indent = options.indent
|
|
@_indentString = options.indentString
|
|
@_pieces = []
|
|
|
|
# Public Methods ###############################################################################
|
|
|
|
call: ->
|
|
args = (arg for arg in arguments)
|
|
callback = args.pop()
|
|
args.unshift this
|
|
return unless _.isFunction callback
|
|
|
|
callback.apply null, args
|
|
|
|
clear: ->
|
|
@_indent = @_initialIndent
|
|
@_pieces = []
|
|
return this
|
|
|
|
indent: ->
|
|
@_indent += 1
|
|
return this
|
|
|
|
line: (args...)->
|
|
@push.apply this, args
|
|
@push '\n'
|
|
|
|
loop: (list, options={})->
|
|
options.start ?= ''
|
|
options.end ?= ''
|
|
options.indent ?= false
|
|
options.delimiter ?= ', '
|
|
options.onEach ?= (builder, item)-> builder.push item
|
|
|
|
@_pushText options.start
|
|
if options.indent then @indent()
|
|
|
|
isFirst = true
|
|
for item in list
|
|
if not isFirst then @push options.delimiter
|
|
isFirst = false
|
|
options.onEach this, item
|
|
|
|
if options.indent then @outdent()
|
|
@_pushText options.end
|
|
|
|
return this
|
|
|
|
onlyIf: (condition, callback=null)->
|
|
return this unless condition
|
|
|
|
callback ?= (builder)-> # do nothing
|
|
callback this
|
|
return this
|
|
|
|
outdent: ->
|
|
@_indent -= 1
|
|
return this
|
|
|
|
push: ->
|
|
for i in [0...arguments.length]
|
|
arg = arguments[i]
|
|
|
|
if _.isArray arg
|
|
@push.apply this, arg
|
|
else if _.isString arg
|
|
@_pushText arg
|
|
else
|
|
@_pushText "#{arg}"
|
|
|
|
return this
|
|
|
|
# Object Overrides #############################################################################
|
|
|
|
toString: ->
|
|
return @_pieces.join ''
|
|
|
|
# Private Methods ##############################################################################
|
|
|
|
_pushIndent: ->
|
|
for i in [0...@_indent]
|
|
@_pieces.push @_indentString
|
|
|
|
_pushText: (text)->
|
|
return if text.length is 0
|
|
index = 0
|
|
|
|
if @_pieces.length > 0
|
|
lastPiece = @_pieces[@_pieces.length-1]
|
|
if lastPiece[lastPiece.length-1] is '\n'
|
|
@_pushIndent()
|
|
|
|
while true
|
|
newLineAt = text.indexOf '\n', index
|
|
break if newLineAt is -1
|
|
|
|
@_pieces.push text[index..newLineAt]
|
|
index = newLineAt + 1
|
|
|
|
break if newLineAt is text.length - 1
|
|
@_pushIndent()
|
|
|
|
if text.length > index
|
|
@_pieces.push text[index...text.length]
|