nokogiri 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (88) hide show
  1. data/History.ja.txt +34 -0
  2. data/History.txt +36 -0
  3. data/Manifest.txt +21 -0
  4. data/README.ja.txt +1 -1
  5. data/README.txt +1 -1
  6. data/Rakefile +27 -89
  7. data/ext/nokogiri/extconf.rb +48 -63
  8. data/ext/nokogiri/html_document.c +90 -29
  9. data/ext/nokogiri/html_sax_parser.c +23 -2
  10. data/ext/nokogiri/native.c +18 -8
  11. data/ext/nokogiri/native.h +22 -0
  12. data/ext/nokogiri/xml_attr.c +83 -0
  13. data/ext/nokogiri/xml_attr.h +9 -0
  14. data/ext/nokogiri/xml_cdata.c +1 -1
  15. data/ext/nokogiri/xml_document.c +84 -18
  16. data/ext/nokogiri/xml_document_fragment.c +38 -0
  17. data/ext/nokogiri/xml_document_fragment.h +10 -0
  18. data/ext/nokogiri/xml_dtd.c +2 -22
  19. data/ext/nokogiri/xml_entity_reference.c +41 -0
  20. data/ext/nokogiri/xml_entity_reference.h +9 -0
  21. data/ext/nokogiri/xml_io.c +10 -3
  22. data/ext/nokogiri/xml_io.h +1 -0
  23. data/ext/nokogiri/xml_node.c +116 -66
  24. data/ext/nokogiri/xml_node_set.c +5 -1
  25. data/ext/nokogiri/xml_processing_instruction.c +44 -0
  26. data/ext/nokogiri/xml_processing_instruction.h +9 -0
  27. data/ext/nokogiri/xml_reader.c +20 -4
  28. data/ext/nokogiri/xml_sax_parser.c +51 -15
  29. data/ext/nokogiri/xml_sax_push_parser.c +85 -0
  30. data/ext/nokogiri/xml_sax_push_parser.h +9 -0
  31. data/ext/nokogiri/xml_syntax_error.c +12 -8
  32. data/ext/nokogiri/xml_syntax_error.h +2 -1
  33. data/ext/nokogiri/xml_xpath_context.c +11 -2
  34. data/ext/nokogiri/xslt_stylesheet.c +1 -6
  35. data/lib/nokogiri.rb +10 -13
  36. data/lib/nokogiri/css.rb +1 -1
  37. data/lib/nokogiri/css/generated_parser.rb +287 -295
  38. data/lib/nokogiri/css/generated_tokenizer.rb +36 -51
  39. data/lib/nokogiri/css/node.rb +1 -3
  40. data/lib/nokogiri/css/parser.rb +21 -12
  41. data/lib/nokogiri/css/parser.y +55 -44
  42. data/lib/nokogiri/css/syntax_error.rb +2 -1
  43. data/lib/nokogiri/css/tokenizer.rex +23 -32
  44. data/lib/nokogiri/decorators/hpricot/node_set.rb +1 -1
  45. data/lib/nokogiri/html.rb +10 -4
  46. data/lib/nokogiri/html/document.rb +6 -2
  47. data/lib/nokogiri/syntax_error.rb +4 -0
  48. data/lib/nokogiri/version.rb +2 -1
  49. data/lib/nokogiri/xml.rb +3 -1
  50. data/lib/nokogiri/xml/attr.rb +3 -4
  51. data/lib/nokogiri/xml/cdata.rb +1 -1
  52. data/lib/nokogiri/xml/document.rb +4 -7
  53. data/lib/nokogiri/xml/document_fragment.rb +9 -0
  54. data/lib/nokogiri/xml/dtd.rb +3 -0
  55. data/lib/nokogiri/xml/node.rb +144 -40
  56. data/lib/nokogiri/xml/node/save_options.rb +32 -0
  57. data/lib/nokogiri/xml/node_set.rb +11 -20
  58. data/lib/nokogiri/xml/processing_instruction.rb +6 -0
  59. data/lib/nokogiri/xml/reader.rb +5 -0
  60. data/lib/nokogiri/xml/sax.rb +1 -0
  61. data/lib/nokogiri/xml/sax/push_parser.rb +47 -0
  62. data/lib/nokogiri/xml/syntax_error.rb +3 -1
  63. data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
  64. data/tasks/test.rb +136 -0
  65. data/test/css/test_parser.rb +4 -0
  66. data/test/css/test_tokenizer.rb +30 -17
  67. data/test/css/test_xpath_visitor.rb +11 -0
  68. data/test/helper.rb +11 -0
  69. data/test/hpricot/test_builder.rb +2 -9
  70. data/test/hpricot/test_parser.rb +4 -4
  71. data/test/html/test_builder.rb +7 -7
  72. data/test/html/test_document.rb +90 -4
  73. data/test/html/test_node.rb +1 -0
  74. data/test/test_css_cache.rb +1 -3
  75. data/test/test_reader.rb +19 -1
  76. data/test/test_xslt_transforms.rb +1 -1
  77. data/test/xml/node/test_save_options.rb +20 -0
  78. data/test/xml/sax/test_parser.rb +17 -0
  79. data/test/xml/sax/test_push_parser.rb +67 -0
  80. data/test/xml/test_attr.rb +16 -0
  81. data/test/xml/test_cdata.rb +1 -1
  82. data/test/xml/test_document.rb +45 -0
  83. data/test/xml/test_document_fragment.rb +18 -0
  84. data/test/xml/test_dtd.rb +2 -4
  85. data/test/xml/test_entity_reference.rb +16 -0
  86. data/test/xml/test_node.rb +149 -80
  87. data/test/xml/test_processing_instruction.rb +24 -0
  88. metadata +28 -2
@@ -0,0 +1,38 @@
1
+ #include <xml_document_fragment.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * new(document)
6
+ *
7
+ * Create a new DocumentFragment element on the +document+
8
+ */
9
+ static VALUE new(VALUE klass, VALUE doc)
10
+ {
11
+ xmlDocPtr xml_doc;
12
+ Data_Get_Struct(doc, xmlDoc, xml_doc);
13
+
14
+ xmlNodePtr node = xmlNewDocFragment(xml_doc);
15
+
16
+ VALUE rb_node = Nokogiri_wrap_xml_node(node);
17
+
18
+ if(rb_block_given_p()) rb_yield(rb_node);
19
+
20
+ return rb_node;
21
+ }
22
+
23
+ VALUE cNokogiriXmlDocumentFragment;
24
+ void init_xml_document_fragment()
25
+ {
26
+ VALUE nokogiri = rb_define_module("Nokogiri");
27
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
28
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
29
+
30
+ /*
31
+ * DocumentFragment represents a DocumentFragment node in an xml document.
32
+ */
33
+ VALUE klass = rb_define_class_under(xml, "DocumentFragment", node);
34
+
35
+ cNokogiriXmlDocumentFragment = klass;
36
+
37
+ rb_define_singleton_method(klass, "new", new, 1);
38
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NOKOGIRI_XML_DOCUMENT_FRAGMENT
2
+ #define NOKOGIRI_XML_DOCUMENT_FRAGMENT
3
+
4
+ #include <native.h>
5
+
6
+ void init_xml_document_fragment();
7
+
8
+ extern VALUE cNokogiriXmlDocumentFragment;
9
+ #endif
10
+
@@ -44,26 +44,6 @@ static VALUE entities(VALUE self)
44
44
  return hash;
45
45
  }
46
46
 
47
- /*
48
- * call-seq:
49
- * attributes
50
- *
51
- * Get a hash of the attributes for this DTD.
52
- */
53
- static VALUE attributes(VALUE self)
54
- {
55
- xmlDtdPtr dtd;
56
- Data_Get_Struct(self, xmlDtd, dtd);
57
-
58
- if(!dtd->attributes) return Qnil;
59
-
60
- VALUE hash = rb_hash_new();
61
-
62
- xmlHashScan((xmlHashTablePtr)dtd->attributes, element_copier, (void *)hash);
63
-
64
- return hash;
65
- }
66
-
67
47
  /*
68
48
  * call-seq:
69
49
  * notations
@@ -108,14 +88,14 @@ void init_xml_dtd()
108
88
  {
109
89
  VALUE nokogiri = rb_define_module("Nokogiri");
110
90
  VALUE xml = rb_define_module_under(nokogiri, "XML");
91
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
111
92
 
112
93
  /*
113
94
  * Nokogiri::XML::DTD wraps DTD nodes in an XML document
114
95
  */
115
- VALUE klass = rb_define_class_under(xml, "DTD", cNokogiriXmlNode);
96
+ VALUE klass = rb_define_class_under(xml, "DTD", node);
116
97
 
117
98
  rb_define_method(klass, "notations", notations, 0);
118
99
  rb_define_method(klass, "elements", elements, 0);
119
- rb_define_method(klass, "attributes", attributes, 0);
120
100
  rb_define_method(klass, "entities", entities, 0);
121
101
  }
@@ -0,0 +1,41 @@
1
+ #include <xml_entity_reference.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * new(document, content)
6
+ *
7
+ * Create a new EntityReference element on the +document+ with +name+
8
+ */
9
+ static VALUE new(VALUE klass, VALUE doc, VALUE name)
10
+ {
11
+ xmlDocPtr xml_doc;
12
+ Data_Get_Struct(doc, xmlDoc, xml_doc);
13
+
14
+ xmlNodePtr node = xmlNewReference(
15
+ xml_doc,
16
+ (const xmlChar *)StringValuePtr(name)
17
+ );
18
+
19
+ VALUE rb_node = Nokogiri_wrap_xml_node(node);
20
+
21
+ if(rb_block_given_p()) rb_yield(rb_node);
22
+
23
+ return rb_node;
24
+ }
25
+
26
+ VALUE cNokogiriXmlEntityReference;
27
+ void init_xml_entity_reference()
28
+ {
29
+ VALUE nokogiri = rb_define_module("Nokogiri");
30
+ VALUE xml = rb_define_module_under(nokogiri, "XML");
31
+ VALUE node = rb_define_class_under(xml, "Node", rb_cObject);
32
+
33
+ /*
34
+ * EntityReference represents an EntityReference node in an xml document.
35
+ */
36
+ VALUE klass = rb_define_class_under(xml, "EntityReference", node);
37
+
38
+ cNokogiriXmlEntityReference = klass;
39
+
40
+ rb_define_singleton_method(klass, "new", new, 2);
41
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef NOKOGIRI_XML_ENTITY_REFERENCE
2
+ #define NOKOGIRI_XML_ENTITY_REFERENCE
3
+
4
+ #include <native.h>
5
+
6
+ void init_xml_entity_reference();
7
+
8
+ extern VALUE cNokogiriXmlEntityReference;
9
+ #endif
@@ -5,11 +5,18 @@ int io_read_callback(void * ctx, char * buffer, int len) {
5
5
  VALUE string = rb_funcall(io, rb_intern("read"), 1, INT2NUM(len));
6
6
 
7
7
  if(Qnil == string) return 0;
8
- VALUE length = rb_funcall(string, rb_intern("length"), 0);
9
8
 
10
- memcpy(buffer, StringValuePtr(string), (unsigned int)NUM2INT(length));
9
+ memcpy(buffer, StringValuePtr(string), (unsigned int)RSTRING_LEN(string));
11
10
 
12
- return NUM2INT(length);
11
+ return RSTRING_LEN(string);
12
+ }
13
+
14
+ int io_write_callback(void * ctx, char * buffer, int len) {
15
+ VALUE io = (VALUE)ctx;
16
+ VALUE string = rb_str_new(buffer, len);
17
+
18
+ rb_funcall(io, rb_intern("write"), 1, string);
19
+ return len;
13
20
  }
14
21
 
15
22
  int io_close_callback(void * ctx) {
@@ -4,6 +4,7 @@
4
4
  #include <native.h>
5
5
 
6
6
  int io_read_callback(void * ctx, char * buffer, int len);
7
+ int io_write_callback(void * ctx, char * buffer, int len);
7
8
  int io_close_callback(void * ctx);
8
9
 
9
10
  #endif
@@ -84,12 +84,8 @@ static VALUE duplicate_node(int argc, VALUE *argv, VALUE self)
84
84
  xmlNodePtr node, dup;
85
85
  Data_Get_Struct(self, xmlNode, node);
86
86
 
87
- dup = xmlCopyNode(node, NUM2INT(level));
87
+ dup = xmlDocCopyNode(node, node->doc, NUM2INT(level));
88
88
  if(dup == NULL) return Qnil;
89
- dup->doc = node->doc;
90
- assert(node->parent);
91
-
92
- xmlAddChild(node->parent, dup);
93
89
 
94
90
  return Nokogiri_wrap_xml_node(dup);
95
91
  }
@@ -211,9 +207,13 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
211
207
  {
212
208
  xmlNodePtr node;
213
209
  Data_Get_Struct(self, xmlNode, node);
214
- xmlSetProp(node, (xmlChar *)StringValuePtr(property),
210
+
211
+ xmlChar *buffer = xmlEncodeEntitiesReentrant(node->doc,
215
212
  (xmlChar *)StringValuePtr(value));
216
213
 
214
+ xmlSetProp(node, (xmlChar *)StringValuePtr(property), buffer);
215
+ xmlFree(buffer);
216
+
217
217
  return value;
218
218
  }
219
219
 
@@ -229,12 +229,35 @@ static VALUE get(VALUE self, VALUE attribute)
229
229
  xmlChar* propstr ;
230
230
  VALUE rval ;
231
231
  Data_Get_Struct(self, xmlNode, node);
232
+
233
+ if(attribute == Qnil) return Qnil;
234
+
232
235
  propstr = xmlGetProp(node, (xmlChar *)StringValuePtr(attribute));
236
+
237
+ if(NULL == propstr) return Qnil;
238
+
233
239
  rval = rb_str_new2((char *)propstr) ;
234
240
  xmlFree(propstr);
235
241
  return rval ;
236
242
  }
237
243
 
244
+ /*
245
+ * call-seq:
246
+ * attribute(name)
247
+ *
248
+ * Get the attribute node with +name+
249
+ */
250
+ static VALUE attr(VALUE self, VALUE name)
251
+ {
252
+ xmlNodePtr node;
253
+ xmlAttrPtr prop;
254
+ Data_Get_Struct(self, xmlNode, node);
255
+ prop = xmlHasProp(node, (xmlChar *)StringValuePtr(name));
256
+
257
+ if(! prop) return Qnil;
258
+ return Nokogiri_wrap_xml_node((xmlNodePtr)prop);
259
+ }
260
+
238
261
  /*
239
262
  * call-seq:
240
263
  * attribute_nodes()
@@ -293,11 +316,11 @@ static VALUE namespaces(VALUE self)
293
316
 
294
317
  /*
295
318
  * call-seq:
296
- * type
319
+ * node_type
297
320
  *
298
- * Get the type for this node
321
+ * Get the type for this Node
299
322
  */
300
- static VALUE type(VALUE self)
323
+ static VALUE node_type(VALUE self)
301
324
  {
302
325
  xmlNodePtr node;
303
326
  Data_Get_Struct(self, xmlNode, node);
@@ -479,55 +502,72 @@ static VALUE add_previous_sibling(VALUE self, VALUE rb_node)
479
502
 
480
503
  /*
481
504
  * call-seq:
482
- * to_html
505
+ * native_write_to(io, encoding, options)
483
506
  *
484
- * Returns this node as HTML
507
+ * Write this Node to +io+ with +encoding+ and +options+
485
508
  */
486
- static VALUE to_html(VALUE self)
509
+ static VALUE native_write_to(VALUE self, VALUE io, VALUE encoding, VALUE options)
487
510
  {
488
- xmlBufferPtr buf ;
489
- xmlNodePtr node ;
511
+ xmlNodePtr node;
512
+
490
513
  Data_Get_Struct(self, xmlNode, node);
491
514
 
492
- VALUE html;
515
+ xmlSaveCtxtPtr savectx = xmlSaveToIO(
516
+ (xmlOutputWriteCallback)io_write_callback,
517
+ (xmlOutputCloseCallback)io_close_callback,
518
+ (void *)io,
519
+ RTEST(encoding) ? StringValuePtr(encoding) : NULL,
520
+ NUM2INT(options)
521
+ );
493
522
 
494
- if(node->doc->type == XML_DOCUMENT_NODE)
495
- return rb_funcall(self, rb_intern("to_xml"), 0);
523
+ xmlSaveTree(savectx, node);
524
+ xmlSaveClose(savectx);
525
+ return io;
526
+ }
496
527
 
497
- buf = xmlBufferCreate() ;
498
- htmlNodeDump(buf, node->doc, node);
499
- html = rb_str_new2((char*)buf->content);
500
- xmlBufferFree(buf);
501
- return html ;
528
+ /*
529
+ * call-seq:
530
+ * line
531
+ *
532
+ * Returns the line for this Node
533
+ */
534
+ static VALUE line(VALUE self)
535
+ {
536
+ xmlNodePtr node;
537
+ Data_Get_Struct(self, xmlNode, node);
538
+
539
+ return INT2NUM(node->line);
502
540
  }
503
541
 
504
542
  /*
505
543
  * call-seq:
506
- * to_xml
544
+ * add_namespace(prefix, href)
507
545
  *
508
- * Returns this node as XML
546
+ * Add a namespace with +prefix+ using +href+
509
547
  */
510
- static VALUE to_xml(int argc, VALUE *argv, VALUE self)
548
+ static VALUE add_namespace(VALUE self, VALUE prefix, VALUE href)
511
549
  {
512
- xmlBufferPtr buf ;
513
- xmlNodePtr node ;
514
- VALUE xml, level;
550
+ xmlNodePtr node;
551
+ Data_Get_Struct(self, xmlNode, node);
515
552
 
516
- if(rb_scan_args(argc, argv, "01", &level) == 0)
517
- level = INT2NUM(1);
553
+ xmlNsPtr ns = xmlNewNs(
554
+ node,
555
+ (const xmlChar *)StringValuePtr(href),
556
+ (const xmlChar *)StringValuePtr(prefix)
557
+ );
518
558
 
519
- Check_Type(level, T_FIXNUM);
559
+ if(NULL == ns) return self;
520
560
 
521
- Data_Get_Struct(self, xmlNode, node);
561
+ xmlNewNsProp(
562
+ node,
563
+ ns,
564
+ (const xmlChar *)StringValuePtr(href),
565
+ (const xmlChar *)StringValuePtr(prefix)
566
+ );
522
567
 
523
- buf = xmlBufferCreate() ;
524
- xmlNodeDump(buf, node->doc, node, 2, NUM2INT(level));
525
- xml = rb_str_new2((char*)buf->content);
526
- xmlBufferFree(buf);
527
- return xml ;
568
+ return self;
528
569
  }
529
570
 
530
-
531
571
  /*
532
572
  * call-seq:
533
573
  * new(name)
@@ -550,30 +590,28 @@ static VALUE new(VALUE klass, VALUE name, VALUE document)
550
590
  return rb_node;
551
591
  }
552
592
 
553
-
554
593
  /*
555
594
  * call-seq:
556
- * new_from_str(string)
595
+ * dump_html
557
596
  *
558
- * Create a new node by parsing +string+
597
+ * Returns the Node as html.
559
598
  */
560
- static VALUE new_from_str(VALUE klass, VALUE xml)
561
- {
562
- /*
563
- * I couldn't find a more efficient way to do this. So we create a new
564
- * document and copy (recursively) the root node.
565
- */
566
- VALUE rb_doc ;
567
- xmlDocPtr doc ;
568
- xmlNodePtr node ;
599
+ static VALUE dump_html(VALUE self)
600
+ {
601
+ xmlBufferPtr buf ;
602
+ xmlNodePtr node ;
603
+ Data_Get_Struct(self, xmlNode, node);
569
604
 
570
- rb_doc = rb_funcall(cNokogiriXmlDocument, rb_intern("read_memory"), 4,
571
- xml, Qnil, Qnil, INT2NUM(0));
572
- Data_Get_Struct(rb_doc, xmlDoc, doc);
573
- node = xmlCopyNode(xmlDocGetRootElement(doc), 1); /* 1 => recursive */
574
- node->doc = doc;
605
+ VALUE html;
575
606
 
576
- return Nokogiri_wrap_xml_node(node);
607
+ if(node->doc->type == XML_DOCUMENT_NODE)
608
+ return rb_funcall(self, rb_intern("to_xml"), 0);
609
+
610
+ buf = xmlBufferCreate() ;
611
+ htmlNodeDump(buf, node->doc, node);
612
+ html = rb_str_new2((char*)buf->content);
613
+ xmlBufferFree(buf);
614
+ return html ;
577
615
  }
578
616
 
579
617
  VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
@@ -598,16 +636,28 @@ VALUE Nokogiri_wrap_xml_node(xmlNodePtr node)
598
636
  klass = rb_const_get(mNokogiriXml, rb_intern("Text"));
599
637
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
600
638
  break;
639
+ case XML_ENTITY_REF_NODE:
640
+ klass = cNokogiriXmlEntityReference;
641
+ rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
642
+ break;
601
643
  case XML_COMMENT_NODE:
602
644
  klass = cNokogiriXmlComment;
603
645
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
604
646
  break;
647
+ case XML_DOCUMENT_FRAG_NODE:
648
+ klass = cNokogiriXmlDocumentFragment;
649
+ rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
650
+ break;
651
+ case XML_PI_NODE:
652
+ klass = cNokogiriXmlProcessingInstruction;
653
+ rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
654
+ break;
605
655
  case XML_ELEMENT_NODE:
606
656
  klass = rb_const_get(mNokogiriXml, rb_intern("Element"));
607
657
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
608
658
  break;
609
659
  case XML_ATTRIBUTE_NODE:
610
- klass = rb_const_get(mNokogiriXml, rb_intern("Attr"));
660
+ klass = cNokogiriXmlAttr;
611
661
  rb_node = Data_Wrap_Struct(klass, 0, debug_node_dealloc, node) ;
612
662
  break;
613
663
  case XML_ENTITY_DECL:
@@ -684,43 +734,43 @@ void Nokogiri_xml_node_namespaces(xmlNodePtr node, VALUE attr_hash)
684
734
  VALUE cNokogiriXmlNode ;
685
735
  void init_xml_node()
686
736
  {
687
- /*
688
737
  VALUE nokogiri = rb_define_module("Nokogiri");
689
738
  VALUE xml = rb_define_module_under(nokogiri, "XML");
690
739
  VALUE klass = rb_define_class_under(xml, "Node", rb_cObject);
691
- */
692
740
 
693
- VALUE klass = cNokogiriXmlNode = rb_const_get(mNokogiriXml, rb_intern("Node"));
741
+ cNokogiriXmlNode = klass;
694
742
 
695
743
  rb_define_singleton_method(klass, "new", new, 2);
696
- rb_define_singleton_method(klass, "new_from_str", new_from_str, 1);
697
744
 
698
- rb_define_method(klass, "name", get_name, 0);
699
- rb_define_method(klass, "name=", set_name, 1);
745
+ rb_define_method(klass, "add_namespace", add_namespace, 2);
746
+ rb_define_method(klass, "node_name", get_name, 0);
747
+ rb_define_method(klass, "node_name=", set_name, 1);
700
748
  rb_define_method(klass, "add_child", add_child, 1);
701
749
  rb_define_method(klass, "parent", get_parent, 0);
702
750
  rb_define_method(klass, "child", child, 0);
703
751
  rb_define_method(klass, "next_sibling", next_sibling, 0);
704
752
  rb_define_method(klass, "previous_sibling", previous_sibling, 0);
705
- rb_define_method(klass, "type", type, 0);
753
+ rb_define_method(klass, "node_type", node_type, 0);
706
754
  rb_define_method(klass, "content", get_content, 0);
707
755
  rb_define_method(klass, "path", path, 0);
708
756
  rb_define_method(klass, "key?", key_eh, 1);
709
757
  rb_define_method(klass, "blank?", blank_eh, 0);
710
758
  rb_define_method(klass, "[]=", set, 2);
711
759
  rb_define_method(klass, "attribute_nodes", attribute_nodes, 0);
760
+ rb_define_method(klass, "attribute", attr, 1);
712
761
  rb_define_method(klass, "namespace", namespace, 0);
713
762
  rb_define_method(klass, "namespaces", namespaces, 0);
714
763
  rb_define_method(klass, "add_previous_sibling", add_previous_sibling, 1);
715
764
  rb_define_method(klass, "add_next_sibling", add_next_sibling, 1);
716
765
  rb_define_method(klass, "encode_special_chars", encode_special_chars, 1);
717
- rb_define_method(klass, "to_xml", to_xml, -1);
718
- rb_define_method(klass, "to_html", to_html, 0);
719
766
  rb_define_method(klass, "dup", duplicate_node, -1);
720
767
  rb_define_method(klass, "unlink", unlink_node, 0);
721
768
  rb_define_method(klass, "internal_subset", internal_subset, 0);
722
769
  rb_define_method(klass, "pointer_id", pointer_id, 0);
770
+ rb_define_method(klass, "line", line, 0);
723
771
 
772
+ rb_define_private_method(klass, "dump_html", dump_html, 0);
773
+ rb_define_private_method(klass, "native_write_to", native_write_to, 3);
724
774
  rb_define_private_method(klass, "replace_with_node", replace, 1);
725
775
  rb_define_private_method(klass, "native_content=", set_content, 1);
726
776
  rb_define_private_method(klass, "get", get, 1);