/
XMLDocType.coffee
187 lines (148 loc) · 4.94 KB
/
XMLDocType.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
_ = require 'underscore'
# Represents doctype declaration
module.exports = class XMLDocType
# Initializes a new instance of `XMLDocType`
#
# `parent` the document object
#
# `pubID` public identifier of the external subset
# `sysID` system identifier of the external subset
constructor: (parent, pubID, sysID) ->
@documentObject = parent
@stringify = @documentObject.stringify
@children = []
if not sysID?
[sysID, pubID] = [pubID, sysID]
@pubID = @stringify.dtdPubID pubID if pubID?
@sysID = @stringify.dtdSysID sysID if sysID?
# Creates an element type declaration
#
# `name` element name
# `value` element content (defaults to #PCDATA)
element: (name, value) ->
XMLDTDElement = require './XMLDTDElement'
child = new XMLDTDElement @, name, value
@children.push child
return @
# Creates an attribute declaration
#
# `elementName` the name of the element containing this attribute
# `attributeName` attribute name
# `attributeType` type of the attribute (defaults to CDATA)
# `defaultValueType` default value type (either #REQUIRED, #IMPLIED, #FIXED or
# #DEFAULT) (defaults to #IMPLIED)
# `defaultValue` default value of the attribute
# (only used for #FIXED or #DEFAULT)
attList: (elementName, attributeName, attributeType, defaultValueType, defaultValue) ->
XMLDTDAttList = require './XMLDTDAttList'
child = new XMLDTDAttList @, elementName, attributeName, attributeType, defaultValueType, defaultValue
@children.push child
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
# `value` an object with external entity details
# `value.pubID` public identifier
# `value.sysID` system identifier
notation: (name, value) ->
XMLDTDNotation = require './XMLDTDNotation'
child = new XMLDTDNotation @, name, value
@children.push child
return @
# Creates a CDATA node
#
# `value` element text without CDATA delimiters
cdata: (value) ->
XMLCData = require './XMLCData'
child = new XMLCData @, value
@children.push child
return @
# Creates a comment node
#
# `value` comment text
comment: (value) ->
XMLComment = require './XMLComment'
child = new XMLComment @, value
@children.push child
return @
# Adds a processing instruction
#
# `target` instruction target
# `value` instruction value
instruction: (target, value) ->
XMLProcessingInstruction = require './XMLProcessingInstruction'
child = new XMLProcessingInstruction @, target, value
@children.push child
return @
# Gets the root node
root: () ->
@documentObject.root()
# Gets the node representing the XML document
document: () ->
return @documentObject
# Converts 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 + 1).join(indent)
r = ''
r += space if pretty
# open tag
r += '<!DOCTYPE ' + @root().name
# external identifier
if @pubID and @sysID
r += ' PUBLIC "' + @pubID + '" "' + @sysID + '"'
else if @sysID
r += ' SYSTEM "' + @sysID + '"'
# internal subset
if @children.length > 0
r += ' ['
for child in @children
r += child.toString options, level + 1
r += newline if pretty
r += ']'
# close tag
r += '>'
r += newline if pretty
return r
# Aliases
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, value) -> @notation name, value
dat: (value) -> @cdata value
com: (value) -> @comment value
ins: (target, value) -> @instruction target, value
up: () -> @root()
doc: () -> @document()