Skip to content

Commit

Permalink
Call appropriate writer functions for nodes with a single child node …
Browse files Browse the repository at this point in the history
…in pretty print mode. Fixes #195.
  • Loading branch information
oozcitak committed Feb 4, 2019
1 parent 447abf0 commit 5eec933
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 90 deletions.
57 changes: 12 additions & 45 deletions src/XMLStreamWriter.coffee
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
XMLDeclaration = require './XMLDeclaration'
XMLDocType = require './XMLDocType'

XMLCData = require './XMLCData'
XMLComment = require './XMLComment'
XMLElement = require './XMLElement'
XMLRaw = require './XMLRaw'
XMLText = require './XMLText'
XMLProcessingInstruction = require './XMLProcessingInstruction'
XMLDummy = require './XMLDummy'

XMLDTDAttList = require './XMLDTDAttList'
XMLDTDElement = require './XMLDTDElement'
XMLDTDEntity = require './XMLDTDEntity'
XMLDTDNotation = require './XMLDTDNotation'

XMLWriterBase = require './XMLWriterBase'
WriterState = require './WriterState'

Expand All @@ -35,7 +19,10 @@ module.exports = class XMLStreamWriter extends XMLWriterBase
super(options)

endline: (node, options, level) ->
if node.isLastRootNode and options.state is WriterState.CloseTag then '' else super(node, options, level)
if node.isLastRootNode and options.state is WriterState.CloseTag
return ''
else
super(node, options, level)

document: (doc, options) ->
# set a flag so that we don't insert a newline after the last root level node
Expand All @@ -45,15 +32,7 @@ module.exports = class XMLStreamWriter extends XMLWriterBase
options = @filterOptions options

for child in doc.children
# skip dummy nodes
if child instanceof XMLDummy then continue

switch
when child instanceof XMLDeclaration then @declaration child, options, 0
when child instanceof XMLDocType then @docType child, options, 0
when child instanceof XMLComment then @comment child, options, 0
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, 0
else @element child, options, 0
@writeChildNode child, options, 0

attribute: (att, options, level) ->
@stream.write super(att, options, level)
Expand Down Expand Up @@ -87,15 +66,7 @@ module.exports = class XMLStreamWriter extends XMLWriterBase
@stream.write @endline(node, options, level)
options.state = WriterState.InsideTag
for child in node.children
switch
when child instanceof XMLDTDAttList then @dtdAttList child, options, level + 1
when child instanceof XMLDTDElement then @dtdElement child, options, level + 1
when child instanceof XMLDTDEntity then @dtdEntity child, options, level + 1
when child instanceof XMLDTDNotation then @dtdNotation child, options, level + 1
when child instanceof XMLCData then @cdata child, options, level + 1
when child instanceof XMLComment then @comment child, options, level + 1
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, level + 1
else throw new Error "Unknown DTD node type: " + child.constructor.name
@writeChildNode child, options, level + 1
options.state = WriterState.CloseTag
@stream.write ']'

Expand Down Expand Up @@ -131,23 +102,19 @@ module.exports = class XMLStreamWriter extends XMLWriterBase
# do not indent text-only nodes
@stream.write '>'
options.state = WriterState.InsideTag
@stream.write node.children[0].value
options.suppressPrettyCount++
prettySuppressed = true
@writeChildNode node.children[0], options, level + 1
options.suppressPrettyCount--
prettySuppressed = false
options.state = WriterState.CloseTag
@stream.write '</' + node.name + '>'
else
@stream.write '>' + @endline(node, options, level)
options.state = WriterState.InsideTag
# inner tags
for child in node.children
switch
when child instanceof XMLCData then @cdata child, options, level + 1
when child instanceof XMLComment then @comment child, options, level + 1
when child instanceof XMLElement then @element child, options, level + 1
when child instanceof XMLRaw then @raw child, options, level + 1
when child instanceof XMLText then @text child, options, level + 1
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, level + 1
when child instanceof XMLDummy then ''
else throw new Error "Unknown XML node type: " + child.constructor.name
@writeChildNode child, options, level + 1
# close tag
options.state = WriterState.CloseTag
@stream.write @indent(node, options, level) + '</' + node.name + '>'
Expand Down
26 changes: 1 addition & 25 deletions src/XMLStringWriter.coffee
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
XMLDeclaration = require './XMLDeclaration'
XMLDocType = require './XMLDocType'

XMLCData = require './XMLCData'
XMLComment = require './XMLComment'
XMLElement = require './XMLElement'
XMLRaw = require './XMLRaw'
XMLText = require './XMLText'
XMLProcessingInstruction = require './XMLProcessingInstruction'
XMLDummy = require './XMLDummy'

XMLDTDAttList = require './XMLDTDAttList'
XMLDTDElement = require './XMLDTDElement'
XMLDTDEntity = require './XMLDTDEntity'
XMLDTDNotation = require './XMLDTDNotation'

XMLWriterBase = require './XMLWriterBase'

# Prints XML nodes as plain text
Expand All @@ -37,15 +21,7 @@ module.exports = class XMLStringWriter extends XMLWriterBase

r = ''
for child in doc.children
# skip dummy nodes
if child instanceof XMLDummy then continue

r += switch
when child instanceof XMLDeclaration then @declaration child, options, 0
when child instanceof XMLDocType then @docType child, options, 0
when child instanceof XMLComment then @comment child, options, 0
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, 0
else @element child, options, 0
r += @writeChildNode child, options, 0

# remove trailing newline
if options.pretty and r.slice(-options.newline.length) == options.newline
Expand Down
44 changes: 24 additions & 20 deletions src/XMLWriterBase.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,7 @@ module.exports = class XMLWriterBase
r += @endline(node, options, level)
options.state = WriterState.InsideTag
for child in node.children
r += switch
when child instanceof XMLDTDAttList then @dtdAttList child, options, level + 1
when child instanceof XMLDTDElement then @dtdElement child, options, level + 1
when child instanceof XMLDTDEntity then @dtdEntity child, options, level + 1
when child instanceof XMLDTDNotation then @dtdNotation child, options, level + 1
when child instanceof XMLCData then @cdata child, options, level + 1
when child instanceof XMLComment then @comment child, options, level + 1
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, level + 1
else throw new Error "Unknown DTD node type: " + child.constructor.name
r += @writeChildNode child, options, level + 1
options.state = WriterState.CloseTag
r += ']'

Expand Down Expand Up @@ -209,7 +201,11 @@ module.exports = class XMLWriterBase
# do not indent text-only nodes
r += '>'
options.state = WriterState.InsideTag
r += node.children[0].value
options.suppressPrettyCount++
prettySuppressed = true
r += @writeChildNode node.children[0], options, level + 1
options.suppressPrettyCount--
prettySuppressed = false
options.state = WriterState.CloseTag
r += '</' + node.name + '>' + @endline(node, options, level)
else
Expand All @@ -226,15 +222,7 @@ module.exports = class XMLWriterBase
options.state = WriterState.InsideTag
# inner tags
for child in node.children
r += switch
when child instanceof XMLCData then @cdata child, options, level + 1
when child instanceof XMLComment then @comment child, options, level + 1
when child instanceof XMLElement then @element child, options, level + 1
when child instanceof XMLRaw then @raw child, options, level + 1
when child instanceof XMLText then @text child, options, level + 1
when child instanceof XMLProcessingInstruction then @processingInstruction child, options, level + 1
when child instanceof XMLDummy then ''
else throw new Error "Unknown XML node type: " + child.constructor.name
r += @writeChildNode child, options, level + 1

# close tag
options.state = WriterState.CloseTag
Expand All @@ -250,6 +238,23 @@ module.exports = class XMLWriterBase

return r

writeChildNode: (node, options, level) ->
switch
when node instanceof XMLCData then @cdata node, options, level
when node instanceof XMLComment then @comment node, options, level
when node instanceof XMLElement then @element node, options, level
when node instanceof XMLRaw then @raw node, options, level
when node instanceof XMLText then @text node, options, level
when node instanceof XMLProcessingInstruction then @processingInstruction node, options, level
when node instanceof XMLDummy then ''
when node instanceof XMLDeclaration then @declaration node, options, level
when node instanceof XMLDocType then @docType node, options, level
when node instanceof XMLDTDAttList then @dtdAttList node, options, level
when node instanceof XMLDTDElement then @dtdElement node, options, level
when node instanceof XMLDTDEntity then @dtdEntity node, options, level
when node instanceof XMLDTDNotation then @dtdNotation node, options, level
else throw new Error "Unknown XML node type: " + node.constructor.name

processingInstruction: (node, options, level) ->
@openNode(node, options, level)
options.state = WriterState.OpenTag
Expand Down Expand Up @@ -363,4 +368,3 @@ module.exports = class XMLWriterBase
openNode: (node, options, level) ->

closeNode: (node, options, level) ->

59 changes: 59 additions & 0 deletions test/issues/195.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
suite 'Tests specific to issues:', ->
test 'Missing callbacks if {pretty: true} and only one method called on element?. Issue 195', ->

debugStr = ''
root = xml('root')
root.ele('textDirect', null, '[1]')
root.ele('textSingle').txt('[2]')
root.ele('rawSingle').raw('[3]')
root.ele('textDirectDummy', null, '[4]').dummy()
root.ele('textDummy').txt('[5]').dummy()
root.ele('rawDummy').raw('[6]').dummy()
root.ele('twoTextNodes').txt('[7]').txt('[7]')
root.ele('twoRaw').raw('[8]').raw('[8]')
root.ele('rawAndTextNode').raw('[9]').txt('[9]')
root.end(builder.stringWriter(
pretty: true
writer:
raw: (node, options, level) ->
debugStr += "#{ options.indent.repeat(level) }RAW #{ node.value }\n"
@_raw node, options, level
text: (node, options, level) ->
debugStr += "#{ options.indent.repeat(level) }TEXT #{ node.value }\n"
@_text node, options, level
element: (node, options, level) ->
debugStr += "#{ options.indent.repeat(level) }ELEMENT #{ node.name }\n"
@_element node, options, level
))

# trim last newline
debugStr = debugStr.slice(0, -1)

eq(
debugStr

"""
ELEMENT root
ELEMENT textDirect
TEXT [1]
ELEMENT textSingle
TEXT [2]
ELEMENT rawSingle
RAW [3]
ELEMENT textDirectDummy
TEXT [4]
ELEMENT textDummy
TEXT [5]
ELEMENT rawDummy
RAW [6]
ELEMENT twoTextNodes
TEXT [7]
TEXT [7]
ELEMENT twoRaw
RAW [8]
RAW [8]
ELEMENT rawAndTextNode
RAW [9]
TEXT [9]
"""
)

0 comments on commit 5eec933

Please sign in to comment.