mathematical 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -4
  3. data/.gitmodules +0 -4
  4. data/README.md +108 -28
  5. data/Rakefile +3 -31
  6. data/ext/mathematical/README.itex2MML.md +11 -0
  7. data/ext/mathematical/README.lasem.md +11 -0
  8. data/ext/mathematical/extconf.rb +51 -0
  9. data/ext/mathematical/itex2MML.h +63 -0
  10. data/ext/mathematical/lasemrender.c +257 -0
  11. data/ext/mathematical/lex.yy.c +6548 -0
  12. data/ext/mathematical/lsm.c +30 -0
  13. data/ext/mathematical/lsm.h +36 -0
  14. data/ext/mathematical/lsmattributes.c +279 -0
  15. data/ext/mathematical/lsmattributes.h +75 -0
  16. data/ext/mathematical/lsmcairo.c +598 -0
  17. data/ext/mathematical/lsmcairo.h +51 -0
  18. data/ext/mathematical/lsmdebug.c +179 -0
  19. data/ext/mathematical/lsmdebug.h +76 -0
  20. data/ext/mathematical/lsmdom.h +43 -0
  21. data/ext/mathematical/lsmdomcharacterdata.c +114 -0
  22. data/ext/mathematical/lsmdomcharacterdata.h +59 -0
  23. data/ext/mathematical/lsmdomdocument.c +292 -0
  24. data/ext/mathematical/lsmdomdocument.h +82 -0
  25. data/ext/mathematical/lsmdomdocumentfragment.c +81 -0
  26. data/ext/mathematical/lsmdomdocumentfragment.h +55 -0
  27. data/ext/mathematical/lsmdomelement.c +148 -0
  28. data/ext/mathematical/lsmdomelement.h +62 -0
  29. data/ext/mathematical/lsmdomentities.c +2155 -0
  30. data/ext/mathematical/lsmdomentities.h +35 -0
  31. data/ext/mathematical/lsmdomenumtypes.c +99 -0
  32. data/ext/mathematical/lsmdomenumtypes.c.template +39 -0
  33. data/ext/mathematical/lsmdomenumtypes.h +26 -0
  34. data/ext/mathematical/lsmdomenumtypes.h.template +26 -0
  35. data/ext/mathematical/lsmdomimplementation.c +82 -0
  36. data/ext/mathematical/lsmdomimplementation.h +41 -0
  37. data/ext/mathematical/lsmdomnamednodemap.c +118 -0
  38. data/ext/mathematical/lsmdomnamednodemap.h +64 -0
  39. data/ext/mathematical/lsmdomnode.c +725 -0
  40. data/ext/mathematical/lsmdomnode.h +120 -0
  41. data/ext/mathematical/lsmdomnodelist.c +70 -0
  42. data/ext/mathematical/lsmdomnodelist.h +58 -0
  43. data/ext/mathematical/lsmdomparser.c +461 -0
  44. data/ext/mathematical/lsmdomparser.h +54 -0
  45. data/ext/mathematical/lsmdomtext.c +82 -0
  46. data/ext/mathematical/lsmdomtext.h +55 -0
  47. data/ext/mathematical/lsmdomtypes.h +44 -0
  48. data/ext/mathematical/lsmdomview.c +422 -0
  49. data/ext/mathematical/lsmdomview.h +94 -0
  50. data/ext/mathematical/lsmmathml.h +66 -0
  51. data/ext/mathematical/lsmmathmlactionelement.c +93 -0
  52. data/ext/mathematical/lsmmathmlactionelement.h +57 -0
  53. data/ext/mathematical/lsmmathmlaligngroupelement.c +102 -0
  54. data/ext/mathematical/lsmmathmlaligngroupelement.h +56 -0
  55. data/ext/mathematical/lsmmathmlalignmarkelement.c +102 -0
  56. data/ext/mathematical/lsmmathmlalignmarkelement.h +56 -0
  57. data/ext/mathematical/lsmmathmlattributes.c +197 -0
  58. data/ext/mathematical/lsmmathmlattributes.h +126 -0
  59. data/ext/mathematical/lsmmathmldocument.c +306 -0
  60. data/ext/mathematical/lsmmathmldocument.h +61 -0
  61. data/ext/mathematical/lsmmathmlelement.c +491 -0
  62. data/ext/mathematical/lsmmathmlelement.h +107 -0
  63. data/ext/mathematical/lsmmathmlenums.c +429 -0
  64. data/ext/mathematical/lsmmathmlenums.h +182 -0
  65. data/ext/mathematical/lsmmathmlenumtypes.c +666 -0
  66. data/ext/mathematical/lsmmathmlenumtypes.c.template +39 -0
  67. data/ext/mathematical/lsmmathmlenumtypes.h +90 -0
  68. data/ext/mathematical/lsmmathmlenumtypes.h.template +26 -0
  69. data/ext/mathematical/lsmmathmlerrorelement.c +58 -0
  70. data/ext/mathematical/lsmmathmlerrorelement.h +56 -0
  71. data/ext/mathematical/lsmmathmlfencedelement.c +178 -0
  72. data/ext/mathematical/lsmmathmlfencedelement.h +65 -0
  73. data/ext/mathematical/lsmmathmlfractionelement.c +253 -0
  74. data/ext/mathematical/lsmmathmlfractionelement.h +62 -0
  75. data/ext/mathematical/lsmmathmlglyphtableams.c +597 -0
  76. data/ext/mathematical/lsmmathmlglyphtableams.h +45 -0
  77. data/ext/mathematical/lsmmathmlitexelement.c +187 -0
  78. data/ext/mathematical/lsmmathmlitexelement.h +60 -0
  79. data/ext/mathematical/lsmmathmllayoututils.c +191 -0
  80. data/ext/mathematical/lsmmathmllayoututils.h +58 -0
  81. data/ext/mathematical/lsmmathmlmathelement.c +204 -0
  82. data/ext/mathematical/lsmmathmlmathelement.h +81 -0
  83. data/ext/mathematical/lsmmathmloperatordictionary.c +3332 -0
  84. data/ext/mathematical/lsmmathmloperatordictionary.h +54 -0
  85. data/ext/mathematical/lsmmathmloperatorelement.c +307 -0
  86. data/ext/mathematical/lsmmathmloperatorelement.h +73 -0
  87. data/ext/mathematical/lsmmathmlpaddedelement.c +58 -0
  88. data/ext/mathematical/lsmmathmlpaddedelement.h +56 -0
  89. data/ext/mathematical/lsmmathmlphantomelement.c +71 -0
  90. data/ext/mathematical/lsmmathmlphantomelement.h +56 -0
  91. data/ext/mathematical/lsmmathmlpresentationcontainer.c +43 -0
  92. data/ext/mathematical/lsmmathmlpresentationcontainer.h +54 -0
  93. data/ext/mathematical/lsmmathmlpresentationtoken.c +303 -0
  94. data/ext/mathematical/lsmmathmlpresentationtoken.h +83 -0
  95. data/ext/mathematical/lsmmathmlradicalelement.c +266 -0
  96. data/ext/mathematical/lsmmathmlradicalelement.h +71 -0
  97. data/ext/mathematical/lsmmathmlrowelement.c +58 -0
  98. data/ext/mathematical/lsmmathmlrowelement.h +56 -0
  99. data/ext/mathematical/lsmmathmlscriptelement.c +282 -0
  100. data/ext/mathematical/lsmmathmlscriptelement.h +78 -0
  101. data/ext/mathematical/lsmmathmlsemanticselement.c +82 -0
  102. data/ext/mathematical/lsmmathmlsemanticselement.h +56 -0
  103. data/ext/mathematical/lsmmathmlspaceelement.c +142 -0
  104. data/ext/mathematical/lsmmathmlspaceelement.h +60 -0
  105. data/ext/mathematical/lsmmathmlstringelement.c +123 -0
  106. data/ext/mathematical/lsmmathmlstringelement.h +58 -0
  107. data/ext/mathematical/lsmmathmlstyle.c +130 -0
  108. data/ext/mathematical/lsmmathmlstyle.h +81 -0
  109. data/ext/mathematical/lsmmathmlstyleelement.c +307 -0
  110. data/ext/mathematical/lsmmathmlstyleelement.h +87 -0
  111. data/ext/mathematical/lsmmathmltablecellelement.c +122 -0
  112. data/ext/mathematical/lsmmathmltablecellelement.h +62 -0
  113. data/ext/mathematical/lsmmathmltableelement.c +545 -0
  114. data/ext/mathematical/lsmmathmltableelement.h +78 -0
  115. data/ext/mathematical/lsmmathmltablerowelement.c +120 -0
  116. data/ext/mathematical/lsmmathmltablerowelement.h +64 -0
  117. data/ext/mathematical/lsmmathmltraits.c +819 -0
  118. data/ext/mathematical/lsmmathmltraits.h +119 -0
  119. data/ext/mathematical/lsmmathmltypes.h +66 -0
  120. data/ext/mathematical/lsmmathmlunderoverelement.c +485 -0
  121. data/ext/mathematical/lsmmathmlunderoverelement.h +82 -0
  122. data/ext/mathematical/lsmmathmlutils.c +170 -0
  123. data/ext/mathematical/lsmmathmlutils.h +50 -0
  124. data/ext/mathematical/lsmmathmlview.c +1048 -0
  125. data/ext/mathematical/lsmmathmlview.h +164 -0
  126. data/ext/mathematical/lsmproperties.c +418 -0
  127. data/ext/mathematical/lsmproperties.h +85 -0
  128. data/ext/mathematical/lsmstr.c +231 -0
  129. data/ext/mathematical/lsmstr.h +114 -0
  130. data/ext/mathematical/lsmsvg.h +67 -0
  131. data/ext/mathematical/lsmsvgaelement.c +73 -0
  132. data/ext/mathematical/lsmsvgaelement.h +55 -0
  133. data/ext/mathematical/lsmsvgattributes.h +113 -0
  134. data/ext/mathematical/lsmsvgcircleelement.c +153 -0
  135. data/ext/mathematical/lsmsvgcircleelement.h +59 -0
  136. data/ext/mathematical/lsmsvgclippathelement.c +134 -0
  137. data/ext/mathematical/lsmsvgclippathelement.h +59 -0
  138. data/ext/mathematical/lsmsvgcolors.c +212 -0
  139. data/ext/mathematical/lsmsvgcolors.h +39 -0
  140. data/ext/mathematical/lsmsvgdefselement.c +74 -0
  141. data/ext/mathematical/lsmsvgdefselement.h +55 -0
  142. data/ext/mathematical/lsmsvgdocument.c +230 -0
  143. data/ext/mathematical/lsmsvgdocument.h +58 -0
  144. data/ext/mathematical/lsmsvgelement.c +367 -0
  145. data/ext/mathematical/lsmsvgelement.h +81 -0
  146. data/ext/mathematical/lsmsvgellipseelement.c +158 -0
  147. data/ext/mathematical/lsmsvgellipseelement.h +60 -0
  148. data/ext/mathematical/lsmsvgenums.c +544 -0
  149. data/ext/mathematical/lsmsvgenums.h +357 -0
  150. data/ext/mathematical/lsmsvgenumtypes.c +1083 -0
  151. data/ext/mathematical/lsmsvgenumtypes.c.template +39 -0
  152. data/ext/mathematical/lsmsvgenumtypes.h +111 -0
  153. data/ext/mathematical/lsmsvgenumtypes.h.template +26 -0
  154. data/ext/mathematical/lsmsvgfilterblend.c +105 -0
  155. data/ext/mathematical/lsmsvgfilterblend.h +58 -0
  156. data/ext/mathematical/lsmsvgfiltercomposite.c +109 -0
  157. data/ext/mathematical/lsmsvgfiltercomposite.h +58 -0
  158. data/ext/mathematical/lsmsvgfilterelement.c +266 -0
  159. data/ext/mathematical/lsmsvgfilterelement.h +66 -0
  160. data/ext/mathematical/lsmsvgfilterflood.c +86 -0
  161. data/ext/mathematical/lsmsvgfilterflood.h +55 -0
  162. data/ext/mathematical/lsmsvgfiltergaussianblur.c +114 -0
  163. data/ext/mathematical/lsmsvgfiltergaussianblur.h +57 -0
  164. data/ext/mathematical/lsmsvgfiltermerge.c +98 -0
  165. data/ext/mathematical/lsmsvgfiltermerge.h +55 -0
  166. data/ext/mathematical/lsmsvgfiltermergenode.c +87 -0
  167. data/ext/mathematical/lsmsvgfiltermergenode.h +57 -0
  168. data/ext/mathematical/lsmsvgfilteroffset.c +112 -0
  169. data/ext/mathematical/lsmsvgfilteroffset.h +58 -0
  170. data/ext/mathematical/lsmsvgfilterprimitive.c +168 -0
  171. data/ext/mathematical/lsmsvgfilterprimitive.h +66 -0
  172. data/ext/mathematical/lsmsvgfilterspecularlighting.c +127 -0
  173. data/ext/mathematical/lsmsvgfilterspecularlighting.h +60 -0
  174. data/ext/mathematical/lsmsvgfiltersurface.c +455 -0
  175. data/ext/mathematical/lsmsvgfiltersurface.h +66 -0
  176. data/ext/mathematical/lsmsvgfiltertile.c +102 -0
  177. data/ext/mathematical/lsmsvgfiltertile.h +57 -0
  178. data/ext/mathematical/lsmsvggelement.c +73 -0
  179. data/ext/mathematical/lsmsvggelement.h +55 -0
  180. data/ext/mathematical/lsmsvggradientelement.c +151 -0
  181. data/ext/mathematical/lsmsvggradientelement.h +68 -0
  182. data/ext/mathematical/lsmsvgimageelement.c +261 -0
  183. data/ext/mathematical/lsmsvgimageelement.h +67 -0
  184. data/ext/mathematical/lsmsvglength.c +93 -0
  185. data/ext/mathematical/lsmsvglength.h +59 -0
  186. data/ext/mathematical/lsmsvglineargradientelement.c +271 -0
  187. data/ext/mathematical/lsmsvglineargradientelement.h +60 -0
  188. data/ext/mathematical/lsmsvglineelement.c +153 -0
  189. data/ext/mathematical/lsmsvglineelement.h +60 -0
  190. data/ext/mathematical/lsmsvgmarkerelement.c +266 -0
  191. data/ext/mathematical/lsmsvgmarkerelement.h +74 -0
  192. data/ext/mathematical/lsmsvgmaskelement.c +232 -0
  193. data/ext/mathematical/lsmsvgmaskelement.h +64 -0
  194. data/ext/mathematical/lsmsvgmatrix.c +205 -0
  195. data/ext/mathematical/lsmsvgmatrix.h +59 -0
  196. data/ext/mathematical/lsmsvgpathelement.c +115 -0
  197. data/ext/mathematical/lsmsvgpathelement.h +59 -0
  198. data/ext/mathematical/lsmsvgpatternelement.c +398 -0
  199. data/ext/mathematical/lsmsvgpatternelement.h +69 -0
  200. data/ext/mathematical/lsmsvgpolygonelement.c +106 -0
  201. data/ext/mathematical/lsmsvgpolygonelement.h +57 -0
  202. data/ext/mathematical/lsmsvgpolylineelement.c +106 -0
  203. data/ext/mathematical/lsmsvgpolylineelement.h +57 -0
  204. data/ext/mathematical/lsmsvgradialgradientelement.c +323 -0
  205. data/ext/mathematical/lsmsvgradialgradientelement.h +61 -0
  206. data/ext/mathematical/lsmsvgrectelement.c +184 -0
  207. data/ext/mathematical/lsmsvgrectelement.h +62 -0
  208. data/ext/mathematical/lsmsvgstopelement.c +106 -0
  209. data/ext/mathematical/lsmsvgstopelement.h +57 -0
  210. data/ext/mathematical/lsmsvgstyle.c +558 -0
  211. data/ext/mathematical/lsmsvgstyle.h +217 -0
  212. data/ext/mathematical/lsmsvgsvgelement.c +260 -0
  213. data/ext/mathematical/lsmsvgsvgelement.h +71 -0
  214. data/ext/mathematical/lsmsvgswitchelement.c +103 -0
  215. data/ext/mathematical/lsmsvgswitchelement.h +55 -0
  216. data/ext/mathematical/lsmsvgsymbolelement.c +74 -0
  217. data/ext/mathematical/lsmsvgsymbolelement.h +55 -0
  218. data/ext/mathematical/lsmsvgtextelement.c +170 -0
  219. data/ext/mathematical/lsmsvgtextelement.h +58 -0
  220. data/ext/mathematical/lsmsvgtraits.c +1158 -0
  221. data/ext/mathematical/lsmsvgtraits.h +103 -0
  222. data/ext/mathematical/lsmsvgtransformable.c +106 -0
  223. data/ext/mathematical/lsmsvgtransformable.h +54 -0
  224. data/ext/mathematical/lsmsvgtspanelement.c +143 -0
  225. data/ext/mathematical/lsmsvgtspanelement.h +58 -0
  226. data/ext/mathematical/lsmsvgtypes.h +77 -0
  227. data/ext/mathematical/lsmsvguseelement.c +237 -0
  228. data/ext/mathematical/lsmsvguseelement.h +69 -0
  229. data/ext/mathematical/lsmsvgview.c +2400 -0
  230. data/ext/mathematical/lsmsvgview.h +168 -0
  231. data/ext/mathematical/lsmtraits.c +119 -0
  232. data/ext/mathematical/lsmtraits.h +49 -0
  233. data/ext/mathematical/lsmtypes.h +36 -0
  234. data/ext/mathematical/lsmutils.c +54 -0
  235. data/ext/mathematical/lsmutils.h +56 -0
  236. data/ext/mathematical/mathematical.c +122 -0
  237. data/ext/mathematical/y.tab.c +6179 -0
  238. data/ext/mathematical/y.tab.h +389 -0
  239. data/lib/mathematical.rb +7 -3
  240. data/lib/mathematical/parser.rb +1 -1
  241. data/lib/mathematical/render.rb +51 -77
  242. data/lib/mathematical/version.rb +1 -1
  243. data/mathematical.gemspec +5 -3
  244. data/script/bench +21 -0
  245. data/script/single_test +7 -0
  246. data/test/mathematical/basic_test.rb +30 -1
  247. data/test/mathematical/fixtures/after/brackets_display.html +1 -0
  248. data/test/mathematical/fixtures/after/dollar_sign_inline.html +1 -0
  249. data/test/mathematical/fixtures/after/equation_display.html +1 -0
  250. data/test/mathematical/fixtures/after/multiple_dollar_inline.html +1 -0
  251. data/test/mathematical/fixtures/after/parens_inline.html +1 -0
  252. data/test/mathematical/fixtures/before/brackets_display.text +1 -0
  253. data/test/mathematical/fixtures/before/{basic.text → dollar_sign_inline.text} +0 -0
  254. data/test/mathematical/fixtures/before/equation_display.text +1 -0
  255. data/test/mathematical/fixtures/before/multiple_dollar_inline.text +1 -0
  256. data/test/mathematical/fixtures/before/parens_inline.text +1 -0
  257. data/test/mathematical/fixtures/performance/big_file.text +1767 -0
  258. data/test/mathematical/performance_test.rb +13 -0
  259. data/test/test_helper.rb +1 -0
  260. metadata +303 -18
  261. data/test/mathematical/fixtures/after/basic.html +0 -1
@@ -0,0 +1,64 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2010 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ #ifndef LSM_DOM_NAMED_NODE_MAP_H
25
+ #define LSM_DOM_NAMED_NODE_MAP_H
26
+
27
+ #include <lsmdomtypes.h>
28
+
29
+ G_BEGIN_DECLS
30
+
31
+ #define LSM_TYPE_DOM_NAMED_NODE_MAP (lsm_dom_named_node_map_get_type ())
32
+ #define LSM_DOM_NAMED_NODE_MAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMap))
33
+ #define LSM_DOM_NAMED_NODE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMapClass))
34
+ #define LSM_IS_DOM_NAMED_NODE_MAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NAMED_NODE_MAP))
35
+ #define LSM_IS_DOM_NAMED_NODE_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NAMED_NODE_MAP))
36
+ #define LSM_DOM_NAMED_NODE_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NAMED_NODE_MAP, LsmDomNamedNodeMapClass))
37
+
38
+ typedef struct _LsmDomNamedNodeMapClass LsmDomNamedNodeMapClass;
39
+
40
+ struct _LsmDomNamedNodeMap {
41
+ GObject object;
42
+ };
43
+
44
+ struct _LsmDomNamedNodeMapClass {
45
+ GObjectClass parent_class;
46
+
47
+ LsmDomNode * (*get) (LsmDomNamedNodeMap *map, const char *name);
48
+ LsmDomNode * (*set) (LsmDomNamedNodeMap *map, LsmDomNode *node);
49
+ LsmDomNode * (*remove) (LsmDomNamedNodeMap *map, const char *name);
50
+ LsmDomNode * (*get_item) (LsmDomNamedNodeMap *map, unsigned int index);
51
+ unsigned int (*get_length) (LsmDomNamedNodeMap *map);
52
+ };
53
+
54
+ GType lsm_dom_named_node_map_get_type (void);
55
+
56
+ LsmDomNode * lsm_dom_named_node_map_get_named_item (LsmDomNamedNodeMap *map, const char *name);
57
+ LsmDomNode * lsm_dom_named_node_map_set_named_item (LsmDomNamedNodeMap *map, LsmDomNode *node);
58
+ LsmDomNode * lsm_dom_named_node_map_remove_named_item (LsmDomNamedNodeMap *map, const char *name);
59
+ LsmDomNode * lsm_dom_named_node_map_get_item (LsmDomNamedNodeMap *map, unsigned int index);
60
+ unsigned int lsm_dom_named_node_map_get_length (LsmDomNamedNodeMap *map);
61
+
62
+ G_END_DECLS
63
+
64
+ #endif
@@ -0,0 +1,725 @@
1
+ /* Lasem
2
+ *
3
+ * Copyright © 2007-2010 Emmanuel Pacaud
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General
16
+ * Public License along with this library; if not, write to the
17
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
+ * Boston, MA 02111-1307, USA.
19
+ *
20
+ * Author:
21
+ * Emmanuel Pacaud <emmanuel@gnome.org>
22
+ */
23
+
24
+ /**
25
+ * SECTION:lsmdomnode
26
+ * @short_description: Base class for DOM nodes
27
+ */
28
+
29
+ #include <lsmdomnode.h>
30
+ #include <lsmdomnodelist.h>
31
+ #include <lsmdomdocument.h>
32
+ #include <lsmdebug.h>
33
+ #include <glib/gprintf.h>
34
+ #include <stdio.h>
35
+
36
+ /* LsmDomNodeChildList */
37
+
38
+
39
+ #define LSM_TYPE_DOM_NODE_CHILD_LIST (lsm_dom_node_child_list_get_type ())
40
+ #define LSM_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildList))
41
+ #define LSM_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildListClass))
42
+ #define LSM_IS_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_DOM_NODE_CHILD_LIST))
43
+ #define LSM_IS_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_DOM_NODE_CHILD_LIST))
44
+ #define LSM_DOM_NODE_CHILD_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_DOM_NODE_CHILD_LIST, LsmDomNodeChildListClass))
45
+
46
+ typedef struct _LsmDomNodeChildListClass LsmDomNodeChildListClass;
47
+
48
+ typedef struct {
49
+ LsmDomNodeList base;
50
+
51
+ LsmDomNode *parent_node;
52
+ } LsmDomNodeChildList;
53
+
54
+ struct _LsmDomNodeChildListClass {
55
+ LsmDomNodeListClass parent_class;
56
+ };
57
+
58
+ GType lsm_dom_node_child_list_get_type (void);
59
+
60
+ static GObjectClass *child_list_parent_class = NULL;
61
+
62
+ static void
63
+ lsm_dom_node_child_list_weak_notify_cb (void *user_data, GObject *object)
64
+ {
65
+ LsmDomNodeChildList *list = user_data;
66
+
67
+ list->parent_node = NULL;
68
+ }
69
+
70
+ static LsmDomNode *
71
+ lsm_dom_node_child_list_get_item (LsmDomNodeList *list, unsigned int index)
72
+ {
73
+ LsmDomNodeChildList *child_list = LSM_DOM_NODE_CHILD_LIST (list);
74
+ LsmDomNode *iter;
75
+ unsigned int i = 0;
76
+
77
+ if (child_list->parent_node == NULL)
78
+ return NULL;
79
+
80
+ for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling) {
81
+ if (i == index)
82
+ return iter;
83
+ i++;
84
+ }
85
+
86
+ return NULL;
87
+ }
88
+
89
+ static unsigned int
90
+ lsm_dom_node_child_list_get_length (LsmDomNodeList *list)
91
+ {
92
+ LsmDomNodeChildList *child_list = LSM_DOM_NODE_CHILD_LIST (list);
93
+ LsmDomNode *iter;
94
+ unsigned int length = 0;
95
+
96
+ if (child_list->parent_node == NULL)
97
+ return 0;
98
+
99
+ for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling)
100
+ length++;
101
+
102
+ return length;
103
+ }
104
+
105
+ LsmDomNodeList *
106
+ lsm_dom_node_child_list_new (LsmDomNode *parent_node)
107
+ {
108
+ LsmDomNodeChildList *list;
109
+
110
+ g_return_val_if_fail (LSM_IS_DOM_NODE (parent_node), NULL);
111
+
112
+ list = g_object_new (LSM_TYPE_DOM_NODE_CHILD_LIST, NULL);
113
+ list->parent_node = parent_node;
114
+
115
+ g_object_weak_ref (G_OBJECT (parent_node), lsm_dom_node_child_list_weak_notify_cb, list);
116
+
117
+ return LSM_DOM_NODE_LIST (list);
118
+ }
119
+
120
+ static void
121
+ lsm_dom_node_child_list_init (LsmDomNodeChildList *list)
122
+ {
123
+ }
124
+
125
+ static void
126
+ lsm_dom_node_child_list_finalize (GObject *object)
127
+ {
128
+ LsmDomNodeChildList *list = LSM_DOM_NODE_CHILD_LIST (object);
129
+
130
+ if (list->parent_node != NULL) {
131
+ g_object_weak_unref (G_OBJECT (list->parent_node), lsm_dom_node_child_list_weak_notify_cb, list);
132
+ list->parent_node = NULL;
133
+ }
134
+
135
+ child_list_parent_class->finalize (object);
136
+ }
137
+
138
+ static void
139
+ lsm_dom_node_child_list_class_init (LsmDomNodeChildListClass *klass)
140
+ {
141
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
142
+ LsmDomNodeListClass *node_list_class = LSM_DOM_NODE_LIST_CLASS (klass);
143
+
144
+ child_list_parent_class = g_type_class_peek_parent (klass);
145
+
146
+ object_class->finalize = lsm_dom_node_child_list_finalize;
147
+
148
+ node_list_class->get_item = lsm_dom_node_child_list_get_item;
149
+ node_list_class->get_length = lsm_dom_node_child_list_get_length;
150
+ }
151
+
152
+ G_DEFINE_TYPE (LsmDomNodeChildList, lsm_dom_node_child_list, LSM_TYPE_DOM_NODE_LIST)
153
+
154
+ static GObjectClass *parent_class = NULL;
155
+
156
+ /* LsmDomNode implementation */
157
+
158
+
159
+ /**
160
+ * lsm_dom_node_get_node_name:
161
+ * @self: a #LsmDomNode
162
+ *
163
+ * Gets the node name.
164
+ *
165
+ * Return value: the node name.
166
+ */
167
+
168
+ const char*
169
+ lsm_dom_node_get_node_name (LsmDomNode* self)
170
+ {
171
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
172
+
173
+ g_return_val_if_fail (node_class != NULL, NULL);
174
+
175
+ if (node_class->get_node_name)
176
+ return node_class->get_node_name (self);
177
+
178
+ return NULL;
179
+ }
180
+
181
+ /**
182
+ * lsm_dom_node_get_node_value:
183
+ * @self: a #LsmDomNode
184
+ *
185
+ * Gets the node value.
186
+ *
187
+ * Return value: the node value.
188
+ */
189
+
190
+ const char*
191
+ lsm_dom_node_get_node_value (LsmDomNode* self)
192
+ {
193
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
194
+
195
+ g_return_val_if_fail (node_class != NULL, NULL);
196
+
197
+ if (node_class->get_node_value)
198
+ return node_class->get_node_value (self);
199
+
200
+ return NULL;
201
+ }
202
+
203
+ void
204
+ lsm_dom_node_set_node_value (LsmDomNode* self, const char* new_value)
205
+ {
206
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
207
+
208
+ g_return_if_fail (node_class != NULL);
209
+ g_return_if_fail (new_value != NULL);
210
+
211
+ if (node_class->set_node_value)
212
+ node_class->set_node_value (self, new_value);
213
+ }
214
+
215
+ LsmDomNodeType lsm_dom_node_get_node_type (LsmDomNode* self)
216
+ {
217
+ LsmDomNodeClass *node_class = LSM_DOM_NODE_GET_CLASS (self);
218
+
219
+ g_return_val_if_fail (node_class != NULL, 0);
220
+
221
+ if (node_class->get_node_type)
222
+ return node_class->get_node_type (self);
223
+
224
+ return 0;
225
+ }
226
+
227
+ /**
228
+ * lsm_dom_node_get_parent_node:
229
+ * @self: a #LsmDomNode
230
+ *
231
+ * Returns: (transfer none): node parent
232
+ */
233
+
234
+ LsmDomNode*
235
+ lsm_dom_node_get_parent_node (LsmDomNode* self)
236
+ {
237
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
238
+
239
+ return self->parent_node;
240
+ }
241
+
242
+ /**
243
+ * lsm_dom_node_get_child_nodes:
244
+ * @self: a #LsmDomNode
245
+ *
246
+ * Returns: (transfer none): node child list
247
+ */
248
+
249
+ LsmDomNodeList*
250
+ lsm_dom_node_get_child_nodes (LsmDomNode* self)
251
+ {
252
+ LsmDomNodeList *list;
253
+
254
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
255
+
256
+ list = g_object_get_data (G_OBJECT (self), "child-nodes");
257
+
258
+ if (list == NULL) {
259
+ list = lsm_dom_node_child_list_new (self);
260
+ g_object_set_data_full (G_OBJECT (self), "child-nodes", list, g_object_unref);
261
+ }
262
+
263
+ return list;
264
+ }
265
+
266
+ /**
267
+ * lsm_dom_node_get_first_child:
268
+ * @self: a #LsmDomNode
269
+ *
270
+ * Returns: (transfer none): node first child
271
+ */
272
+
273
+ LsmDomNode*
274
+ lsm_dom_node_get_first_child (LsmDomNode* self)
275
+ {
276
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
277
+
278
+ return self->first_child;
279
+ }
280
+
281
+ /**
282
+ * lsm_dom_node_get_last_child:
283
+ * @self: a #LsmDomNode
284
+ *
285
+ * Returns: (transfer none): node last child
286
+ */
287
+
288
+ LsmDomNode*
289
+ lsm_dom_node_get_last_child (LsmDomNode* self)
290
+ {
291
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
292
+
293
+ return self->last_child;
294
+ }
295
+
296
+ /**
297
+ * lsm_dom_node_get_previous_sibling:
298
+ * @self: a #LsmDomNode
299
+ *
300
+ * Returns: (transfer none): node previous sibling
301
+ */
302
+
303
+ LsmDomNode*
304
+ lsm_dom_node_get_previous_sibling (LsmDomNode* self)
305
+ {
306
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
307
+
308
+ return self->previous_sibling;
309
+ }
310
+
311
+ /**
312
+ * lsm_dom_node_get_next_sibling:
313
+ * @self: a #LsmDomNode
314
+ *
315
+ * Returns: (transfer none): node next sibling
316
+ */
317
+
318
+ LsmDomNode*
319
+ lsm_dom_node_get_next_sibling (LsmDomNode* self)
320
+ {
321
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
322
+
323
+ return self->next_sibling;
324
+ }
325
+
326
+ #if 0
327
+ LsmDomNamedNodeMap*
328
+ lsm_dom_node_get_attributes (LsmDomNode* self)
329
+ {
330
+ return LSM_DOM_NODE_GET_CLASS (self)->get_attributes (self);
331
+ }
332
+ #endif
333
+
334
+ /**
335
+ * lsm_dom_node_get_owner_document:
336
+ * @self: a #LsmDomNode
337
+ *
338
+ * Returns: (transfer none): node owner document
339
+ */
340
+
341
+ LsmDomDocument *
342
+ lsm_dom_node_get_owner_document (LsmDomNode* self)
343
+ {
344
+ LsmDomNode *parent;
345
+
346
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
347
+
348
+ for (parent = self;
349
+ parent != NULL &&
350
+ !LSM_IS_DOM_DOCUMENT (parent);
351
+ parent = parent->parent_node);
352
+
353
+ return LSM_DOM_DOCUMENT (parent);
354
+ }
355
+
356
+ /**
357
+ * lsm_dom_node_insert_before:
358
+ * @self: a #LsmDomNode
359
+ * @new_child: (transfer full): node to insert
360
+ * @ref_child: (transfer none): reference node, i.e., the node before which the new node must be inserted.
361
+ *
362
+ * Inserts the node @new_child before the existing child node @ref_child. If
363
+ * @ref_child is null, insert @new_child at the end of the list of children.
364
+ * If the @new_child is already in the tree, it is first removed.
365
+ *
366
+ * Returns: (transfer none): the inserted node.
367
+ */
368
+
369
+ /* TODO:
370
+ * If @new_child is a #LsmDocumentFragment object, all of its children are inserted,
371
+ * in the same order, before @ref_child.
372
+ * Check if new_child is an ancestor of self.
373
+ */
374
+
375
+ LsmDomNode*
376
+ lsm_dom_node_insert_before (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* ref_child)
377
+ {
378
+ LsmDomNodeClass *node_class;
379
+
380
+ if (ref_child == NULL)
381
+ lsm_dom_node_append_child (self, new_child);
382
+
383
+ g_return_val_if_fail (LSM_IS_DOM_NODE (new_child), NULL);
384
+
385
+ if (new_child->parent_node != NULL)
386
+ lsm_dom_node_remove_child (self, new_child);
387
+
388
+ if (!LSM_IS_DOM_NODE (self)) {
389
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
390
+ g_object_unref (new_child);
391
+ return NULL;
392
+ }
393
+
394
+ if (!LSM_IS_DOM_NODE (ref_child)) {
395
+ g_critical ("%s: ref_child is not a LsmDomNode", G_STRFUNC);
396
+ g_object_unref (new_child);
397
+ return NULL;
398
+ }
399
+
400
+ if (ref_child->parent_node != self) {
401
+ lsm_debug_dom ("[LsmDomNode::insert_before] Ref child '%s' doesn't belong to '%s'",
402
+ lsm_dom_node_get_node_name (ref_child),
403
+ lsm_dom_node_get_node_name (self));
404
+ g_object_unref (new_child);
405
+ return NULL;
406
+ }
407
+
408
+ if (!LSM_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
409
+ lsm_debug_dom ("[LsmDomNode::insert_before] Can't append '%s' to '%s'",
410
+ lsm_dom_node_get_node_name (new_child),
411
+ lsm_dom_node_get_node_name (self));
412
+ g_object_unref (new_child);
413
+ return NULL;
414
+ }
415
+
416
+ new_child->parent_node = self;
417
+ new_child->next_sibling = ref_child;
418
+ new_child->previous_sibling = ref_child->previous_sibling;
419
+
420
+ if (ref_child->previous_sibling == NULL)
421
+ self->first_child = new_child;
422
+ else
423
+ ref_child->previous_sibling->next_sibling = new_child;
424
+
425
+ ref_child->previous_sibling = new_child;
426
+
427
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
428
+
429
+ if (node_class->post_new_child)
430
+ node_class->post_new_child (self, new_child);
431
+
432
+ lsm_dom_node_changed (self);
433
+
434
+ return new_child;
435
+ }
436
+
437
+ /**
438
+ * lsm_dom_node_replace_child:
439
+ * @self: a #LsmDomNode
440
+ * @new_child: (transfer full): a replacement node
441
+ * @old_child: (transfer none): node to replace
442
+ *
443
+ * Replaces the child node @old_child with @new_child in the list of children,
444
+ * and returns the @old_child node.
445
+ * If the @new_child is already in the tree, it is first removed.
446
+ *
447
+ * Returns: (transfer full): the replaced node.
448
+ */
449
+
450
+ /* TODO:
451
+ * Check if new_child is an ancestor of self.
452
+ */
453
+
454
+ LsmDomNode*
455
+ lsm_dom_node_replace_child (LsmDomNode* self, LsmDomNode* new_child, LsmDomNode* old_child)
456
+ {
457
+ LsmDomNode *next_sibling;
458
+ LsmDomNode *node;
459
+
460
+ if (new_child == NULL)
461
+ return lsm_dom_node_remove_child (self, old_child);
462
+
463
+ if (!LSM_IS_DOM_NODE (new_child)) {
464
+ g_critical ("%s: new_child is not a LsmDomNode", G_STRFUNC);
465
+ if (LSM_IS_DOM_NODE (old_child))
466
+ g_object_unref (old_child);
467
+ return NULL;
468
+ }
469
+
470
+ if (new_child->parent_node != NULL)
471
+ lsm_dom_node_remove_child (self, new_child);
472
+
473
+ if (old_child == NULL) {
474
+ lsm_debug_dom ("[LsmDomNode::replace_child] old_child == NULL)");
475
+ g_object_unref (new_child);
476
+ return NULL;
477
+ }
478
+
479
+ if (!LSM_IS_DOM_NODE (old_child)) {
480
+ g_critical ("%s: old_child is not a LsmDomNode", G_STRFUNC);
481
+ g_object_unref (new_child);
482
+ return NULL;
483
+ }
484
+
485
+ if (!LSM_IS_DOM_NODE (self)) {
486
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
487
+ g_object_unref (new_child);
488
+ g_object_unref (old_child);
489
+ return NULL;
490
+ }
491
+
492
+ if (old_child->parent_node != self) {
493
+ g_object_unref (new_child);
494
+ g_object_unref (old_child);
495
+ return NULL;
496
+ }
497
+
498
+ next_sibling = old_child->next_sibling;
499
+
500
+ node = lsm_dom_node_remove_child (self, old_child);
501
+ if (node != old_child) {
502
+ g_object_unref (new_child);
503
+ g_object_unref (old_child);
504
+ return NULL;
505
+ }
506
+
507
+ if (next_sibling == NULL)
508
+ lsm_dom_node_append_child (self, new_child);
509
+ else
510
+ lsm_dom_node_insert_before (self, new_child, next_sibling);
511
+
512
+ return old_child;
513
+ }
514
+
515
+ /**
516
+ * lsm_dom_node_remove_child:
517
+ * @self: a #LsmDomNode
518
+ * @old_child: (transfer none): node to remove.
519
+ *
520
+ * Removes the child node indicated by @old_child from the list of children, and returns it.
521
+ *
522
+ * Returns: (transfer full): the removed node.
523
+ */
524
+
525
+ LsmDomNode*
526
+ lsm_dom_node_remove_child (LsmDomNode* self, LsmDomNode* old_child)
527
+ {
528
+ LsmDomNode *node;
529
+ LsmDomNodeClass *node_class;
530
+
531
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), NULL);
532
+
533
+ if (old_child == NULL)
534
+ return NULL;
535
+
536
+ g_return_val_if_fail (LSM_IS_DOM_NODE (old_child), NULL);
537
+
538
+ for (node = self->first_child;
539
+ node != NULL && node != old_child;
540
+ node = node->next_sibling);
541
+
542
+ if (node == NULL)
543
+ return NULL;
544
+
545
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
546
+
547
+ if (node_class->pre_remove_child)
548
+ node_class->pre_remove_child (self, old_child);
549
+
550
+ if (self->first_child == old_child)
551
+ self->first_child = old_child->next_sibling;
552
+ if (self->last_child == old_child)
553
+ self->last_child = old_child->previous_sibling;
554
+
555
+ if (old_child->next_sibling != NULL)
556
+ old_child->next_sibling->previous_sibling = old_child->previous_sibling;
557
+ if (old_child->previous_sibling != NULL)
558
+ old_child->previous_sibling->next_sibling = old_child->next_sibling;
559
+
560
+ old_child->parent_node = NULL;
561
+ old_child->next_sibling = NULL;
562
+ old_child->previous_sibling = NULL;
563
+
564
+ lsm_dom_node_changed (self);
565
+
566
+ return old_child;
567
+ }
568
+
569
+ /**
570
+ * lsm_dom_node_append_child:
571
+ * @self: a #LsmDomNode
572
+ * @new_child: (transfer full): node to append
573
+ *
574
+ * Adds the node @new_child to the end of the list of children of this node.
575
+ * If the @new_child is already in the tree, it is first removed.
576
+ *
577
+ * Returns: (transfer none): the added node.
578
+ */
579
+
580
+ LsmDomNode *
581
+ lsm_dom_node_append_child (LsmDomNode* self, LsmDomNode* new_child)
582
+ {
583
+ LsmDomNodeClass *node_class;
584
+
585
+ if (new_child == NULL)
586
+ return NULL;
587
+
588
+ g_return_val_if_fail (LSM_IS_DOM_NODE (new_child), NULL);
589
+
590
+ if (!LSM_IS_DOM_NODE (self)) {
591
+ g_critical ("%s: self is not a LsmDomNode", G_STRFUNC);
592
+ g_object_unref (new_child);
593
+ return NULL;
594
+ }
595
+
596
+ if (new_child->parent_node != NULL)
597
+ lsm_dom_node_remove_child (self, new_child);
598
+
599
+ if (!LSM_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
600
+ lsm_debug_dom ("[LsmDomNode::append_child] Can't append '%s' to '%s'",
601
+ lsm_dom_node_get_node_name (new_child),
602
+ lsm_dom_node_get_node_name (self));
603
+ g_object_unref (new_child);
604
+ return NULL;
605
+ }
606
+
607
+ if (self->first_child == NULL)
608
+ self->first_child = new_child;
609
+ if (self->last_child != NULL)
610
+ self->last_child->next_sibling = new_child;
611
+
612
+ new_child->parent_node = self;
613
+ new_child->next_sibling = NULL;
614
+ new_child->previous_sibling = self->last_child;
615
+ self->last_child = new_child;
616
+
617
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
618
+
619
+ if (node_class->post_new_child)
620
+ node_class->post_new_child (self, new_child);
621
+
622
+ lsm_dom_node_changed (self);
623
+
624
+ return new_child;
625
+ }
626
+
627
+ static gboolean
628
+ lsm_dom_node_can_append_child_default (LsmDomNode *self, LsmDomNode* new_child)
629
+ {
630
+ return FALSE;
631
+ }
632
+
633
+ void
634
+ lsm_dom_node_changed (LsmDomNode *self)
635
+ {
636
+ LsmDomNode *parent_node;
637
+ LsmDomNode *child_node;
638
+ LsmDomNodeClass *node_class;
639
+
640
+ g_return_if_fail (LSM_IS_DOM_NODE (self));
641
+
642
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
643
+
644
+ if (node_class->changed)
645
+ node_class->changed (self);
646
+
647
+ child_node = self;
648
+ for (parent_node = self->parent_node;
649
+ parent_node != NULL;
650
+ parent_node = parent_node->parent_node) {
651
+ node_class = LSM_DOM_NODE_GET_CLASS (parent_node);
652
+ if (node_class->child_changed == NULL ||
653
+ !node_class->child_changed (parent_node, child_node))
654
+ break;
655
+ child_node = parent_node;
656
+ }
657
+ }
658
+
659
+ gboolean
660
+ lsm_dom_node_has_child_nodes (LsmDomNode* self)
661
+ {
662
+ g_return_val_if_fail (LSM_IS_DOM_NODE (self), FALSE);
663
+
664
+ return self->first_child != NULL;
665
+ }
666
+
667
+ static void
668
+ lsm_dom_node_write_to_stream_default (LsmDomNode *self, GOutputStream *stream, GError **error)
669
+ {
670
+ LsmDomNode *child;
671
+
672
+ for (child = self->first_child; child != NULL; child = child->next_sibling)
673
+ lsm_dom_node_write_to_stream (child, stream, error);
674
+ }
675
+
676
+ void
677
+ lsm_dom_node_write_to_stream (LsmDomNode *self, GOutputStream *stream, GError **error)
678
+ {
679
+ LsmDomNodeClass *node_class;
680
+
681
+ g_return_if_fail (LSM_IS_DOM_NODE (self));
682
+ g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
683
+
684
+ node_class = LSM_DOM_NODE_GET_CLASS (self);
685
+ if (node_class->write_to_stream != NULL)
686
+ node_class->write_to_stream (self, stream, error);
687
+ }
688
+
689
+ static void
690
+ lsm_dom_node_init (LsmDomNode *node)
691
+ {
692
+ }
693
+
694
+ static void
695
+ lsm_dom_node_finalize (GObject *object)
696
+ {
697
+ LsmDomNode *node = LSM_DOM_NODE (object);
698
+ LsmDomNode *child, *next_child;
699
+
700
+ child = node->first_child;
701
+ while (child != NULL) {
702
+ next_child = child->next_sibling;
703
+ g_object_unref (child);
704
+ child = next_child;
705
+ }
706
+
707
+ parent_class->finalize (object);
708
+ }
709
+
710
+ /* LsmDomNode class */
711
+
712
+ static void
713
+ lsm_dom_node_class_init (LsmDomNodeClass *node_class)
714
+ {
715
+ GObjectClass *object_class = G_OBJECT_CLASS (node_class);
716
+
717
+ parent_class = g_type_class_peek_parent (node_class);
718
+
719
+ object_class->finalize = lsm_dom_node_finalize;
720
+
721
+ node_class->can_append_child = lsm_dom_node_can_append_child_default;
722
+ node_class->write_to_stream = lsm_dom_node_write_to_stream_default;
723
+ }
724
+
725
+ G_DEFINE_ABSTRACT_TYPE (LsmDomNode, lsm_dom_node, G_TYPE_OBJECT)