Skip to content
Browse files

Added entity declaration tp dtd

  • Loading branch information...
1 parent c42251a commit c95e28ee7c8d1698bff7573d18b494a84594e36d @oozcitak committed Dec 23, 2013
Showing with 126 additions and 0 deletions.
  1. +1 −0 src/XMLDTDAttList.coffee
  2. +75 −0 src/XMLDTDEntity.coffee
  3. +29 −0 src/XMLDocType.coffee
  4. +5 −0 src/XMLStringifier.coffee
  5. +16 −0 test/doctype.coffee
View
1 src/XMLDTDAttList.coffee
@@ -38,6 +38,7 @@ module.exports = class XMLDTDAttList
@defaultValue = @stringify.dtdAttDefault defaultValue
@defaultValueType = defaultValueType
+
# Converts the XML fragment to string
#
# `options.pretty` pretty prints the result
View
75 src/XMLDTDEntity.coffee
@@ -0,0 +1,75 @@
+_ = require 'underscore'
+
+# Represents an entity declaration in the DTD
+module.exports = class XMLDTDEntity
+
+
+ # Initializes a new instance of `XMLDTDEntity`
+ #
+ # `parent` the parent `XMLDocType` element
+ # `pe` whether this is a parameter entity or a general entity
+ # defaults to `false` (general entity)
+ # `name` the name of the entity
+ # `value` internal entity value or an object with external entity details
+ # `value.pubid` public identifier
+ # `value.sysid` system identifier
+ # `value.ndata` notation declaration
+ constructor: (parent, pe, name, value) ->
+ @stringify = parent.stringify
+
+ if not name?
+ throw new Error "Missing entity name"
+ if not value?
+ throw new Error "Missing entity value"
+
+ @pe = !!pe
+ @name = @stringify.eleName name
+
+ if not _.isObject value
+ @value = @stringify.dtdEntityValue value
+ else
+ if not value.pubid and not value.sysid
+ throw new Error "Public and/or system identifiers are required for an external entity"
+ if value.pubid and not value.sysid
+ throw new Error "System identifier is required for a public external entity"
+
+ @pubid = @stringify.dtdPubID value.pubid if value.pubid?
+ @sysid = @stringify.dtdSysID value.sysid if value.sysid?
+
+ @ndata = @stringify.dtdNData value.ndata if value.ndata?
+ if @pe and @ndata
+ throw new Error "Notation declaration is not allowed in a parameter entity"
+
+ # Converts the XML fragment to string
+ #
+ # `options.pretty` pretty prints the result
+ # `options.indent` indentation for pretty print
+ # `options.newline` newline sequence for pretty print
+ toString: (options, level) ->
+ pretty = options?.pretty or false
+ indent = options?.indent or ' '
+ newline = options?.newline or '\n'
+ level or= 0
+
+ space = new Array(level).join(indent)
+
+ r = ''
+
+ r += space if pretty
+
+ r += '<!ENTITY'
+ r += ' %' if @pe
+ r += ' ' + @name
+ if @value
+ r += ' "' + @value + '"'
+ else
+ if @pubid and @sysid
+ r += ' PUBLIC "' + @pubid + '" "' + @sysid + '"'
+ else if @sysid
+ r += ' SYSTEM "' + @sysid + '"'
+ r += ' NDATA ' + @ndata if @ndata
+ r += '>'
+
+ r += newline if pretty
+
+ return r
View
29 src/XMLDocType.coffee
@@ -50,6 +50,33 @@ module.exports = class XMLDocType
return @
+ # Creates a general entity declaration
+ #
+ # `name` the name of the entity
+ # `value` internal entity value or an object with external entity details
+ # `value.pubid` public identifier
+ # `value.sysid` system identifier
+ # `value.ndata` notation declaration
+ entity: (name, value) ->
+ XMLDTDEntity = require './XMLDTDEntity'
+ child = new XMLDTDEntity @, false, name, value
+ @children.push child
+ return @
+
+
+ # Creates a parameter entity declaration
+ #
+ # `name` the name of the entity
+ # `value` internal entity value or an object with external entity details
+ # `value.pubid` public identifier
+ # `value.sysid` system identifier
+ pEntity: (name, value) ->
+ XMLDTDEntity = require './XMLDTDEntity'
+ child = new XMLDTDEntity @, true, name, value
+ @children.push child
+ return @
+
+
# Creates a NOTATION declaration
#
# `name` the name of the notation
@@ -151,6 +178,8 @@ module.exports = class XMLDocType
ele: (name, value) -> @element name, value
att: (elementName, attributeName, attributeType, defaultValueType, defaultValue) ->
@attList elementName, attributeName, attributeType, defaultValueType, defaultValue
+ ent: (name, value) -> @entity name, value
+ pent: (name, value) -> @pEntity name, value
not: (name, identifierType, pubID, sysID) ->
@notation name, identifierType, pubID, sysID
dat: (value) -> @cdata value
View
5 src/XMLStringifier.coffee
@@ -64,6 +64,10 @@ module.exports = class XMLStringifier
'' + val or ''
dtdAttDefault: (val) ->
if val? then '' + val or '' else val
+ dtdEntityValue: (val) ->
+ '' + val or ''
+ dtdNData: (val) ->
+ '' + val or ''
# strings to match while converting from JS objects
convertAttKey: '@'
@@ -74,6 +78,7 @@ module.exports = class XMLStringifier
convertRawKey: '#raw'
convertListKey: '#list'
+
# Checks whether the given string contains legal characters
# Fails with an exception on error
#
View
16 test/doctype.coffee
@@ -53,6 +53,14 @@ vows
.att('img', 'src', 'NOTATION (fs|fs-nt)', '#REQUIRED')
.dat('<owner>John</owner>')
.ele('node')
+ .ent('ent', 'my val')
+ .ent('ent', { sysid: 'http://www.myspec.com/ent' })
+ .ent('ent', { pubid: '-//MY//SPEC ENT//EN', sysid: 'http://www.myspec.com/ent' })
+ .ent('ent', { sysid: 'http://www.myspec.com/ent', ndata: 'entprg' })
+ .ent('ent', { pubid: '-//MY//SPEC ENT//EN', sysid: 'http://www.myspec.com/ent', ndata: 'entprg' })
+ .pent('ent', 'my val')
+ .pent('ent', { sysid: 'http://www.myspec.com/ent' })
+ .pent('ent', { pubid: '-//MY//SPEC ENT//EN', sysid: 'http://www.myspec.com/ent' })
.root()
.ele('node').txt('test')
@@ -69,6 +77,14 @@ vows
'<!ATTLIST img src NOTATION (fs|fs-nt) #REQUIRED>' +
'<![CDATA[<owner>John</owner>]]>' +
'<!ELEMENT node (#PCDATA)>' +
+ '<!ENTITY ent "my val">' +
+ '<!ENTITY ent SYSTEM "http://www.myspec.com/ent">' +
+ '<!ENTITY ent PUBLIC "-//MY//SPEC ENT//EN" "http://www.myspec.com/ent">' +
+ '<!ENTITY ent SYSTEM "http://www.myspec.com/ent" NDATA entprg>' +
+ '<!ENTITY ent PUBLIC "-//MY//SPEC ENT//EN" "http://www.myspec.com/ent" NDATA entprg>' +
+ '<!ENTITY % ent "my val">' +
+ '<!ENTITY % ent SYSTEM "http://www.myspec.com/ent">' +
+ '<!ENTITY % ent PUBLIC "-//MY//SPEC ENT//EN" "http://www.myspec.com/ent">' +
']>' +
'<root><node>test</node></root>'
assert.strictEqual topic.end(), xml

0 comments on commit c95e28e

Please sign in to comment.
Something went wrong with that request. Please try again.