├── docs ├── .gitignore ├── assets │ ├── images │ │ └── .keep │ ├── licenses │ │ ├── font-awesome │ │ │ └── LICENSE │ │ └── bootstrap │ │ │ └── LICENSE │ ├── fonts │ │ ├── font-awesome │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ └── bootstrap │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ ├── stylesheets │ │ ├── font-awesome │ │ │ ├── _fixed-width.scss │ │ │ ├── _larger.scss │ │ │ ├── _list.scss │ │ │ ├── _font-awesome.scss │ │ │ ├── _core.scss │ │ │ ├── _stacked.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _path.scss │ │ │ ├── _animated.scss │ │ │ └── _mixins.scss │ │ ├── bootstrap │ │ │ ├── mixins │ │ │ │ ├── _center-block.scss │ │ │ │ ├── _opacity.scss │ │ │ │ ├── _size.scss │ │ │ │ ├── _text-overflow.scss │ │ │ │ ├── _tab-focus.scss │ │ │ │ ├── _labels.scss │ │ │ │ ├── _resize.scss │ │ │ │ ├── _progress-bar.scss │ │ │ │ ├── _text-emphasis.scss │ │ │ │ ├── _reset-filter.scss │ │ │ │ ├── _nav-divider.scss │ │ │ │ ├── _background-variant.scss │ │ │ │ ├── _alerts.scss │ │ │ │ ├── _nav-vertical-align.scss │ │ │ │ ├── _reset-text.scss │ │ │ │ ├── _border-radius.scss │ │ │ │ ├── _pagination.scss │ │ │ │ ├── _responsive-visibility.scss │ │ │ │ ├── _panels.scss │ │ │ │ ├── _hide-text.scss │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _list-group.scss │ │ │ │ ├── _table-row.scss │ │ │ │ ├── _image.scss │ │ │ │ └── _buttons.scss │ │ │ ├── _wells.scss │ │ │ ├── _breadcrumbs.scss │ │ │ ├── _responsive-embed.scss │ │ │ ├── _close.scss │ │ │ ├── _component-animations.scss │ │ │ ├── _utilities.scss │ │ │ ├── _thumbnails.scss │ │ │ ├── _pager.scss │ │ │ ├── _mixins.scss │ │ │ ├── _media.scss │ │ │ ├── _jumbotron.scss │ │ │ ├── _labels.scss │ │ │ ├── _badges.scss │ │ │ ├── _code.scss │ │ │ ├── _grid.scss │ │ │ ├── _alerts.scss │ │ │ ├── _progress-bars.scss │ │ │ ├── _pagination.scss │ │ │ └── _print.scss │ │ ├── _bootstrap-sprockets.scss │ │ ├── _bootstrap-compass.scss │ │ ├── _bootstrap-mincer.scss │ │ ├── xmlua.scss │ │ └── _bootstrap.scss │ └── javascripts │ │ ├── bootstrap-sprockets.js │ │ └── bootstrap │ │ └── transition.js ├── Gemfile ├── _includes │ ├── site-description.html │ ├── contribute.html │ ├── navbar-content.html │ ├── contribute.en.html │ ├── contribute.ja.html │ ├── navbar-content.ja.html │ └── navbar-content.en.html ├── ja │ ├── reference │ │ ├── error-level-list.md │ │ ├── cdata-section.md │ │ ├── document-fragment.md │ │ ├── xmlua.md │ │ ├── processing-instruction.md │ │ ├── error-domain-list.md │ │ ├── namespace.md │ │ ├── text.md │ │ └── document-type.md │ ├── install │ │ └── index.md │ └── index.md ├── reference │ ├── error-level-list.md │ ├── cdata-section.md │ ├── document-fragment.md │ ├── processing-instruction.md │ ├── xmlua.md │ ├── namespace.md │ ├── error-domain-list.md │ ├── text.md │ └── document-type.md ├── Rakefile ├── _config.yml ├── install │ └── index.md ├── _po │ └── ja │ │ ├── reference │ │ ├── error-level-list.po │ │ ├── cdata-section.po │ │ └── document-fragment.po │ │ └── install │ │ └── index.po ├── index.md └── _layouts │ └── base.html ├── test ├── test.dtd ├── run-test.lua ├── test-xml-stream-sax-parser.lua ├── test-xml.lua ├── test-comment.lua ├── test-cdata-section.lua └── test-attribute.lua ├── sample ├── sample.dtd ├── sample-xml-sax-ignorable_whitespace.xml ├── sample.html ├── sample-xml-sax-warning.xml ├── text-concat.lua ├── document-create-comment.lua ├── document-create-cdata-section.lua ├── node-set-content.lua ├── text-merge.lua ├── document-create-document-type.lua ├── element-content.lua ├── document-create-namespace.lua ├── element-children.lua ├── document-create-document-fragment.lua ├── node-set-path.lua ├── node-set-paths.lua ├── parse-xml-sax-warning.lua ├── element-add-next-sibling.lua ├── element-append-sibling.lua ├── element-path.lua ├── element-unlink.lua ├── element-add-previous-sibling.lua ├── parse-html-errors.lua ├── sample-xml-sax.xml ├── document-create-processing-instruction.lua ├── parse-xml-sax-ignorable-whitespace.lua ├── node-replace-node.lua ├── node-set-unlink.lua ├── parse-xml-file.lua ├── parse-xml.lua ├── parse-html.lua ├── parse-html-file.lua ├── search-node-set.lua ├── to-xml-node-set.lua ├── element-find-namespace.lua ├── element-remove-attribute.lua ├── to-html-node-set.lua ├── element-add-child.lua ├── to-xml.lua ├── element-get-attribute.lua ├── node-set-insert.lua ├── node-set-remove.lua ├── search.lua ├── css-select.lua ├── element-set-attribute.lua ├── element-move.lua ├── node-set-merge.lua ├── to-html.lua ├── element-append-element.lua ├── element-insert-element.lua ├── parse-html-sax.lua ├── parse-html-cqueues-thread.lua ├── document-add-entity.lua ├── xml-build.lua └── html-build.lua ├── Brewfile ├── xmlua ├── libxml2 │ ├── dict.lua │ ├── hash.lua │ ├── html-tree.lua │ ├── xmlstring.lua │ ├── memory.lua │ ├── global.lua │ ├── c14n.lua │ ├── xmlsave.lua │ ├── xml-io.lua │ ├── valid.lua │ ├── encoding.lua │ ├── html-parser.lua │ └── entities.lua ├── entity.lua ├── comment.lua ├── cdata-section.lua ├── entity-declaration.lua ├── element-declaration.lua ├── notation-declaration.lua ├── attribute-declaration.lua ├── namespace-declaration.lua ├── document-fragment.lua ├── processing-instruction.lua ├── entity-reference.lua ├── notation.lua ├── document-type.lua ├── xml.lua ├── namespace.lua ├── attribute.lua ├── node.lua ├── text.lua ├── serializable.lua └── html.lua ├── .github ├── dependabot.yml └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .dir-locals.el ├── xmlua.lua ├── README.md ├── LICENSE ├── dockerfiles └── Dockerfile.almalinux-8 └── Rakefile /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | -------------------------------------------------------------------------------- /docs/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/test.dtd: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sample/sample.dtd: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | brew "libxml2" 2 | brew "luajit" 3 | brew "luarocks" 4 | brew "openssl" 5 | -------------------------------------------------------------------------------- /xmlua/libxml2/dict.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef void *xmlDictPtr; 5 | ]] 6 | -------------------------------------------------------------------------------- /xmlua/libxml2/hash.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef void *xmlHashTablePtr; 5 | ]] 6 | -------------------------------------------------------------------------------- /sample/sample-xml-sax-ignorable_whitespace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/assets/licenses/font-awesome/LICENSE: -------------------------------------------------------------------------------- 1 | /asserts/fonts/font-awesome/: SIL OFL 1.1 2 | /asserts/stylesheets/font-awesome/: MIT License 3 | -------------------------------------------------------------------------------- /docs/assets/fonts/font-awesome/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/font-awesome/FontAwesome.otf -------------------------------------------------------------------------------- /sample/sample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello 4 | 5 | 6 |

World

7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/assets/fonts/font-awesome/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/font-awesome/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/assets/fonts/font-awesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/font-awesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/assets/fonts/font-awesome/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/font-awesome/fontawesome-webfont.woff -------------------------------------------------------------------------------- /xmlua/libxml2/html-tree.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | htmlDocPtr htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID); 5 | ]] 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "jekyll-task-i18n" 4 | gem "rake" 5 | gem "yard" 6 | gem "coderay" 7 | gem "github-pages" 8 | gem "kramdown" 9 | -------------------------------------------------------------------------------- /docs/assets/fonts/font-awesome/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/font-awesome/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/assets/fonts/bootstrap/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/bootstrap/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /xmlua/libxml2/xmlstring.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef unsigned char xmlChar; 5 | 6 | xmlChar *xmlStrdup(const xmlChar *cur); 7 | ]] 8 | -------------------------------------------------------------------------------- /docs/assets/fonts/bootstrap/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/bootstrap/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clear-code/xmlua/HEAD/docs/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /xmlua/libxml2/memory.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef void *(*xmlMallocFunc)(size_t size); 5 | typedef void (*xmlFreeFunc)(void *mem); 6 | ]] 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | *.edit.po 3 | *.edit.po~ 4 | *.pot 5 | *.time_stamp 6 | *.rock 7 | /docs/.sass-cache/ 8 | /docs/_site/ 9 | /docs/_po/*.po 10 | /docs/Gemfile.lock 11 | -------------------------------------------------------------------------------- /docs/_includes/site-description.html: -------------------------------------------------------------------------------- 1 | {% case page.language %} 2 | {% when "ja" %} 3 | {{ site.description.ja }} 4 | {% else %} 5 | {{ site.description.en }} 6 | {% endcase %} 7 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((lua-mode . ((lua-indent-level . 2) 2 | (indent-tabs-mode . nil))) 3 | (css-mode . ((indent-tabs-mode . nil) 4 | (css-indent-offset . 2)))) 5 | -------------------------------------------------------------------------------- /docs/_includes/contribute.html: -------------------------------------------------------------------------------- 1 | {% case page.language %} 2 | {% when "ja" %} 3 | {% include contribute.ja.html %} 4 | {% else %} 5 | {% include contribute.en.html %} 6 | {% endcase %} 7 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /docs/_includes/navbar-content.html: -------------------------------------------------------------------------------- 1 | {% case page.language %} 2 | {% when "ja" %} 3 | {% include navbar-content.ja.html %} 4 | {% else %} 5 | {% include navbar-content.en.html %} 6 | {% endcase %} 7 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_center-block.scss: -------------------------------------------------------------------------------- 1 | // Center-align a block level element 2 | 3 | @mixin center-block() { 4 | display: block; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | -------------------------------------------------------------------------------- /sample/sample-xml-sax-warning.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | ]> 6 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_opacity.scss: -------------------------------------------------------------------------------- 1 | // Opacity 2 | 3 | @mixin opacity($opacity) { 4 | opacity: $opacity; 5 | // IE8 filter 6 | $opacity-ie: ($opacity * 100); 7 | filter: alpha(opacity=$opacity-ie); 8 | } 9 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_size.scss: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | @mixin size($width, $height) { 4 | width: $width; 5 | height: $height; 6 | } 7 | 8 | @mixin square($size) { 9 | @include size($size, $size); 10 | } 11 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/_bootstrap-sprockets.scss: -------------------------------------------------------------------------------- 1 | @function twbs-font-path($path) { 2 | @return font-path($path); 3 | } 4 | 5 | @function twbs-image-path($path) { 6 | @return image-path($path); 7 | } 8 | 9 | $bootstrap-sass-asset-helper: true; 10 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_text-overflow.scss: -------------------------------------------------------------------------------- 1 | // Text overflow 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-overflow() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_tab-focus.scss: -------------------------------------------------------------------------------- 1 | // WebKit-style focus 2 | 3 | @mixin tab-focus() { 4 | // Default 5 | outline: thin dotted; 6 | // WebKit 7 | outline: 5px auto -webkit-focus-ring-color; 8 | outline-offset: -2px; 9 | } 10 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/_bootstrap-compass.scss: -------------------------------------------------------------------------------- 1 | @function twbs-font-path($path) { 2 | @return font-url($path, true); 3 | } 4 | 5 | @function twbs-image-path($path) { 6 | @return image-url($path, true); 7 | } 8 | 9 | $bootstrap-sass-asset-helper: true; 10 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_labels.scss: -------------------------------------------------------------------------------- 1 | // Labels 2 | 3 | @mixin label-variant($color) { 4 | background-color: $color; 5 | 6 | &[href] { 7 | &:hover, 8 | &:focus { 9 | background-color: darken($color, 10%); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | resize: $direction; // Options: horizontal, vertical, both 5 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 6 | } 7 | -------------------------------------------------------------------------------- /xmlua/libxml2/global.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | xmlMallocFunc *__xmlMalloc(void); 5 | xmlMallocFunc xmlMalloc; 6 | xmlFreeFunc *__xmlFree(void); 7 | xmlFreeFunc xmlFree; 8 | 9 | const char * *__xmlParserVersion(void); 10 | const char * xmlParserVersion; 11 | ]] 12 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_progress-bar.scss: -------------------------------------------------------------------------------- 1 | // Progress bars 2 | 3 | @mixin progress-bar-variant($color) { 4 | background-color: $color; 5 | 6 | // Deprecated parent class requirement as of v3.2.0 7 | .progress-striped & { 8 | @include gradient-striped; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docs/_includes/contribute.en.html: -------------------------------------------------------------------------------- 1 |

2 | {% assign source_path = page.path %} 3 | {% assign source_url = source_path | prepend: "https://github.com/clear-code/xmlua/blob/master/docs/" %} 4 | If you find any typo, please feel free to send pull requests! 5 |

6 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | 3 | // [converter] $parent hack 4 | @mixin text-emphasis-variant($parent, $color) { 5 | #{$parent} { 6 | color: $color; 7 | } 8 | a#{$parent}:hover, 9 | a#{$parent}:focus { 10 | color: darken($color, 10%); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_reset-filter.scss: -------------------------------------------------------------------------------- 1 | // Reset filters for IE 2 | // 3 | // When you need to remove a gradient background, do not forget to use this to reset 4 | // the IE filter for IE9 and below. 5 | 6 | @mixin reset-filter() { 7 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 8 | } 9 | -------------------------------------------------------------------------------- /docs/_includes/contribute.ja.html: -------------------------------------------------------------------------------- 1 |

2 | {% assign source_path = page.path | prepend: "_po/" | replace_first: ".md", ".po" %} 3 | {% assign source_url = source_path | prepend: "https://github.com/clear-code/xmlua/blob/master/docs/" %} 4 | 誤字や誤訳、未訳を見つけたらお気軽にプルリクエストを送ってください! 5 |

6 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_nav-divider.scss: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | @mixin nav-divider($color: #e5e5e5) { 6 | height: 1px; 7 | margin: (($line-height-computed / 2) - 1) 0; 8 | overflow: hidden; 9 | background-color: $color; 10 | } 11 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // Contextual backgrounds 2 | 3 | // [converter] $parent hack 4 | @mixin bg-variant($parent, $color) { 5 | #{$parent} { 6 | background-color: $color; 7 | } 8 | a#{$parent}:hover, 9 | a#{$parent}:focus { 10 | background-color: darken($color, 10%); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample/text-concat.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = 6 | xmlua.XML.build({"root", {}, "Text1"}) 7 | local text_nodes = document:search("/root/text()") 8 | text_nodes[1]:concat("Text2") 9 | print(document:to_xml()) 10 | -- 11 | --Text1Text2 12 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_alerts.scss: -------------------------------------------------------------------------------- 1 | // Alerts 2 | 3 | @mixin alert-variant($background, $border, $text-color) { 4 | background-color: $background; 5 | border-color: $border; 6 | color: $text-color; 7 | 8 | hr { 9 | border-top-color: darken($border, 5%); 10 | } 11 | .alert-link { 12 | color: darken($text-color, 10%); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/ja/reference/error-level-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAXParser error level 3 | --- 4 | 5 | # `xmlua.HTMLSAXParser.error.level`と`xmlua.XMLSAXParser.error.level`の値一覧 6 | 7 | `xmlua.HTMLSAXParser.error.level`と`xmlua.XMLSAXParser.error.level`の値は以下の通りです。 8 | 9 | ``` 10 | XML_ERR_NONE = 0 11 | XML_ERR_WARNING = 1 : 警告 12 | XML_ERR_ERROR = 2 : 回復可能なエラー 13 | XML_ERR_FATAL = 3 : 致命的なエラー 14 | ``` 15 | -------------------------------------------------------------------------------- /sample/document-create-comment.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | local comment_node = document:create_comment("This is comment") 7 | root = document:root() 8 | root:add_child(comment_node) 9 | print(document:to_xml()) 10 | -- 11 | -- 12 | -- 13 | -- 14 | -------------------------------------------------------------------------------- /sample/document-create-cdata-section.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | local cdata_section_node = 7 | document:create_cdata_section("This is ") 8 | root = document:root() 9 | root:add_child(cdata_section_node) 10 | print(document:to_xml()) 11 | -- 12 | --]]> 13 | -------------------------------------------------------------------------------- /docs/reference/error-level-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAXParser error level 3 | --- 4 | 5 | # `xmlua.HTMLSAXParser.error.level` and `xmlua.XMLSAXParser.error.level` value list 6 | 7 | `xmlua.HTMLSAXParser.error.level` and `xmlua.XMLSAXParser.error.level` have values as below. 8 | 9 | ``` 10 | XML_ERR_NONE = 0 11 | XML_ERR_WARNING = 1 : A simple warning 12 | XML_ERR_ERROR = 2 : A recoverable error 13 | XML_ERR_FATAL = 3 : A fatal error 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_nav-vertical-align.scss: -------------------------------------------------------------------------------- 1 | // Navbar vertical align 2 | // 3 | // Vertically center elements in the navbar. 4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin. 5 | 6 | @mixin navbar-vertical-align($element-height) { 7 | margin-top: (($navbar-height - $element-height) / 2); 8 | margin-bottom: (($navbar-height - $element-height) / 2); 9 | } 10 | -------------------------------------------------------------------------------- /sample/node-set-content.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]]) 12 | 13 | -- All elements under (, and ) 14 | local node_set = document:search("/root/*") 15 | 16 | -- Gets all contents and concatenates them 17 | print(node_set:content()) 18 | -- text1text2text3 19 | -------------------------------------------------------------------------------- /docs/assets/javascripts/bootstrap-sprockets.js: -------------------------------------------------------------------------------- 1 | //= require ./bootstrap/affix 2 | //= require ./bootstrap/alert 3 | //= require ./bootstrap/button 4 | //= require ./bootstrap/carousel 5 | //= require ./bootstrap/collapse 6 | //= require ./bootstrap/dropdown 7 | //= require ./bootstrap/tab 8 | //= require ./bootstrap/transition 9 | //= require ./bootstrap/scrollspy 10 | //= require ./bootstrap/modal 11 | //= require ./bootstrap/tooltip 12 | //= require ./bootstrap/popover 13 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /docs/Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require "bundler/setup" 4 | require "jekyll/task/i18n" 5 | 6 | Jekyll::Task::I18n.define do |task| 7 | task.locales = ["ja"] 8 | task.files = Rake::FileList["**/*.md"] 9 | task.files -= Rake::FileList["_*/**/*.md"] 10 | task.files -= Rake::FileList["vendor/**/*.md"] 11 | task.locales.each do |locale| 12 | task.files -= Rake::FileList["#{locale}/**/*.md"] 13 | end 14 | end 15 | 16 | task :default => ["jekyll:i18n:translate"] 17 | -------------------------------------------------------------------------------- /sample/text-merge.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | Text: 8 | This is child 9 | 10 | ]]) 11 | local text1 = document:search("/root/text()") 12 | local text2 = document:search("/root/child/text()") 13 | 14 | text1[1]:merge(text2[1]) 15 | print(document:to_xml()) 16 | -- 17 | -- 18 | -- Text: 19 | -- This is child 20 | -- 21 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/document-create-document-type.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | --Specify a location by PublicID 6 | local document = xmlua.XML.build({}) 7 | local document_type = 8 | document:create_document_type("TestDocumentDecl", 9 | "-//Test/Sample/EN", 10 | "//test.dtd") 11 | print(document:to_xml()) 12 | -- 13 | -- 14 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /sample/element-content.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | text1 8 | child1 text 9 | text2 10 | child2 text 11 | text3 12 | 13 | ]] 14 | local document = xmlua.XML.parse(xml) 15 | local root = document:root() 16 | 17 | -- The 's content. Spaces are also the 's content. 18 | print(root:content()) 19 | -- 20 | -- text1 21 | -- child1 text 22 | -- text2 23 | -- child2 text 24 | -- text3 25 | -- 26 | -------------------------------------------------------------------------------- /xmlua/entity.lua: -------------------------------------------------------------------------------- 1 | local Entity = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "entity" 15 | end 16 | 17 | function Entity.new(document, node) 18 | local entity = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(entity, metatable) 23 | return entity 24 | end 25 | 26 | return Entity 27 | -------------------------------------------------------------------------------- /sample/document-create-namespace.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | local namespace = 7 | document:create_namespace("http://www.w3.org/1999/xhtml", 8 | "xhtml") 9 | local root = document:root() 10 | root:set_namespace(namespace) 11 | print(namespace:href(), namespace:prefix(), document:to_xml()) 12 | --"http://www.w3.org/1999/xhtml", 13 | --"xhtml", 14 | -- 15 | -- 16 | 17 | -------------------------------------------------------------------------------- /xmlua/comment.lua: -------------------------------------------------------------------------------- 1 | local Comment = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "comment" 15 | end 16 | 17 | function Comment.new(document, node) 18 | local comment = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(comment, metatable) 23 | return comment 24 | end 25 | 26 | return Comment 27 | -------------------------------------------------------------------------------- /sample/element-children.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | 8 | 9 | 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | local root = document:root() 15 | 16 | -- Gets all child elements of (, and ) 17 | local subs = root:children() 18 | 19 | print(#subs) 20 | -- 3 21 | print(subs[1]:to_xml()) 22 | -- 23 | print(subs[2]:to_xml()) 24 | -- 25 | print(subs[3]:to_xml()) 26 | -- 27 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /sample/document-create-document-fragment.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | 7 | local document_fragment = document:create_document_fragment() 8 | local comment_node = document:create_comment("This is comment") 9 | document_fragment:add_child(comment_node) 10 | 11 | root = document:root() 12 | root:add_child(document_fragment) 13 | print(document:to_xml()) 14 | -- 15 | -- 16 | -- 17 | -- 18 | -- 19 | 20 | -------------------------------------------------------------------------------- /sample/node-set-path.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]]) 12 | 13 | -- All elements under (, and ) 14 | local node_set = document:search("/root/*") 15 | -- Gets xpath of all elements under (, and ) 16 | for _, node in ipairs(node_set) do 17 | print(node:path()) 18 | --/root/sub1 19 | --/root/sub2 20 | --/root/sub3 21 | end 22 | -------------------------------------------------------------------------------- /sample/node-set-paths.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]]) 12 | 13 | -- All elements under (, and ) 14 | local node_set = document:search("/root/*") 15 | -- Returns XPath of all elements under (, and ) 16 | for _, path in ipairs(node_set:paths()) do 17 | print(path) 18 | --/root/sub1 19 | --/root/sub2 20 | --/root/sub3 21 | end 22 | -------------------------------------------------------------------------------- /sample/parse-xml-sax-warning.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local path = arg[1] 6 | local file = assert(io.open(path)) 7 | 8 | local parser = xmlua.XMLSAXParser.new() 9 | 10 | parser.is_pedantic = true 11 | parser.warning = function(message) 12 | print("Warning message: " .. message) 13 | print("Pedantic :", parser.is_pedantic) 14 | end 15 | 16 | while true do 17 | local line = file:read() 18 | if not line then 19 | parser:finish() 20 | break 21 | end 22 | parser:parse(line) 23 | end 24 | file:close() 25 | -------------------------------------------------------------------------------- /sample/element-add-next-sibling.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | 8 | 9 | 10 | ]]) 11 | local root = document:root() 12 | local comment_node = 13 | document:create_comment("This is comment!") 14 | 15 | local child = root:children()[1] 16 | child:add_next_sibling(comment_node) 17 | print(document:to_xml()) 18 | -- 19 | -- 20 | -- 21 | -- 22 | -------------------------------------------------------------------------------- /sample/element-append-sibling.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | 8 | 9 | 10 | ]]) 11 | local root = document:root() 12 | local comment_node = 13 | document:create_comment("This is comment!") 14 | 15 | local child = root:children()[1] 16 | child:append_sibling(comment_node) 17 | print(document:to_xml()) 18 | -- 19 | -- 20 | -- 21 | -- 22 | 23 | -------------------------------------------------------------------------------- /sample/element-path.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | child1 text 8 | child2 text 9 | 10 | ]] 11 | local document = xmlua.XML.parse(xml) 12 | local root = document:root() 13 | -- Gets all child elements of ( and ) 14 | local children = root:children() 15 | 16 | -- Returns XPath of 's all child elements. 17 | for _, child in ipairs(children) do 18 | print(child:path()) 19 | --/root/child1 20 | --/root/child2 21 | end 22 | 23 | -------------------------------------------------------------------------------- /sample/element-unlink.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | 8 | 9 | 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | 15 | -- Find the 16 | local child2s = document:css_select("child2") 17 | local child2 = child2s[1] 18 | 19 | -- Unlink from the document 20 | child2:unlink() 21 | print(document:to_xml()) 22 | -- 23 | -- 24 | -- 25 | -- 26 | -- 27 | -- 28 | -------------------------------------------------------------------------------- /sample/element-add-previous-sibling.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | 8 | 9 | 10 | ]]) 11 | local root = document:root() 12 | local comment_node = 13 | document:create_comment("This is comment!") 14 | 15 | local child = root:children()[1] 16 | child:add_previous_sibling(comment_node) 17 | print(document:to_xml()) 18 | -- 19 | -- 20 | -- 21 | -- 22 | -------------------------------------------------------------------------------- /xmlua/cdata-section.lua: -------------------------------------------------------------------------------- 1 | local CDATASection = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "cdata-section" 15 | end 16 | 17 | function CDATASection.new(document, node) 18 | local cdata_section = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(cdata_section, metatable) 23 | return cdata_section 24 | end 25 | 26 | return CDATASection 27 | -------------------------------------------------------------------------------- /sample/parse-html-errors.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | -- Invalid HTML. "&" is invalid. 6 | local html = [[ 7 | 8 |

&

9 | 10 | ]] 11 | 12 | -- Parses HTML loosely 13 | local document = xmlua.HTML.parse(html) 14 | 15 | -- "&" is parsed as "&" 16 | print(document:search("//body"):to_html()) 17 | --

&

18 | 19 | for i, err in ipairs(document.errors) do 20 | print("Error" .. i .. ":") 21 | print("Line=" .. err.line .. ": " .. err.message) 22 | -- Line=2: htmlParseEntityRef: no name 23 | end 24 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text() { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size. 4 | font-style: normal; 5 | font-weight: normal; 6 | letter-spacing: normal; 7 | line-break: auto; 8 | line-height: $line-height-base; 9 | text-align: left; // Fallback for where `start` is not supported 10 | text-align: start; 11 | text-decoration: none; 12 | text-shadow: none; 13 | text-transform: none; 14 | white-space: normal; 15 | word-break: normal; 16 | word-spacing: normal; 17 | word-wrap: normal; 18 | } 19 | -------------------------------------------------------------------------------- /sample/sample-xml-sax.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ]> 12 | 13 | 14 | Hello world!

]]> 15 | This is Text 16 | &ref; 17 | 18 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // Single side border-radius 2 | 3 | @mixin border-top-radius($radius) { 4 | border-top-right-radius: $radius; 5 | border-top-left-radius: $radius; 6 | } 7 | @mixin border-right-radius($radius) { 8 | border-bottom-right-radius: $radius; 9 | border-top-right-radius: $radius; 10 | } 11 | @mixin border-bottom-radius($radius) { 12 | border-bottom-right-radius: $radius; 13 | border-bottom-left-radius: $radius; 14 | } 15 | @mixin border-left-radius($radius) { 16 | border-bottom-left-radius: $radius; 17 | border-top-left-radius: $radius; 18 | } 19 | -------------------------------------------------------------------------------- /xmlua/entity-declaration.lua: -------------------------------------------------------------------------------- 1 | local EntityDeclaration = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "entity-declaration" 15 | end 16 | 17 | function EntityDeclaration.new(document, node) 18 | local entity_declaration = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(entity_declaration, metatable) 23 | return entity_declaration 24 | end 25 | 26 | return EntityDeclaration 27 | -------------------------------------------------------------------------------- /sample/document-create-processing-instruction.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | local processing_instruction = 7 | document:create_processing_instruction("xml-stylesheet", 8 | "href=\"www.test.com/test-style.xsl\" type=\"text/xsl\"") 9 | local root = document:root() 10 | root:add_child(processing_instruction) 11 | print(document:to_xml()) 12 | -- 13 | -- 14 | -- 15 | -- 16 | 17 | -------------------------------------------------------------------------------- /xmlua/element-declaration.lua: -------------------------------------------------------------------------------- 1 | local ElementDeclaration = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "element-declaration" 15 | end 16 | 17 | function ElementDeclaration.new(document, node) 18 | local element_declaration = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(element_declaration, metatable) 23 | return element_declaration 24 | end 25 | 26 | return ElementDeclaration 27 | -------------------------------------------------------------------------------- /sample/parse-xml-sax-ignorable-whitespace.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local path = arg[1] 6 | local file = assert(io.open(path)) 7 | 8 | local parser = xmlua.XMLSAXParser.new() 9 | 10 | parser.ignorable_whitespace = function(ignorable_whitespaces) 11 | print("Ignorable whitespaces: " .. "\"" .. ignorable_whitespaces .. "\"") 12 | print("Ignorable whitespaces length: " .. #ignorable_whitespaces) 13 | end 14 | 15 | while true do 16 | local line = file:read() 17 | if not line then 18 | parser:finish() 19 | break 20 | end 21 | parser:parse(line) 22 | end 23 | file:close() 24 | -------------------------------------------------------------------------------- /xmlua/notation-declaration.lua: -------------------------------------------------------------------------------- 1 | local NotationDeclaration = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "notation-declaration" 15 | end 16 | 17 | function NotationDeclaration.new(document, node) 18 | local notation_declaration = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(notation_declaration, metatable) 23 | return notation_declaration 24 | end 25 | 26 | return NotationDeclaration 27 | -------------------------------------------------------------------------------- /xmlua/attribute-declaration.lua: -------------------------------------------------------------------------------- 1 | local AttributeDeclaration = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "attribute-declaration" 15 | end 16 | 17 | function AttributeDeclaration.new(document, node) 18 | local attribute_declaration = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(attribute_declaration, metatable) 23 | return attribute_declaration 24 | end 25 | 26 | return AttributeDeclaration 27 | -------------------------------------------------------------------------------- /xmlua/namespace-declaration.lua: -------------------------------------------------------------------------------- 1 | local NamespaceDeclaration = {} 2 | 3 | local Node = require("xmlua.node") 4 | 5 | local methods = {} 6 | local metatable = {} 7 | 8 | function metatable.__index(element, key) 9 | return methods[key] or 10 | Node[key] 11 | end 12 | 13 | function methods:node_name() 14 | return "namespace-declaration" 15 | end 16 | 17 | function NamespaceDeclaration.new(document, node) 18 | local namespace_declaration = { 19 | document = document, 20 | node = node, 21 | } 22 | setmetatable(namespace_declaration, metatable) 23 | return namespace_declaration 24 | end 25 | 26 | return NamespaceDeclaration 27 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | @mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { 4 | > li { 5 | > a, 6 | > span { 7 | padding: $padding-vertical $padding-horizontal; 8 | font-size: $font-size; 9 | line-height: $line-height; 10 | } 11 | &:first-child { 12 | > a, 13 | > span { 14 | @include border-left-radius($border-radius); 15 | } 16 | } 17 | &:last-child { 18 | > a, 19 | > span { 20 | @include border-right-radius($border-radius); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss: -------------------------------------------------------------------------------- 1 | // Responsive utilities 2 | 3 | // 4 | // More easily include all the states for responsive-utilities.less. 5 | // [converter] $parent hack 6 | @mixin responsive-visibility($parent) { 7 | #{$parent} { 8 | display: block !important; 9 | } 10 | table#{$parent} { display: table !important; } 11 | tr#{$parent} { display: table-row !important; } 12 | th#{$parent}, 13 | td#{$parent} { display: table-cell !important; } 14 | } 15 | 16 | // [converter] $parent hack 17 | @mixin responsive-invisibility($parent) { 18 | #{$parent} { 19 | display: none !important; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/node-replace-node.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.build({"root"}) 6 | local comment_node = 7 | document:create_comment("This is comment") 8 | 9 | local replace_node = 10 | document:create_cdata_section("This is ") 11 | 12 | root = document:root() 13 | root:add_child(comment_node) 14 | print(document:to_xml()) 15 | -- 16 | -- 17 | -- 18 | -- 19 | 20 | comment_node:replace(replace_node) 21 | print(document:to_xml()) 22 | -- 23 | -- element as xmlua.Element 28 | 29 | -- Prints the root element name 30 | print(root:name()) -- -> root 31 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; 8 | margin-bottom: $line-height-computed; 9 | list-style: none; 10 | background-color: $breadcrumb-bg; 11 | border-radius: $border-radius-base; 12 | 13 | > li { 14 | display: inline-block; 15 | 16 | + li:before { 17 | content: "#{$breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space 18 | padding: 0 5px; 19 | color: $breadcrumb-color; 20 | } 21 | } 22 | 23 | > .active { 24 | color: $breadcrumb-active-color; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_responsive-embed.scss: -------------------------------------------------------------------------------- 1 | // Embeds responsive 2 | // 3 | // Credit: Nicolas Gallagher and SUIT CSS. 4 | 5 | .embed-responsive { 6 | position: relative; 7 | display: block; 8 | height: 0; 9 | padding: 0; 10 | overflow: hidden; 11 | 12 | .embed-responsive-item, 13 | iframe, 14 | embed, 15 | object, 16 | video { 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | bottom: 0; 21 | height: 100%; 22 | width: 100%; 23 | border: 0; 24 | } 25 | } 26 | 27 | // Modifier class for 16:9 aspect ratio 28 | .embed-responsive-16by9 { 29 | padding-bottom: 56.25%; 30 | } 31 | 32 | // Modifier class for 4:3 aspect ratio 33 | .embed-responsive-4by3 { 34 | padding-bottom: 75%; 35 | } 36 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Clearfix 2 | // 3 | // For modern browsers 4 | // 1. The space content is one way to avoid an Opera bug when the 5 | // contenteditable attribute is included anywhere else in the document. 6 | // Otherwise it causes space to appear at the top and bottom of elements 7 | // that are clearfixed. 8 | // 2. The use of `table` rather than `block` is only necessary if using 9 | // `:before` to contain the top-margins of child elements. 10 | // 11 | // Source: http://nicolasgallagher.com/micro-clearfix-hack/ 12 | 13 | @mixin clearfix() { 14 | &:before, 15 | &:after { 16 | content: " "; // 1 17 | display: table; // 2 18 | } 19 | &:after { 20 | clear: both; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /sample/parse-html.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | -- HTML to be parsed 6 | local html = [[ 7 | 8 | 9 |

Hello

10 | 11 | 12 | ]] 13 | 14 | -- If you want to use text in a file, you need to read file content by yourself. 15 | 16 | -- local html = io.open("example.html"):read("*all") 17 | 18 | -- Parses HTML 19 | local success, document = pcall(xmlua.HTML.parse, html) 20 | if not success then 21 | local message = document 22 | print("Failed to parse HTML: " .. message) 23 | os.exit(1) 24 | end 25 | 26 | -- Gets the root element 27 | local root = document:root() -- --> element as xmlua.Element 28 | 29 | -- Prints root element name 30 | print(root:name()) -- -> html 31 | -------------------------------------------------------------------------------- /sample/parse-html-file.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local path = arg[1] 6 | local file = assert(io.open(path)) 7 | local html = file:read("*all") 8 | file:close() 9 | 10 | -- Parses HTML 11 | local success, document = pcall(xmlua.HTML.parse, html) 12 | if not success then 13 | local message = document 14 | print("Failed to parse HTML: " .. message) 15 | os.exit(1) 16 | end 17 | 18 | print("Encoding: " .. document:encoding()) 19 | 20 | print("Title: " .. document:search("/html/head/title"):text()) 21 | 22 | if #document.errors > 0 then 23 | print() 24 | for i, err in ipairs(document.errors) do 25 | print("Error" .. i .. ":") 26 | print(path .. ":" .. err.line .. ":" .. err.message) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: XMLua 2 | markdown: kramdown 3 | highlighter: rouge 4 | version: 1.2.2 5 | release_date: 2024-12-18 6 | exclude: 7 | - "Rakefile" 8 | - "Gemfile" 9 | - "Gemfile.lock" 10 | - "vendor" 11 | description: 12 | en: Easy to use HTML and XML library for Lua 13 | ja: 使いやすいLua用のHTML・XML処理ライブラリー 14 | 15 | kramdown: 16 | input: GFM 17 | smart_quotes: ["apos", "apos", "quot", "quot"] 18 | 19 | sass: 20 | sass_dir: assets/stylesheets 21 | 22 | defaults: 23 | - scope: 24 | path: "ja" 25 | values: 26 | path_prefix: /ja/ 27 | layout: "base" 28 | language: ja 29 | country: JP 30 | - scope: 31 | path: "" 32 | values: 33 | path_prefix: / 34 | layout: "base" 35 | language: en 36 | country: US 37 | -------------------------------------------------------------------------------- /sample/search-node-set.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | 8 | 9 | 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | 15 | -- Searches all elements 16 | local class_a_subs = document:search("//sub[@class='A']") 17 | 18 | -- Searches all elements under elements 19 | local subsubs_in_class_a = class_a_subs:search("*") 20 | 21 | print(#subsubs_in_class_a) -- -> 2 22 | 23 | -- It's /root/sub[@class="A"]/subsub1 24 | print(subsubs_in_class_a[1]:to_xml()) 25 | -- 26 | 27 | -- It's /root/sub[@class="A"]/subsub3 28 | print(subsubs_in_class_a[2]:to_xml()) 29 | -- 30 | -------------------------------------------------------------------------------- /xmlua.lua: -------------------------------------------------------------------------------- 1 | local xmlua = {} 2 | 3 | xmlua.VERSION = "1.2.3" 4 | 5 | xmlua.libxml2 = require("xmlua.libxml2") 6 | xmlua.XML = require("xmlua.xml") 7 | xmlua.HTML = require("xmlua.html") 8 | xmlua.HTMLSAXParser = require("xmlua.html-sax-parser") 9 | xmlua.XMLSAXParser = require("xmlua.xml-sax-parser") 10 | xmlua.XMLStreamSAXParser = require("xmlua.xml-stream-sax-parser") 11 | 12 | local Document = require("xmlua.document") 13 | Document.lazy_load() 14 | Document.lazy_load = nil 15 | 16 | local Searchable = require("xmlua.searchable") 17 | Searchable.lazy_load() 18 | Searchable.lazy_load = nil 19 | 20 | function xmlua.init() 21 | xmlua.libxml2.xmlInitParser() 22 | end 23 | 24 | function xmlua.cleanup() 25 | collectgarbage() 26 | xmlua.libxml2.xmlCleanupParser() 27 | end 28 | 29 | return xmlua 30 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /sample/to-xml-node-set.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]]) 12 | 13 | -- All elements under (, and ) 14 | local node_set = document:search("/root/*") 15 | 16 | -- Serializes all elements as XML and concatenates serialized XML 17 | print(node_set:to_xml()) 18 | -- text1text2text3 19 | 20 | -- FYI: serialization 21 | print(node_set[1]:to_xml()) 22 | -- text1 23 | 24 | -- FYI: serialization 25 | print(node_set[2]:to_xml()) 26 | -- text2 27 | 28 | -- FYI: serialization 29 | print(node_set[3]:to_xml()) 30 | -- text3 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | ## Name 4 | 5 | XMLua 6 | 7 | ## Description 8 | 9 | XMLua is a Lua library for processing XML and HTML. It's based on 10 | [libxml2](http://xmlsoft.org/). It uses LuaJIT's FFI module. 11 | 12 | XMLua provides user-friendly API instead of low-level libxml2 API. 13 | The user-friendly API is implemented top of low-level libxml2 API. 14 | 15 | ## Dependencies 16 | 17 | * LuaJIT 18 | 19 | * libxml2 20 | 21 | ## Install 22 | 23 | See [online document](https://clear-code.github.io/xmlua/install/). 24 | 25 | ## Usage 26 | 27 | See [online document](https://clear-code.github.io/xmlua/tutorial/). 28 | 29 | ## Authors 30 | 31 | * Horimoto Yasuhiro \ 32 | 33 | * Kouhei Sutou \ 34 | 35 | ## License 36 | 37 | MIT. See LICENSE for details. 38 | -------------------------------------------------------------------------------- /xmlua/notation.lua: -------------------------------------------------------------------------------- 1 | local Notation = {} 2 | 3 | local Node = require("xmlua.node") 4 | local ffi = require("ffi") 5 | 6 | local methods = {} 7 | local metatable = {} 8 | 9 | function metatable.__index(element, key) 10 | return methods[key] or 11 | Node[key] 12 | end 13 | 14 | function methods:node_name() 15 | return "notation" 16 | end 17 | 18 | function methods:name() 19 | return ffi.string(self.node.name) 20 | end 21 | 22 | function methods:public_id() 23 | return ffi.string(self.node.PublicID) 24 | end 25 | 26 | function methods:system_id() 27 | return ffi.string(self.node.SystemID) 28 | end 29 | 30 | function Notation.new(document, node) 31 | local notation = { 32 | document = document, 33 | node = node, 34 | } 35 | setmetatable(notation, metatable) 36 | return notation 37 | end 38 | 39 | return Notation 40 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | @mixin list-group-item-variant($state, $background, $color) { 4 | .list-group-item-#{$state} { 5 | color: $color; 6 | background-color: $background; 7 | 8 | // [converter] extracted a&, button& to a.list-group-item-#{$state}, button.list-group-item-#{$state} 9 | } 10 | 11 | a.list-group-item-#{$state}, 12 | button.list-group-item-#{$state} { 13 | color: $color; 14 | 15 | .list-group-item-heading { 16 | color: inherit; 17 | } 18 | 19 | &:hover, 20 | &:focus { 21 | color: $color; 22 | background-color: darken($background, 5%); 23 | } 24 | &.active, 25 | &.active:hover, 26 | &.active:focus { 27 | color: #fff; 28 | background-color: $color; 29 | border-color: $color; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/_bootstrap-mincer.scss: -------------------------------------------------------------------------------- 1 | // Mincer asset helper functions 2 | // 3 | // This must be imported into a .css.ejs.scss file. 4 | // Then, <% %>-interpolations will be parsed as strings by Sass, and evaluated by EJS after Sass compilation. 5 | 6 | 7 | @function twbs-font-path($path) { 8 | // do something like following 9 | // from "path/to/font.ext#suffix" to "<%- asset_path(path/to/font.ext)) + #suffix %>" 10 | // from "path/to/font.ext?#suffix" to "<%- asset_path(path/to/font.ext)) + ?#suffix %>" 11 | // or from "path/to/font.ext" just "<%- asset_path(path/to/font.ext)) %>" 12 | @return "<%- asset_path('#{$path}'.replace(/[#?].*$/, '')) + '#{$path}'.replace(/(^[^#?]*)([#?]?.*$)/, '$2') %>"; 13 | } 14 | 15 | @function twbs-image-path($file) { 16 | @return "<%- asset_path('#{$file}') %>"; 17 | } 18 | 19 | $bootstrap-sass-asset-helper: true; 20 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_table-row.scss: -------------------------------------------------------------------------------- 1 | // Tables 2 | 3 | @mixin table-row-variant($state, $background) { 4 | // Exact selectors below required to override `.table-striped` and prevent 5 | // inheritance to nested tables. 6 | .table > thead > tr, 7 | .table > tbody > tr, 8 | .table > tfoot > tr { 9 | > td.#{$state}, 10 | > th.#{$state}, 11 | &.#{$state} > td, 12 | &.#{$state} > th { 13 | background-color: $background; 14 | } 15 | } 16 | 17 | // Hover states for `.table-hover` 18 | // Note: this is not available for cells or rows within `thead` or `tfoot`. 19 | .table-hover > tbody > tr { 20 | > td.#{$state}:hover, 21 | > th.#{$state}:hover, 22 | &.#{$state}:hover > td, 23 | &:hover > .#{$state}, 24 | &.#{$state}:hover > th { 25 | background-color: darken($background, 5%); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /xmlua/document-type.lua: -------------------------------------------------------------------------------- 1 | local DocumentType = {} 2 | 3 | local Node = require("xmlua.node") 4 | local ffi = require("ffi") 5 | 6 | local methods = {} 7 | local metatable = {} 8 | 9 | function metatable.__index(element, key) 10 | return methods[key] or 11 | Node[key] 12 | end 13 | 14 | function methods:node_name() 15 | return "document-type" 16 | end 17 | 18 | function methods:name() 19 | return ffi.string(self.node.name) 20 | end 21 | 22 | function methods:external_id() 23 | return ffi.string(self.node.ExternalID) 24 | end 25 | 26 | function methods:system_id() 27 | return ffi.string(self.node.SystemID) 28 | end 29 | 30 | function DocumentType.new(document, node) 31 | local document_type = { 32 | document = document, 33 | node = node, 34 | } 35 | setmetatable(document_type, metatable) 36 | return document_type 37 | end 38 | 39 | return DocumentType 40 | -------------------------------------------------------------------------------- /xmlua/xml.lua: -------------------------------------------------------------------------------- 1 | local XML = {} 2 | 3 | local libxml2 = require("xmlua.libxml2") 4 | local ffi = require("ffi") 5 | 6 | local Document = require("xmlua.document") 7 | 8 | function XML.build(tree) 9 | local raw_document = libxml2.xmlNewDoc("1.0") 10 | return Document.build(raw_document, tree) 11 | end 12 | 13 | function XML.parse(xml, options) 14 | local context = libxml2.xmlNewParserCtxt() 15 | if not context then 16 | error("Failed to create context to parse XML") 17 | end 18 | local document = libxml2.xmlCtxtReadMemory(context, xml, options) 19 | if context.lastError.message ~= ffi.NULL then 20 | if context.lastError.message == ffi.NULL then 21 | error("Failed to parse XML") 22 | else 23 | error("Failed to parse XML: " .. ffi.string(context.lastError.message)) 24 | end 25 | end 26 | return Document.new(document) 27 | end 28 | 29 | return XML 30 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: 5 | - "*" 6 | jobs: 7 | github: 8 | name: GitHub 9 | runs-on: ubuntu-latest 10 | timeout-minutes: 10 11 | steps: 12 | - uses: actions/checkout@v6 13 | - name: Release 14 | run: | 15 | ruby \ 16 | -e 'print("## XMLua "); \ 17 | puts(ARGF.read.split(/^## /)[1].gsub(/ {.+?}/, ""))' \ 18 | docs/news/index.md > release-note.md 19 | title="$(head -n 1 release-note.md | sed -e 's/^## //')" 20 | tail -n +2 release-note.md > release-note-without-version.md 21 | gh release create \ 22 | ${GITHUB_REF_NAME} \ 23 | --discussion-category Announcements \ 24 | --notes-file release-note-without-version.md \ 25 | --title "${title}" 26 | env: 27 | GH_TOKEN: ${{ github.token }} 28 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/xmlua.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "bootstrap"; 5 | 6 | $fa-font-path: "../fonts/font-awesome"; 7 | @import "font-awesome/font-awesome"; 8 | 9 | 10 | .navbar-brand img 11 | { 12 | height: 20px; 13 | vertical-align: super; 14 | } 15 | 16 | ul.other-languages { 17 | margin-left: 0; 18 | margin-right: 0; 19 | padding-left: 0; 20 | padding-right: 0; 21 | } 22 | 23 | ul.other-languages li { 24 | display: inline-block; 25 | } 26 | 27 | ul.other-languages li:after { 28 | content: " | "; 29 | } 30 | 31 | ul.other-languages li:last-child:after { 32 | content: ""; 33 | } 34 | 35 | table { 36 | @extend .table; 37 | @extend .table-striped; 38 | @extend .table-bordered; 39 | 40 | td.note { 41 | @extend .text-center; 42 | } 43 | } 44 | 45 | div.note { 46 | @extend .alert; 47 | @extend .alert-info; 48 | 49 | a { 50 | @extend .alert-link; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sample/element-find-namespace.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | local root = document:root() 15 | --Search by prefix 16 | local namespace = root:find_namespace("xhtml") 17 | print(namespace:prefix(), namespace:href()) 18 | --"xhtml" "http://www.w3.org/1999/xhtml" 19 | 20 | --Search by href 21 | local namespace = root:find_namespace(nil, "http://www.sample.org/sample") 22 | print(namespace:prefix(), namespace:href()) 23 | --"sample" "http://www.sample.org/sample" 24 | 25 | --Search default namespace 26 | namespace = root:find_namespace() 27 | print(namespace:href()) 28 | --"http://www.test.org/xhtml" 29 | -------------------------------------------------------------------------------- /sample/element-remove-attribute.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 10 | ]]) 11 | local root = document:root() 12 | 13 | -- Removes an attribute by settings nil as attribute value 14 | root.a1 = nil 15 | print(root:to_xml()) 16 | -- 17 | 18 | -- Removes an attribute by remove_attribute 19 | root:remove_attribute("a2") 20 | print(root:to_xml()) 21 | -- 22 | 23 | -- Document with namespace 24 | local document = xmlua.XML.parse([[ 25 | 28 | ]]) 29 | local root = document:root() 30 | 31 | -- Removes namespace declaration. It unsets the namespace of 32 | -- existing elements and attributes. 33 | root:remove_attribute("xmlns:example") 34 | print(root:to_xml()) 35 | -- 36 | -------------------------------------------------------------------------------- /sample/to-html-node-set.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.HTML.parse([[ 6 | 7 | 8 | Hello 9 | 10 | World 11 | 12 | ]]) 13 | 14 | -- All elements under ( and ) 15 | local node_set = document:search("/html/*") 16 | 17 | -- Serializes all elements as HTML and concatenates serialized HTML 18 | print(node_set:to_html()) 19 | -- 20 | -- 21 | -- Hello 22 | -- World 23 | 24 | -- FYI: serialization 25 | print(node_set[1]:to_html()) 26 | -- 27 | -- 28 | -- Hello 29 | -- 30 | 31 | -- FYI: serialization 32 | print(node_set[2]:to_html()) 33 | -- World 34 | -------------------------------------------------------------------------------- /test/run-test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | package.path = "../luacs/?.lua;" .. package.path 4 | 5 | require("test.test-libxml2") 6 | require("test.test-xml") 7 | require("test.test-html") 8 | require("test.test-html-sax-parser") 9 | require("test.test-xml-sax-parser") 10 | require("test.test-xml-stream-sax-parser") 11 | require("test.test-serialize") 12 | require("test.test-search") 13 | require("test.test-css-select") 14 | require("test.test-xml-build") 15 | require("test.test-html-build") 16 | require("test.test-document") 17 | require("test.test-document-c14n") 18 | require("test.test-element") 19 | require("test.test-node-set") 20 | require("test.test-text") 21 | require("test.test-comment") 22 | require("test.test-processing-instruction") 23 | require("test.test-attribute") 24 | require("test.test-cdata-section") 25 | require("test.test-node") 26 | 27 | luaunit = require("luaunit") 28 | os.exit(luaunit.LuaUnit.run()) 29 | -------------------------------------------------------------------------------- /xmlua/namespace.lua: -------------------------------------------------------------------------------- 1 | local Namespace = {} 2 | 3 | local Node = require("xmlua.node") 4 | local ffi = require("ffi") 5 | 6 | local methods = {} 7 | local metatable = {} 8 | 9 | function metatable.__index(element, key) 10 | return methods[key] or 11 | Node[key] 12 | end 13 | 14 | function methods:node_name() 15 | return "namespace" 16 | end 17 | 18 | function methods:prefix() 19 | if self.node.prefix == ffi.NULL then 20 | return nil 21 | else 22 | return ffi.string(self.node.prefix) 23 | end 24 | end 25 | 26 | function methods:href() 27 | if self.node.href == ffi.NULL then 28 | return nil 29 | else 30 | return ffi.string(self.node.href) 31 | end 32 | end 33 | 34 | function Namespace.new(document, node) 35 | local namespace = { 36 | document = document, 37 | node = node, 38 | } 39 | setmetatable(namespace, metatable) 40 | return namespace 41 | end 42 | 43 | return Namespace 44 | -------------------------------------------------------------------------------- /docs/ja/reference/cdata-section.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.CDATASection 3 | --- 4 | 5 | # `xmlua.CDATASection` クラス 6 | 7 | ## 概要 8 | 9 | cdata sectionノード用のクラスです。通常、[`xmlua.Document:create_cdata_section`][create-cdata-section]を使用して取得できます。 10 | 11 | 例: 12 | 13 | ```lua 14 | local xmlua = require("xmlua") 15 | 16 | local document = xmlua.XML.build({"root"}) 17 | local cdata_section_node = -- -> xmlua.CDATASection 18 | document:create_cdata_section("This is ") 19 | ``` 20 | 21 | このクラスのオブジェクトは以下のモジュールのメソッドを使えます。 22 | 23 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 24 | 25 | つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。 26 | 27 | ## インスタンスメソッド 28 | 29 | このクラス特有のメソッドはありません。 30 | 31 | ## 参照 32 | 33 | * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。 34 | 35 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 36 | 37 | 38 | [create-cdata-section]:document.html#cdata-section.html 39 | 40 | [document]:document.html 41 | 42 | [node]:node.html 43 | -------------------------------------------------------------------------------- /sample/element-add-child.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | 8 | 9 | 10 | ]]) 11 | local attribute_node = document:search("/root/@id") 12 | 13 | local root = document:root() 14 | local child = root:children()[1] 15 | --Add attribute node 16 | child:add_child(attribute_node[1]) 17 | print(document:to_xml()) 18 | -- 19 | -- 20 | -- 21 | -- 22 | 23 | local document_fragment = document:create_document_fragment() 24 | local comment_node = document:create_comment("This is comment in document fragment") 25 | document_fragment:add_child(comment_node) 26 | root:add_child(document_fragment) 27 | print(document:to_xml()) 28 | 29 | -- 30 | -- 31 | -- 32 | -- 33 | -------------------------------------------------------------------------------- /xmlua/attribute.lua: -------------------------------------------------------------------------------- 1 | local Attribute = {} 2 | 3 | local Node = require("xmlua.node") 4 | local Element = require("xmlua.element") 5 | local ffi = require("ffi") 6 | 7 | local methods = {} 8 | local metatable = {} 9 | 10 | function metatable.__index(element, key) 11 | return methods[key] or 12 | Node[key] 13 | end 14 | 15 | function methods:node_name() 16 | return "attribute" 17 | end 18 | 19 | function methods:name() 20 | return ffi.string(self.node.name) 21 | end 22 | 23 | function methods:content() 24 | return ffi.string(self.node.children.content) 25 | end 26 | 27 | function methods:value() 28 | return self:content() 29 | end 30 | 31 | function methods:get_owner_element() 32 | return Element.new(self.document, 33 | self.node.parent) 34 | end 35 | 36 | function Attribute.new(document, node) 37 | local attr = { 38 | document = document, 39 | node = node, 40 | } 41 | setmetatable(attr, metatable) 42 | return attr 43 | end 44 | 45 | return Attribute 46 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_close.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: ($font-size-base * 1.5); 9 | font-weight: $close-font-weight; 10 | line-height: 1; 11 | color: $close-color; 12 | text-shadow: $close-text-shadow; 13 | @include opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: $close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | @include opacity(.5); 21 | } 22 | 23 | // [converter] extracted button& to button.close 24 | } 25 | 26 | // Additional properties for button version 27 | // iOS requires the button element instead of an anchor tag. 28 | // If you want the anchor version, it requires `href="#"`. 29 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 30 | button.close { 31 | padding: 0; 32 | cursor: pointer; 33 | background: transparent; 34 | border: 0; 35 | -webkit-appearance: none; 36 | } 37 | -------------------------------------------------------------------------------- /sample/to-xml.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]]) 12 | 13 | -- Serializes as XML 14 | print(document:to_xml()) 15 | -- 16 | -- 17 | -- text1 18 | -- text2 19 | -- text3 20 | -- 21 | 22 | -- Serializes as EUC-JP encoded XML 23 | print(document:to_xml({encoding = "EUC-JP"})) 24 | -- 25 | -- 26 | -- text1 27 | -- text2 28 | -- text3 29 | -- 30 | 31 | -- Serializes element as XML 32 | print(document:search("/root/sub1")[1]:to_xml()) 33 | -- text1 34 | 35 | -- Serializes elements under (, and ) as XML 36 | print(document:search("/root/*"):to_xml()) 37 | -- text1text2text3 38 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_component-animations.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity: 0; 12 | @include transition(opacity .15s linear); 13 | &.in { 14 | opacity: 1; 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | 21 | &.in { display: block; } 22 | // [converter] extracted tr&.in to tr.collapse.in 23 | // [converter] extracted tbody&.in to tbody.collapse.in 24 | } 25 | 26 | tr.collapse.in { display: table-row; } 27 | 28 | tbody.collapse.in { display: table-row-group; } 29 | 30 | .collapsing { 31 | position: relative; 32 | height: 0; 33 | overflow: hidden; 34 | @include transition-property(height, visibility); 35 | @include transition-duration(.35s); 36 | @include transition-timing-function(ease); 37 | } 38 | -------------------------------------------------------------------------------- /xmlua/node.lua: -------------------------------------------------------------------------------- 1 | local Node = {} 2 | 3 | local libxml2 = require("xmlua.libxml2") 4 | local ffi = require("ffi") 5 | 6 | function Node:replace(replace_node) 7 | if not self.node and not replace_node.node then 8 | error("Already freed receiver node and replace node") 9 | elseif not self.node then 10 | error("Already freed receiver node") 11 | elseif not replace_node.node then 12 | error("Already freed replace node") 13 | end 14 | 15 | local was_freed = 16 | libxml2.xmlReplaceNode(self.node, replace_node.node) 17 | if was_freed then 18 | self.node = nil 19 | end 20 | end 21 | 22 | function Node:set_content(content) 23 | libxml2.xmlNodeSetContent(self.node, content) 24 | end 25 | 26 | function Node:content() 27 | return libxml2.xmlNodeGetContent(self.node) 28 | end 29 | 30 | function Node:text() 31 | return "" 32 | end 33 | 34 | function Node:path() 35 | return libxml2.xmlGetNodePath(self.node) 36 | end 37 | 38 | function Node:unlink() 39 | return libxml2.xmlUnlinkNode(self.node) 40 | end 41 | 42 | return Node 43 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_utilities.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Floats 7 | // ------------------------- 8 | 9 | .clearfix { 10 | @include clearfix; 11 | } 12 | .center-block { 13 | @include center-block; 14 | } 15 | .pull-right { 16 | float: right !important; 17 | } 18 | .pull-left { 19 | float: left !important; 20 | } 21 | 22 | 23 | // Toggling content 24 | // ------------------------- 25 | 26 | // Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 27 | .hide { 28 | display: none !important; 29 | } 30 | .show { 31 | display: block !important; 32 | } 33 | .invisible { 34 | visibility: hidden; 35 | } 36 | .text-hide { 37 | @include text-hide; 38 | } 39 | 40 | 41 | // Hide from screenreaders and browsers 42 | // 43 | // Credit: HTML5 Boilerplate 44 | 45 | .hidden { 46 | display: none !important; 47 | } 48 | 49 | 50 | // For Affix plugin 51 | // ------------------------- 52 | 53 | .affix { 54 | position: fixed; 55 | } 56 | -------------------------------------------------------------------------------- /xmlua/libxml2/c14n.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | /* 5 | * xmlC14NMode: 6 | * 7 | * Predefined values for C14N modes 8 | * 9 | */ 10 | typedef enum { 11 | XML_C14N_1_0 = 0, /* Original C14N 1.0 spec */ 12 | XML_C14N_EXCLUSIVE_1_0 = 1, /* Exclusive C14N 1.0 spec */ 13 | XML_C14N_1_1 = 2 /* C14N 1.1 spec */ 14 | } xmlC14NMode; 15 | 16 | int 17 | xmlC14NDocSaveTo (xmlDocPtr doc, 18 | xmlNodeSetPtr nodes, 19 | int mode, /* a xmlC14NMode */ 20 | xmlChar **inclusive_ns_prefixes, 21 | int with_comments, 22 | xmlOutputBufferPtr buf); 23 | 24 | typedef int (*xmlC14NIsVisibleCallback) (void* user_data, 25 | xmlNodePtr node, 26 | xmlNodePtr parent); 27 | 28 | int 29 | xmlC14NExecute (xmlDocPtr doc, 30 | xmlC14NIsVisibleCallback is_visible_callback, 31 | void* user_data, 32 | int mode, /* a xmlC14NMode */ 33 | xmlChar **inclusive_ns_prefixes, 34 | int with_comments, 35 | xmlOutputBufferPtr buf); 36 | 37 | ]] 38 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/font-awesome/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 16 | -webkit-transform: rotate($degrees); 17 | -ms-transform: rotate($degrees); 18 | transform: rotate($degrees); 19 | } 20 | 21 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 22 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 23 | -webkit-transform: scale($horiz, $vert); 24 | -ms-transform: scale($horiz, $vert); 25 | transform: scale($horiz, $vert); 26 | } 27 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_thumbnails.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | display: block; 9 | padding: $thumbnail-padding; 10 | margin-bottom: $line-height-computed; 11 | line-height: $line-height-base; 12 | background-color: $thumbnail-bg; 13 | border: 1px solid $thumbnail-border; 14 | border-radius: $thumbnail-border-radius; 15 | @include transition(border .2s ease-in-out); 16 | 17 | > img, 18 | a > img { 19 | @include img-responsive; 20 | margin-left: auto; 21 | margin-right: auto; 22 | } 23 | 24 | // [converter] extracted a&:hover, a&:focus, a&.active to a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active 25 | 26 | // Image captions 27 | .caption { 28 | padding: $thumbnail-caption-padding; 29 | color: $thumbnail-caption-color; 30 | } 31 | } 32 | 33 | // Add a hover state for linked versions only 34 | a.thumbnail:hover, 35 | a.thumbnail:focus, 36 | a.thumbnail.active { 37 | border-color: $link-color; 38 | } 39 | -------------------------------------------------------------------------------- /sample/element-get-attribute.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse("") 6 | local root = document:root() 7 | 8 | -- Uses dot syntax to get attribute value 9 | print(root.class) 10 | -- -> A 11 | 12 | -- Uses [] syntax to get attribute value 13 | print(root["class"]) 14 | -- -> A 15 | 16 | -- Uses get_attribute method to get attribute value 17 | print(root:get_attribute("class")) 18 | -- -> A 19 | 20 | local xml = [[ 21 | 25 | ]] 26 | 27 | local document = xmlua.XML.parse(xml) 28 | local root = document:root() 29 | 30 | -- With namespace prefix 31 | print(root["example:attribute"]) 32 | -- -> value-example 33 | 34 | -- Without namespace prefix 35 | print(root["attribute"]) 36 | -- -> value 37 | 38 | -- With nonexistent namespace prefix 39 | print(root["nonexistent-namespace:attribute"]) 40 | -- -> value-nonexistent-namespace 41 | -------------------------------------------------------------------------------- /docs/ja/install/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: インストール 3 | --- 4 | 5 | # インストール 6 | 7 | このドキュメントでは次のプラットフォーム上でXMLuaをインストールする方法を説明します。 8 | 9 | * [Debian GNU/Linux](#debian) 10 | 11 | * [Ubuntu](#ubuntu) 12 | 13 | * [CentOS](#centos) 14 | 15 | * [macOS](#macos) 16 | 17 | XMLuaをインストールする前に[LuaJIT][luajit]と[LuaRocks][luarocks]をインストールしておいてください。 18 | 19 | ## Debian GNU/Linux {#debian} 20 | 21 | ```console 22 | % sudo apt install -y -V libxml2 23 | % sudo luarocks install xmlua 24 | ``` 25 | 26 | ## Ubuntu {#ubuntu} 27 | 28 | ```console 29 | % sudo apt install -y -V libxml2 30 | % sudo luarocks install xmlua 31 | ``` 32 | 33 | ## CentOS {#centos} 34 | 35 | ```console 36 | % sudo yum install -y libxml2 37 | % sudo luarocks install xmlua 38 | ``` 39 | 40 | CentOS 6 x86_64の場合: 41 | 42 | ```console 43 | % sudo yum install -y libxml2 44 | % sudo luarocks install xmlua LIBXML2_LIBDIR=/usr/lib64 45 | ``` 46 | 47 | ## macOS {#macos} 48 | 49 | ```console 50 | % brew install libxml2 51 | % sudo luarocks install xmlua 52 | ``` 53 | 54 | 55 | [luajit]:http://luajit.org/ 56 | 57 | [luarocks]:https://luarocks.org/ 58 | -------------------------------------------------------------------------------- /docs/reference/cdata-section.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.CDATASection 3 | --- 4 | 5 | # `xmlua.CDATASection` class 6 | 7 | ## Summary 8 | 9 | It's a class for cdata section node. Normaly, you can get cdata section object by [`xmlua.Document:create_cdata_section`][create-cdata-section]. 10 | 11 | Example: 12 | 13 | ```lua 14 | local xmlua = require("xmlua") 15 | 16 | local document = xmlua.XML.build({"root"}) 17 | local cdata_section_node = -- -> xmlua.CDATASection 18 | document:create_cdata_section("This is ") 19 | ``` 20 | 21 | It has methods of the following modules: 22 | 23 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 24 | 25 | It means that you can use methods in the modules. 26 | 27 | ## Instance methods 28 | 29 | There are no methods specific to this class. 30 | 31 | ## See also 32 | 33 | * [`xmlua.Document`][document]: The class for HTML document and XML document. 34 | 35 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 36 | 37 | 38 | [create-cdata-section]:document.html#cdata-section.html 39 | 40 | [document]:document.html 41 | 42 | [node]:node.html 43 | -------------------------------------------------------------------------------- /sample/node-set-insert.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 |
8 | This is test 9 |
10 | 11 | sub1 12 | sub2 13 | sub3 14 | 15 |
16 | ]]) 17 | 18 | -- Insert a node 19 | 20 | local node_set = document:search("//title") 21 | -- This is test 22 | 23 | local sub1 = document:search("//xml/contents/sub1")[1] 24 | -- sub1 25 | 26 | node_set:insert(sub1) 27 | 28 | print(node_set:to_xml()) 29 | -- This is testsub1 30 | 31 | -- Insert a node with position 32 | 33 | local node_set = document:search("//xml/contents/*") 34 | -- sub1 35 | -- sub2 36 | -- sub3 37 | 38 | local title = document:search("//title")[1] 39 | -- This is test 40 | node_set:insert(1, title) 41 | 42 | print(node_set:to_xml()) 43 | -- This is test 44 | -- sub1 45 | -- sub2 46 | -- sub3 47 | -------------------------------------------------------------------------------- /sample/node-set-remove.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 |
8 | This is test 9 |
10 | 11 | sub1 12 | sub2 13 | sub3 14 | 15 |
16 | ]]) 17 | 18 | -- Remove a node 19 | 20 | local subs = document:search("//xml/contents/*") 21 | -- sub1 22 | -- sub2 23 | -- sub3 24 | 25 | local sub1 = subs:remove(subs[1]) 26 | -- "sub1" is removed 27 | 28 | print(sub1:to_xml()) 29 | -- sub1 30 | 31 | print(subs:to_xml()) 32 | -- sub2 33 | -- sub3 34 | 35 | -- Remove a node with position 36 | 37 | local subs = document:search("//xml/contents/*") 38 | -- sub1 39 | -- sub2 40 | -- sub3 41 | 42 | local sub2 = subs:remove(2) 43 | -- "sub2" is removed 44 | 45 | print(sub2:to_xml()) 46 | -- sub2 47 | 48 | print(subs:to_xml()) 49 | -- sub1 50 | -- sub3 51 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_pager.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | padding-left: 0; 8 | margin: $line-height-computed 0; 9 | list-style: none; 10 | text-align: center; 11 | @include clearfix; 12 | li { 13 | display: inline; 14 | > a, 15 | > span { 16 | display: inline-block; 17 | padding: 5px 14px; 18 | background-color: $pager-bg; 19 | border: 1px solid $pager-border; 20 | border-radius: $pager-border-radius; 21 | } 22 | 23 | > a:hover, 24 | > a:focus { 25 | text-decoration: none; 26 | background-color: $pager-hover-bg; 27 | } 28 | } 29 | 30 | .next { 31 | > a, 32 | > span { 33 | float: right; 34 | } 35 | } 36 | 37 | .previous { 38 | > a, 39 | > span { 40 | float: left; 41 | } 42 | } 43 | 44 | .disabled { 45 | > a, 46 | > a:hover, 47 | > a:focus, 48 | > span { 49 | color: $pager-disabled-color; 50 | background-color: $pager-bg; 51 | cursor: $cursor-disabled; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /docs/install/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Install 3 | --- 4 | 5 | # Install 6 | 7 | This document how to install XMLua on the following platforms: 8 | 9 | * [Debian GNU/Linux](#debian) 10 | 11 | * [Ubuntu](#ubuntu) 12 | 13 | * [CentOS](#centos) 14 | 15 | * [macOS](#macos) 16 | 17 | You must install [LuaJIT][luajit] and [LuaRocks][luarocks] before installing XMLua. 18 | 19 | ## Debian GNU/Linux {#debian} 20 | 21 | ```console 22 | % sudo apt install -y -V libxml2 23 | % sudo luarocks install xmlua 24 | ``` 25 | 26 | ## Ubuntu {#ubuntu} 27 | 28 | ```console 29 | % sudo apt install -y -V libxml2 30 | % sudo luarocks install xmlua 31 | ``` 32 | 33 | ## CentOS {#centos} 34 | 35 | ```console 36 | % sudo yum install -y libxml2 37 | % sudo luarocks install xmlua 38 | ``` 39 | 40 | For CentOS 6 x86_64: 41 | 42 | ```console 43 | % sudo yum install -y libxml2 44 | % sudo luarocks install xmlua LIBXML2_LIBDIR=/usr/lib64 45 | ``` 46 | 47 | ## macOS {#macos} 48 | 49 | ```console 50 | % brew install libxml2 51 | % sudo luarocks install xmlua 52 | ``` 53 | 54 | 55 | [luajit]:http://luajit.org/ 56 | 57 | [luarocks]:https://luarocks.org/ 58 | -------------------------------------------------------------------------------- /docs/ja/reference/document-fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.DocumentFragment 3 | --- 4 | 5 | # `xmlua.DocumentFragment` クラス 6 | 7 | ## 概要 8 | 9 | ドキュメントフラグメントノード用のクラスです。 10 | 11 | 通常、[`xmlua.Document:create_document_fragment`][create-document-fragment]を使用して取得します。 12 | 13 | 例: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_fragment_node = -- -> xmlua.DocumentFragment 20 | document:create_document_fragment() 21 | ``` 22 | 23 | このクラスのオブジェクトは以下のモジュールのメソッドを使えます。 24 | 25 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 26 | 27 | * [`xmlua.Element`][element]: 要素ノード用のクラスです。 28 | 29 | つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。 30 | 31 | ## インスタンスメソッド 32 | 33 | このクラス特有のメソッドはありません。 34 | 35 | ## 参照 36 | 37 | * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。 38 | 39 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 40 | 41 | * [`xmlua.Element`][element]: 要素ノード用のクラスです。 42 | 43 | 44 | [create-document-fragment]:document.html#document-fragment.html 45 | 46 | [document]:document.html 47 | 48 | [node]:node.html 49 | 50 | [element]:element.html 51 | -------------------------------------------------------------------------------- /sample/search.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | 15 | -- Searches the element 16 | local root_node_set = document:search("/root") 17 | 18 | -- You can use "#" for getting the number of matched nodes 19 | print(#root_node_set) -- -> 1 20 | 21 | -- You can access the N-th node by "[]". 22 | -- It's 1-origin like normal table. 23 | local root = root_node_set[1] -- xmlua.Element 24 | print(root:to_xml()) 25 | -- 26 | -- text1 27 | -- text2 28 | -- text3 29 | -- 30 | 31 | -- Searches all sub elements under the element 32 | local all_subs = root:search("*") 33 | 34 | -- You can use "#" for getting the number of matched nodes 35 | print(#all_subs) -- -> 3 36 | 37 | -- You can access the N-th node by "[]". 38 | print(all_subs[1]:to_xml()) -- -> text1 39 | print(all_subs[2]:to_xml()) -- -> text2 40 | print(all_subs[3]:to_xml()) -- -> text3 41 | -------------------------------------------------------------------------------- /sample/css-select.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | text1 8 | text2 9 | text3 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | 15 | -- Searches the element 16 | local root_node_set = document:css_select("root") 17 | 18 | -- You can use "#" for getting the number of matched nodes 19 | print(#root_node_set) -- -> 1 20 | 21 | -- You can access the N-th node by "[]". 22 | -- It's 1-origin like normal table. 23 | local root = root_node_set[1] -- xmlua.Element 24 | print(root:to_xml()) 25 | -- 26 | -- text1 27 | -- text2 28 | -- text3 29 | -- 30 | 31 | -- Searches all sub elements under the element 32 | local all_subs = root:css_select("*") 33 | 34 | -- You can use "#" for getting the number of matched nodes 35 | print(#all_subs) -- -> 3 36 | 37 | -- You can access the N-th node by "[]". 38 | print(all_subs[1]:to_xml()) -- -> text1 39 | print(all_subs[2]:to_xml()) -- -> text2 40 | print(all_subs[3]:to_xml()) -- -> text3 41 | -------------------------------------------------------------------------------- /docs/_po/ja/reference/error-level-list.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: PACKAGE VERSION\n" 4 | "Language: ja\n" 5 | "MIME-Version: 1.0\n" 6 | "Content-Type: text/plain; charset=UTF-8\n" 7 | "Content-Transfer-Encoding: 8bit\n" 8 | "Plural-Forms: nplurals=1; plural=0;\n" 9 | 10 | msgid "" 11 | "---\n" 12 | "title: SAXParser error level\n" 13 | "---" 14 | msgstr "" 15 | 16 | msgid "" 17 | "# `xmlua.HTMLSAXParser.error.level` and `xmlua.XMLSAXParser.error.level` valu" 18 | "e list" 19 | msgstr "# `xmlua.HTMLSAXParser.error.level`と`xmlua.XMLSAXParser.error.level`の値一覧" 20 | 21 | msgid "" 22 | "`xmlua.HTMLSAXParser.error.level` and `xmlua.XMLSAXParser.error.level` have va" 23 | "lues as below." 24 | msgstr "`xmlua.HTMLSAXParser.error.level`と`xmlua.XMLSAXParser.error.level`の値は以下の通りです。" 25 | 26 | msgid "" 27 | "```\n" 28 | "XML_ERR_NONE = 0\n" 29 | "XML_ERR_WARNING = 1 : A simple warning\n" 30 | "XML_ERR_ERROR = 2 : A recoverable error\n" 31 | "XML_ERR_FATAL = 3 : A fatal error\n" 32 | "```" 33 | msgstr "" 34 | "```\n" 35 | "XML_ERR_NONE = 0\n" 36 | "XML_ERR_WARNING = 1 : 警告\n" 37 | "XML_ERR_ERROR = 2 : 回復可能なエラー\n" 38 | "XML_ERR_FATAL = 3 : 致命的なエラー\n" 39 | "```" 40 | -------------------------------------------------------------------------------- /docs/assets/licenses/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Twitter, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /xmlua/libxml2/xmlsave.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef enum { 5 | XML_SAVE_FORMAT = 1<<0, /* format save output */ 6 | XML_SAVE_NO_DECL = 1<<1, /* drop the xml declaration */ 7 | XML_SAVE_NO_EMPTY = 1<<2, /* no empty tags */ 8 | XML_SAVE_NO_XHTML = 1<<3, /* disable XHTML1 specific rules */ 9 | XML_SAVE_XHTML = 1<<4, /* force XHTML1 specific rules */ 10 | XML_SAVE_AS_XML = 1<<5, /* force XML serialization on HTML doc */ 11 | XML_SAVE_AS_HTML = 1<<6, /* force HTML serialization on XML doc */ 12 | XML_SAVE_WSNONSIG = 1<<7 /* format with non-significant whitespace */ 13 | } xmlSaveOption; 14 | 15 | typedef struct _xmlSaveCtxt xmlSaveCtxt; 16 | typedef xmlSaveCtxt *xmlSaveCtxtPtr; 17 | 18 | xmlSaveCtxtPtr xmlSaveToBuffer(xmlBuffer *buffer, 19 | const char *encoding, 20 | int options); 21 | long xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc); 22 | long xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node); 23 | int xmlSaveClose(xmlSaveCtxtPtr ctxt); 24 | int xmlSaveSetEscape(xmlSaveCtxtPtr ctxt, 25 | xmlCharEncodingOutputFunc escape); 26 | ]] 27 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------------------------------- 3 | 4 | // Utilities 5 | @import "mixins/hide-text"; 6 | @import "mixins/opacity"; 7 | @import "mixins/image"; 8 | @import "mixins/labels"; 9 | @import "mixins/reset-filter"; 10 | @import "mixins/resize"; 11 | @import "mixins/responsive-visibility"; 12 | @import "mixins/size"; 13 | @import "mixins/tab-focus"; 14 | @import "mixins/reset-text"; 15 | @import "mixins/text-emphasis"; 16 | @import "mixins/text-overflow"; 17 | @import "mixins/vendor-prefixes"; 18 | 19 | // Components 20 | @import "mixins/alerts"; 21 | @import "mixins/buttons"; 22 | @import "mixins/panels"; 23 | @import "mixins/pagination"; 24 | @import "mixins/list-group"; 25 | @import "mixins/nav-divider"; 26 | @import "mixins/forms"; 27 | @import "mixins/progress-bar"; 28 | @import "mixins/table-row"; 29 | 30 | // Skins 31 | @import "mixins/background-variant"; 32 | @import "mixins/border-radius"; 33 | @import "mixins/gradients"; 34 | 35 | // Layout 36 | @import "mixins/clearfix"; 37 | @import "mixins/center-block"; 38 | @import "mixins/nav-vertical-align"; 39 | @import "mixins/grid-framework"; 40 | @import "mixins/grid"; 41 | -------------------------------------------------------------------------------- /test/test-xml-stream-sax-parser.lua: -------------------------------------------------------------------------------- 1 | local luaunit = require("luaunit") 2 | local xmlua = require("xmlua") 3 | 4 | local ffi = require("ffi") 5 | 6 | TestXMLStreamSAXParser = {} 7 | 8 | function TestXMLStreamSAXParser.test_multiple_documents() 9 | local xml = [[ 10 | 11 | 12 | 13 | ]] 14 | local listener = { 15 | elements = {}, 16 | errors = {}, 17 | } 18 | function listener:start_element(local_name, ...) 19 | table.insert(self.elements, local_name) 20 | end 21 | function listener:error(error) 22 | table.insert(self.errors, error.message) 23 | end 24 | local parser = xmlua.XMLStreamSAXParser.new(listener) 25 | local parse_succeeded = parser:parse(xml) 26 | local finish_succeeded = parser:finish() 27 | luaunit.assertEquals({ 28 | parse_succeeded, 29 | finish_succeeded, 30 | listener.elements, 31 | listener.errors, 32 | }, 33 | { 34 | true, 35 | true, 36 | {"root", "root", "root"}, 37 | {}, 38 | }) 39 | end 40 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_media.scss: -------------------------------------------------------------------------------- 1 | .media { 2 | // Proper spacing between instances of .media 3 | margin-top: 15px; 4 | 5 | &:first-child { 6 | margin-top: 0; 7 | } 8 | } 9 | 10 | .media, 11 | .media-body { 12 | zoom: 1; 13 | overflow: hidden; 14 | } 15 | 16 | .media-body { 17 | width: 10000px; 18 | } 19 | 20 | .media-object { 21 | display: block; 22 | 23 | // Fix collapse in webkit from max-width: 100% and display: table-cell. 24 | &.img-thumbnail { 25 | max-width: none; 26 | } 27 | } 28 | 29 | .media-right, 30 | .media > .pull-right { 31 | padding-left: 10px; 32 | } 33 | 34 | .media-left, 35 | .media > .pull-left { 36 | padding-right: 10px; 37 | } 38 | 39 | .media-left, 40 | .media-right, 41 | .media-body { 42 | display: table-cell; 43 | vertical-align: top; 44 | } 45 | 46 | .media-middle { 47 | vertical-align: middle; 48 | } 49 | 50 | .media-bottom { 51 | vertical-align: bottom; 52 | } 53 | 54 | // Reset margins on headings for tighter default spacing 55 | .media-heading { 56 | margin-top: 0; 57 | margin-bottom: 5px; 58 | } 59 | 60 | // Media list variation 61 | // 62 | // Undo default ul/ol styles 63 | .media-list { 64 | padding-left: 0; 65 | list-style: none; 66 | } 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2018 Horimoto Yasuhiro 4 | Copyright (c) 2017-2018 Kouhei Sutou 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /sample/element-set-attribute.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse("") 6 | local root = document:root() 7 | 8 | -- Uses dot syntax to set attribute value 9 | root.class = "A" 10 | print(root.class) 11 | -- -> A 12 | 13 | -- Uses [] syntax to set attribute value 14 | root["class"] = "B" 15 | print(root["class"]) 16 | -- -> B 17 | 18 | -- Uses set_attribute method to set attribute value 19 | root:set_attribute("class", "C") 20 | print(root:get_attribute("class")) 21 | -- -> C 22 | 23 | -- Removes an attribute by setting nil 24 | root.class = nil 25 | print(root:to_xml()) 26 | -- 27 | 28 | -- Adds a namespace declaration 29 | root["xmlns:example"] = "http://example.com/" 30 | print(root:to_xml()) 31 | -- 32 | 33 | -- Adds a new attribute with namespace 34 | root["example:attribute"] = "with namespace" 35 | print(root:to_xml()) 36 | -- 37 | 38 | -- Removes namespace declaration. It unsets the namespace of 39 | -- existing elements and attributes. 40 | root["xmlns:example"] = nil 41 | print(root:to_xml()) 42 | -- 43 | -------------------------------------------------------------------------------- /sample/element-move.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | 8 | 9 | 10 | 11 | ]] 12 | 13 | local document = xmlua.XML.parse(xml) 14 | local sub2 = document:search("/root/sub2")[1] 15 | 16 | -- Gets the previous sibling element of 17 | print(sub2:previous():to_xml()) 18 | -- 19 | 20 | local sub1 = sub2:previous() 21 | 22 | -- Gets the previous sibling element of 23 | print(sub1:previous()) 24 | -- nil 25 | 26 | 27 | -- Gets the next sibling element of 28 | print(sub2:next():to_xml()) 29 | -- 30 | 31 | local sub3 = sub2:next() 32 | 33 | -- Gets the next sibling element of 34 | print(sub3:next()) 35 | -- nil 36 | 37 | 38 | -- Gets the parent element of 39 | print(sub2:parent():to_xml()) 40 | -- 41 | -- 42 | -- 43 | -- 44 | -- 45 | 46 | local root = sub2:parent() 47 | 48 | -- Gets the parent of : xmlua.Document 49 | print(root:parent():to_xml()) 50 | -- 51 | -- 52 | -- 53 | -- 54 | -- 55 | -- 56 | 57 | local document = root:parent() 58 | 59 | -- Gets the parent of document 60 | print(document:parent()) 61 | -- nil 62 | -------------------------------------------------------------------------------- /xmlua/text.lua: -------------------------------------------------------------------------------- 1 | local Text = {} 2 | 3 | local libxml2 = require("xmlua.libxml2") 4 | local Node = require("xmlua.node") 5 | 6 | local methods = {} 7 | 8 | local metatable = {} 9 | 10 | function metatable.__index(element, key) 11 | return methods[key] or 12 | Node[key] 13 | end 14 | 15 | function methods:node_name() 16 | return "text" 17 | end 18 | 19 | function methods:text() 20 | return self:content() 21 | end 22 | 23 | function methods:concat(content) 24 | return libxml2.xmlTextConcat(self.node, 25 | content, 26 | content:len()) 27 | end 28 | 29 | function methods:merge(merge_node) 30 | if not self.node and not merge_node.node then 31 | error("Already freed receiver node and merged node") 32 | elseif not self.node then 33 | error("Already freed receiver node") 34 | elseif not merge_node.node then 35 | error("Already freed merged node") 36 | end 37 | 38 | local was_freed = libxml2.xmlTextMerge(self.node, merge_node.node) 39 | if was_freed then 40 | merge_node.node = nil 41 | end 42 | end 43 | 44 | function Text.new(document, node) 45 | local text = { 46 | document = document, 47 | node = node, 48 | } 49 | setmetatable(text, metatable) 50 | return text 51 | end 52 | 53 | return Text 54 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_jumbotron.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding-top: $jumbotron-padding; 8 | padding-bottom: $jumbotron-padding; 9 | margin-bottom: $jumbotron-padding; 10 | color: $jumbotron-color; 11 | background-color: $jumbotron-bg; 12 | 13 | h1, 14 | .h1 { 15 | color: $jumbotron-heading-color; 16 | } 17 | 18 | p { 19 | margin-bottom: ($jumbotron-padding / 2); 20 | font-size: $jumbotron-font-size; 21 | font-weight: 200; 22 | } 23 | 24 | > hr { 25 | border-top-color: darken($jumbotron-bg, 10%); 26 | } 27 | 28 | .container &, 29 | .container-fluid & { 30 | border-radius: $border-radius-large; // Only round corners at higher resolutions if contained in a container 31 | } 32 | 33 | .container { 34 | max-width: 100%; 35 | } 36 | 37 | @media screen and (min-width: $screen-sm-min) { 38 | padding-top: ($jumbotron-padding * 1.6); 39 | padding-bottom: ($jumbotron-padding * 1.6); 40 | 41 | .container &, 42 | .container-fluid & { 43 | padding-left: ($jumbotron-padding * 2); 44 | padding-right: ($jumbotron-padding * 2); 45 | } 46 | 47 | h1, 48 | .h1 { 49 | font-size: $jumbotron-heading-font-size; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /docs/reference/document-fragment.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.DocumentFragment 3 | --- 4 | 5 | # `xmlua.DocumentFragment` class 6 | 7 | ## Summary 8 | 9 | It's a class for document fragment node. 10 | 11 | Normaly, you can get document fragment object by [`xmlua.Document:create_document_fragment`][create-document-fragment]. 12 | 13 | Example: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_fragment_node = -- -> xmlua.DocumentFragment 20 | document:create_document_fragment() 21 | ``` 22 | 23 | It has methods of the following modules: 24 | 25 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 26 | 27 | * [`xmlua.Element`][element]: The class for element node. 28 | 29 | It means that you can use methods in the modules. 30 | 31 | ## Instance methods 32 | 33 | There are no methods specific to this class. 34 | 35 | ## See also 36 | 37 | * [`xmlua.Document`][document]: The class for HTML document and XML document. 38 | 39 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 40 | 41 | * [`xmlua.Element`][element]: The class for element node. 42 | 43 | 44 | [create-document-fragment]:document.html#document-fragment.html 45 | 46 | [document]:document.html 47 | 48 | [node]:node.html 49 | 50 | [element]:element.html 51 | -------------------------------------------------------------------------------- /docs/ja/reference/xmlua.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua 3 | --- 4 | 5 | # `xmlua`モジュール 6 | 7 | ## 概要 8 | 9 | メインモジュールです。 10 | 11 | ## モジュール関数 12 | 13 | ### `init() -> nil` {#init} 14 | 15 | XMLuaを明示的に初期化します。XMLuaは暗黙的に初期化されるので、通常、呼ぶ必要はありません。 16 | 17 | マルチスレッドに対応するときに必要になります。 18 | 19 | 複数のスレッドでXMLuaを使いたいときは、スレッドを作る前にメインスレッドで`xmlua.init`を呼ばなければいけません。 20 | 21 | 例: 22 | 23 | ```lua 24 | local xmlua = require("xmlua") 25 | 26 | -- 複数のスレッドでXMLuaを使う場合は 27 | -- スレッドを作る前にメインスレッドでxmlua.initを呼ばないといけません。 28 | xmlua.init() 29 | 30 | local thread = require("cqueues.thread") 31 | 32 | -- thread.start(function() ... end) 33 | ``` 34 | 35 | ### `cleanup() -> nil` {#cleanup} 36 | 37 | XMLuaが使っているすべてのリソースを解放します。通常、呼ぶ必要はありません。なぜなら、これを呼びたいときはプロセスが終了する直前だからです。 38 | 39 | メインスレッドで呼ばないといけません。 40 | 41 | 呼ぶときは、すべてのスレッドを終了し、すべてのXMLua関連のオブジェクトをこれ以上触らないようにしないといけません。 42 | 43 | 例: 44 | 45 | ```lua 46 | local xmlua = require("xmlua") 47 | 48 | -- local xml = ... 49 | -- local document = xmlua.XML.parse(xml) 50 | -- document:search(...) 51 | 52 | -- XMLuaが使っているすべてのリソースを開放するために 53 | -- メインスレッドでxmlua.cleanupを呼べます。 54 | -- 呼ぶときは、すべてのスレッドを終了して、XMLua関連のオブジェクトを今後 55 | -- 絶対使わないようにしてください。 56 | xmlua.cleanup() 57 | 58 | os.exit() 59 | ``` 60 | 61 | ## 参照 62 | 63 | * [チュートリアルのマルチスレッドセクション][tutorial-multithread] 64 | 65 | 66 | [tutorial-multithread]:../tutorial/#multithread 67 | -------------------------------------------------------------------------------- /sample/node-set-merge.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.XML.parse([[ 6 | 7 | sub1-1 8 | sub2-1 9 | sub1-2 10 | sub2-2 11 | sub3 12 | 13 | ]]) 14 | 15 | local sub1s = document:search("/root/sub1") 16 | -- sub1-1 17 | -- sub1-2 18 | 19 | local sub2s = document:search("/root/sub2") 20 | -- sub2-1 21 | -- sub2-2 22 | 23 | -- Merge two node sets 24 | local sub1_and_sub2s = sub1s:merge(sub2s) 25 | print(sub1_and_sub2s:to_xml()) 26 | -- sub1-1 27 | -- sub1-2 28 | -- sub2-1 29 | -- sub2-2 30 | 31 | -- + is a shortcut for :merge() 32 | local sub1_and_sub2s = sub1s + sub2s 33 | print(sub1_and_sub2s:to_xml()) 34 | -- sub1-1 35 | -- sub1-2 36 | -- sub2-1 37 | -- sub2-2 38 | 39 | local sub2_and_sub3s = document:css_select("sub2, sub3") 40 | -- sub2-1 41 | -- sub2-2 42 | -- sub3 43 | 44 | -- Duplicated nodes (sub2s) are unified 45 | local all_subs = sub1_and_sub2s + sub2_and_sub3s 46 | print(all_subs:to_xml()) 47 | -- sub1-1 48 | -- sub1-2 49 | -- sub2-1 50 | -- sub2-2 51 | -- sub3 52 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | @mixin img-responsive($display: block) { 10 | display: $display; 11 | max-width: 100%; // Part 1: Set a maximum relative to the parent 12 | height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching 13 | } 14 | 15 | 16 | // Retina image 17 | // 18 | // Short retina mixin for setting background-image and -size. Note that the 19 | // spelling of `min--moz-device-pixel-ratio` is intentional. 20 | @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) { 21 | background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}")); 22 | 23 | @media 24 | only screen and (-webkit-min-device-pixel-ratio: 2), 25 | only screen and ( min--moz-device-pixel-ratio: 2), 26 | only screen and ( -o-min-device-pixel-ratio: 2/1), 27 | only screen and ( min-device-pixel-ratio: 2), 28 | only screen and ( min-resolution: 192dpi), 29 | only screen and ( min-resolution: 2dppx) { 30 | background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}")); 31 | background-size: $width-1x $height-1x; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dockerfiles/Dockerfile.almalinux-8: -------------------------------------------------------------------------------- 1 | FROM almalinux:8 2 | 3 | RUN \ 4 | dnf install -y epel-release 5 | RUN \ 6 | dnf install --enablerepo=powertools -y \ 7 | compat-lua-devel \ 8 | gcc \ 9 | git \ 10 | libxml2 \ 11 | luajit \ 12 | luajit-devel \ 13 | luarocks \ 14 | m4 \ 15 | make \ 16 | openssl-devel \ 17 | unzip 18 | RUN \ 19 | luarocks --lua-version 5.1 install cqueues \ 20 | CRYPTO_LIBDIR=/usr/lib64 \ 21 | OPENSSL_LIBDIR=/usr/lib64 && \ 22 | luarocks --lua-version 5.1 install luaunit 23 | 24 | RUN \ 25 | useradd --user-group --create-home xmlua 26 | 27 | COPY . /home/xmlua/xmlua 28 | WORKDIR /home/xmlua/xmlua 29 | RUN \ 30 | cp \ 31 | xmlua.rockspec \ 32 | xmlua-$(grep VERSION xmlua.lua | sed -e 's/.*"\(.*\)"/\1/g')-0.rockspec 33 | RUN \ 34 | luarocks --lua-version 5.1 make xmlua-*.rockspec \ 35 | LIBXML2_LIBDIR=/usr/lib64 36 | RUN rm -rf xmlua.lua xmlua 37 | 38 | RUN \ 39 | mv /root/.luarocks/share/lua/5.1/* \ 40 | /usr/share/lua/5.1/ && \ 41 | mv /root/.luarocks/lib64/lua/5.1/* \ 42 | /usr/lib64/lua/5.1/ 43 | 44 | USER xmlua 45 | 46 | RUN \ 47 | git clone --depth 1 https://github.com/clear-code/luacs.git ../luacs 48 | 49 | CMD \ 50 | test/run-test.lua && \ 51 | luajit -e 'package.path = "../luacs/?.lua;" .. package.path' \ 52 | sample/parse-html-cqueues-thread.lua sample/sample.html 53 | -------------------------------------------------------------------------------- /docs/ja/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: none 3 | --- 4 | 5 |
6 |

XMLua

7 |

{{ site.description.ja }}

8 |

最新版({{ site.version }})は{{ site.release_date }}にリリースされました。 9 |

10 |

11 | チュートリアルをやってみる 14 | インストール 17 |

18 |
19 | 20 | ## XMLuaについて {#about} 21 | 22 | XMLua(えっくすえむえるあ)はXML・HTMLを処理するLuaライブラリーです。[libxml2][libxml2]を使っています。LuaJITのFFIモジュールを使って実装しています。 23 | 24 | XMLuaはlibxml2の生のAPIではなく、使いやすいAPIを提供します。使いやすいAPIは生のlibxml2のAPIの上に実装しています。 25 | 26 | ## ドキュメント {#documentations} 27 | 28 | * [おしらせ][news]: リリース情報。 29 | 30 | * [インストール][install]: XMLuaのインストール方法。 31 | 32 | * [チュートリアル][tutorial]: XMLuaの使い方を1つずつ説明。 33 | 34 | * [リファレンス][reference]: クラスやメソッドなど個別の機能の詳細な説明。 35 | 36 | ## ライセンス {#license} 37 | 38 | XMLuaのライセンスは[MITライセンス][mit-license]です。 39 | 40 | 著作権保持者など詳細は[LICENSE][license]ファイルを見てください。 41 | 42 | [libxml2]:http://xmlsoft.org/ 43 | 44 | [news]:news/ 45 | 46 | [install]:install/ 47 | 48 | [tutorial]:tutorial/ 49 | 50 | [reference]:reference/ 51 | 52 | [mit-license]:https://opensource.org/licenses/mit 53 | 54 | [license]:https://github.com/clear-code/xmlua/blob/master/LICENSE 55 | -------------------------------------------------------------------------------- /sample/to-html.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local document = xmlua.HTML.parse([[ 6 | 7 | 8 | Hello 9 | 10 | World 11 | 12 | ]]) 13 | 14 | -- Serializes as HTML 15 | print(document:to_html()) 16 | -- 17 | -- 18 | -- 19 | -- 20 | -- Hello 21 | -- 22 | -- World 23 | -- 24 | 25 | -- Serializes as EUC-JP encoded HTML 26 | print(document:to_html({encoding = "EUC-JP"})) 27 | -- 28 | -- 29 | -- 30 | -- 31 | -- Hello 32 | -- 33 | -- World 34 | -- 35 | 36 | -- Serializes element as HTML 37 | print(document:search("/html/body")[1]:to_html()) 38 | -- World 39 | 40 | -- Serializes elements under ( and ) as HTML 41 | print(document:search("/html/*"):to_html()) 42 | -- 43 | -- 44 | -- Hello 45 | -- World 46 | -------------------------------------------------------------------------------- /sample/element-append-element.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | ]] 8 | 9 | local document = xmlua.XML.parse(xml) 10 | local root = document:root() 11 | 12 | -- Append a new to 13 | root:append_element("sub1") 14 | print(root:to_xml()) 15 | -- 16 | -- 17 | -- 18 | 19 | -- Append a new to 20 | root:append_element("sub2") 21 | print(root:to_xml()) 22 | -- 23 | -- 24 | -- 25 | -- 26 | 27 | -- Append a new with attributes to 28 | root:append_element("sub3", {attribute1 = "value1", attribute2 = "value2"}) 29 | print(root:to_xml()) 30 | -- 31 | -- 32 | -- 33 | -- 34 | -- 35 | 36 | -- Append a new with namespace to 37 | root:append_element("example:sub4", 38 | { 39 | ["xmlns:example"] = "http://example.com/", 40 | data = "without namespace", 41 | ["example:data"] = "with namespace"}) 42 | print(root:to_xml()) 43 | -- 44 | -- 45 | -- 46 | -- 47 | -- 51 | -- 52 | -------------------------------------------------------------------------------- /docs/ja/reference/processing-instruction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.ProcessingInstruction 3 | --- 4 | 5 | # `xmlua.ProcessingInstruction` クラス 6 | 7 | ## 概要 8 | 9 | 処理命令ノード用のクラスです。 10 | 11 | 通常、[`xmlua.Document:create_processing_instruction`][create-processing-instruction]を使用して取得します。 12 | 13 | 例: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.ProcessingInstruction 20 | document:create_processing_instruction() 21 | ``` 22 | 23 | このクラスのオブジェクトは以下のモジュールのメソッドを使えます。 24 | 25 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 26 | 27 | つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。 28 | 29 | ## インスタンスメソッド 30 | 31 | ### `target() -> string` {#prefix} 32 | 33 | 処理命令を `string` として返します。 34 | 35 | 例: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({"root"}) 41 | local processing_instruction = 42 | document:create_processing_instruction("xml-stylesheet", 43 | "href=\"www.test.com/test-style.xsl\" type=\"text/xsl\"") 44 | print(processing_instruction:target()) 45 | -- xml-stylesheet 46 | ``` 47 | 48 | ## 参照 49 | 50 | * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。 51 | 52 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 53 | 54 | 55 | [create-processing-instruction]:document.html#create-processing-instruction 56 | 57 | [document]:document.html 58 | 59 | [node]:node.html 60 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: $label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // [converter] extracted a& to a.label 18 | 19 | // Empty labels collapse automatically (not available in IE8) 20 | &:empty { 21 | display: none; 22 | } 23 | 24 | // Quick fix for labels in buttons 25 | .btn & { 26 | position: relative; 27 | top: -1px; 28 | } 29 | } 30 | 31 | // Add hover effects, but only for links 32 | a.label { 33 | &:hover, 34 | &:focus { 35 | color: $label-link-hover-color; 36 | text-decoration: none; 37 | cursor: pointer; 38 | } 39 | } 40 | 41 | // Colors 42 | // Contextual variations (linked labels get darker on :hover) 43 | 44 | .label-default { 45 | @include label-variant($label-default-bg); 46 | } 47 | 48 | .label-primary { 49 | @include label-variant($label-primary-bg); 50 | } 51 | 52 | .label-success { 53 | @include label-variant($label-success-bg); 54 | } 55 | 56 | .label-info { 57 | @include label-variant($label-info-bg); 58 | } 59 | 60 | .label-warning { 61 | @include label-variant($label-warning-bg); 62 | } 63 | 64 | .label-danger { 65 | @include label-variant($label-danger-bg); 66 | } 67 | -------------------------------------------------------------------------------- /docs/ja/reference/error-domain-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAXParser error domain 3 | --- 4 | 5 | # `xmlua.HTMLSAXParser.error.domain`と`xmlua.XMLSAXParser.error.domain`の値一覧 6 | 7 | `xmlua.HTMLSAXParser.error.domain`と`xmlua.XMLSAXParser.error.domain`の値は以下の通りです。 8 | 9 | ``` 10 | XML_FROM_NONE = 0 11 | XML_FROM_PARSER = 1 : XMLパーサー 12 | XML_FROM_TREE = 2 : treeモジュール 13 | XML_FROM_NAMESPACE = 3 : XML名前空間モジュール 14 | XML_FROM_DTD = 4 : パーサーコンテキストによるXML DTD検証 15 | XML_FROM_HTML = 5 : HTMLパーサー 16 | XML_FROM_MEMORY = 6 : メモリーアロケーター 17 | XML_FROM_OUTPUT = 7 : シリアライゼーションコード 18 | XML_FROM_IO = 8 : Input/Outputスタック 19 | XML_FROM_FTP = 9 : FTPモジュール 20 | XML_FROM_HTTP = 10 : HTTPモジュール 21 | XML_FROM_XINCLUDE = 11 : XInclude処理 22 | XML_FROM_XPATH = 12 : XPathモジュール 23 | XML_FROM_XPOINTER = 13 : XPointerモジュール 24 | XML_FROM_REGEXP = 14 : 正規表現モジュール 25 | XML_FROM_DATATYPE = 15 : W3C XML Schemas データタイプモジュール 26 | XML_FROM_SCHEMASP = 16 : W3C XML Schemas パーサーモジュール 27 | XML_FROM_SCHEMASV = 17 : W3C XML Schemas 検証モジュール 28 | XML_FROM_RELAXNGP = 18 : Relax-NG パーサーモジュー 29 | XML_FROM_RELAXNGV = 19 : Relax-NG 検証モジュール 30 | XML_FROM_CATALOG = 20 : カタログモジュール 31 | XML_FROM_C14N = 21 : 正規化モジュール 32 | XML_FROM_XSLT = 22 : XSLTエンジン(libxslt) 33 | XML_FROM_VALID = 23 : XML DTD 検証 34 | XML_FROM_CHECK = 24 : エラーチェックモジュール 35 | XML_FROM_WRITER = 25 : xmlwriter モジュール 36 | XML_FROM_MODULE = 26 : 動的ロードモジュール 37 | XML_FROM_I18N = 27 : 文字変換ハンドリングモジュール 38 | XML_FROM_SCHEMATRONV = 28 : Schematron検証モジュール 39 | XML_FROM_BUFFER = 29 : バッファーモジュール 40 | XML_FROM_URI = 30 : URIモジュール 41 | ``` 42 | -------------------------------------------------------------------------------- /xmlua/serializable.lua: -------------------------------------------------------------------------------- 1 | local Serializable = {} 2 | 3 | local libxml2 = require("xmlua.libxml2") 4 | local ffi = require("ffi") 5 | 6 | local function save(target, flags, failure_message, options) 7 | local buffer = libxml2.xmlBufferCreate() 8 | local encoding = "UTF-8" 9 | if options and options.encoding then 10 | encoding = options.encoding 11 | end 12 | local context = libxml2.xmlSaveToBuffer(buffer, encoding, flags) 13 | if options and options.escape then 14 | libxml2.xmlSaveSetEscape(context, options.escape) 15 | end 16 | local success 17 | if target.node then 18 | success = libxml2.xmlSaveTree(context, target.node) 19 | else 20 | success = libxml2.xmlSaveDoc(context, target.document) 21 | end 22 | libxml2.xmlSaveClose(context) 23 | if not success then 24 | error(failure_message) 25 | end 26 | return libxml2.xmlBufferGetContent(buffer) 27 | end 28 | 29 | function Serializable:to_html(options) 30 | return save(self, 31 | bit.bor(ffi.C.XML_SAVE_FORMAT, 32 | ffi.C.XML_SAVE_NO_DECL, 33 | ffi.C.XML_SAVE_NO_EMPTY, 34 | ffi.C.XML_SAVE_AS_HTML), 35 | "failed to generate HTML string", 36 | options) 37 | end 38 | 39 | function Serializable:to_xml(options) 40 | return save(self, 41 | bit.bor(ffi.C.XML_SAVE_FORMAT, 42 | ffi.C.XML_SAVE_AS_XML), 43 | "failed to generate XML string", 44 | options) 45 | end 46 | 47 | return Serializable 48 | -------------------------------------------------------------------------------- /sample/element-insert-element.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local xml = [[ 6 | 7 | ]] 8 | 9 | local document = xmlua.XML.parse(xml) 10 | local root = document:root() 11 | 12 | -- Insert a new to as the first element 13 | root:insert_element(1, "sub1") 14 | print(root:to_xml()) 15 | -- 16 | -- 17 | -- 18 | 19 | -- Insert a new to as the first element 20 | root:insert_element(1, "sub2") 21 | print(root:to_xml()) 22 | -- 23 | -- 24 | -- 25 | -- 26 | 27 | -- Insert a new with attributes to as the first element 28 | root:insert_element(1, "sub3", {attribute1 = "value1", attribute2 = "value2"}) 29 | print(root:to_xml()) 30 | -- 31 | -- 32 | -- 33 | -- 34 | -- 35 | 36 | -- Insert a new with namespace to as the first element 37 | root:insert_element(1, 38 | "example:sub4", 39 | { 40 | ["xmlns:example"] = "http://example.com/", 41 | data = "without namespace", 42 | ["example:data"] = "with namespace"}) 43 | print(root:to_xml()) 44 | -- 45 | -- 49 | -- 50 | -- 51 | -- 52 | -- 53 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_badges.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: $font-size-small; 12 | font-weight: $badge-font-weight; 13 | color: $badge-color; 14 | line-height: $badge-line-height; 15 | vertical-align: middle; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: $badge-bg; 19 | border-radius: $badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | 26 | // Quick fix for badges in buttons 27 | .btn & { 28 | position: relative; 29 | top: -1px; 30 | } 31 | 32 | .btn-xs &, 33 | .btn-group-xs > .btn & { 34 | top: 0; 35 | padding: 1px 5px; 36 | } 37 | 38 | // [converter] extracted a& to a.badge 39 | 40 | // Account for badges in navs 41 | .list-group-item.active > &, 42 | .nav-pills > .active > a > & { 43 | color: $badge-active-color; 44 | background-color: $badge-active-bg; 45 | } 46 | 47 | .list-group-item > & { 48 | float: right; 49 | } 50 | 51 | .list-group-item > & + & { 52 | margin-right: 5px; 53 | } 54 | 55 | .nav-pills > li > a > & { 56 | margin-left: 3px; 57 | } 58 | } 59 | 60 | // Hover state, but only for links 61 | a.badge { 62 | &:hover, 63 | &:focus { 64 | color: $badge-link-hover-color; 65 | text-decoration: none; 66 | cursor: pointer; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /test/test-xml.lua: -------------------------------------------------------------------------------- 1 | local luaunit = require("luaunit") 2 | local xmlua = require("xmlua") 3 | 4 | TestXML = {} 5 | function TestXML.test_parse_valid() 6 | local success, xml = pcall(xmlua.XML.parse, "") 7 | luaunit.assertEquals(success, true) 8 | luaunit.assertEquals(xml:to_html(), 9 | "\n") 10 | end 11 | 12 | function TestXML.test_parse_invalid() 13 | local success, message = pcall(xmlua.XML.parse, " ") 14 | luaunit.assertEquals(success, false) 15 | luaunit.assertEquals(message:gsub("^.+:%d+: ", ""), 16 | "Failed to parse XML: " .. 17 | "Start tag expected, '<' not found\n") 18 | end 19 | 20 | function TestXML.test_parse_options() 21 | local options = { 22 | parse_options = {"default", "nocdata"}, 23 | } 24 | local success, xml = pcall(xmlua.XML.parse, 25 | "texttext", 26 | options) 27 | luaunit.assertEquals(success, true) 28 | luaunit.assertEquals(xml:to_xml(), 29 | "\n" .. 30 | "textcdatatext\n") 31 | end 32 | 33 | function TestXML.test_root() 34 | local xml = xmlua.XML.parse("") 35 | luaunit.assertEquals(xml:root():to_xml(), 36 | [[ 37 | 38 | 39 | ]]) 40 | end 41 | 42 | function TestXML.test_parent() 43 | local xml = xmlua.XML.parse("") 44 | luaunit.assertNil(xml:parent()) 45 | end 46 | -------------------------------------------------------------------------------- /xmlua/libxml2/xml-io.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | 5 | /** 6 | * xmlOutputWriteCallback: 7 | * @context: an Output context 8 | * @buffer: the buffer of data to write 9 | * @len: the length of the buffer in bytes 10 | * 11 | * Callback used in the I/O Output API to write to the resource 12 | * 13 | * Returns the number of bytes written or -1 in case of error 14 | */ 15 | typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer, 16 | int len); 17 | /** 18 | * xmlOutputCloseCallback: 19 | * @context: an Output context 20 | * 21 | * Callback used in the I/O Output API to close the resource 22 | * 23 | * Returns 0 or -1 in case of error 24 | */ 25 | typedef int (*xmlOutputCloseCallback) (void * context); 26 | 27 | struct _xmlOutputBuffer { 28 | void* context; 29 | xmlOutputWriteCallback writecallback; 30 | xmlOutputCloseCallback closecallback; 31 | 32 | xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */ 33 | 34 | xmlBufPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */ 35 | xmlBufPtr conv; /* if encoder != NULL buffer for output */ 36 | int written; /* total number of byte written */ 37 | int error; 38 | }; 39 | 40 | xmlOutputBufferPtr 41 | xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder); 42 | 43 | xmlOutputBufferPtr 44 | xmlOutputBufferCreateBuffer (xmlBufferPtr buffer, 45 | xmlCharEncodingHandlerPtr encoder); 46 | 47 | int 48 | xmlOutputBufferClose (xmlOutputBufferPtr out); 49 | 50 | ]] 51 | -------------------------------------------------------------------------------- /docs/reference/processing-instruction.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.ProcessingInstruction 3 | --- 4 | 5 | # `xmlua.ProcessingInstruction` class 6 | 7 | ## Summary 8 | 9 | It's a class for processing instruction node. 10 | 11 | Normaly, you can get processing instruction object by [`xmlua.Document:create_processing_instruction`][create-processing-instruction]. 12 | 13 | Example: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.ProcessingInstruction 20 | document:create_processing_instruction() 21 | ``` 22 | 23 | It has methods of the following modules: 24 | 25 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 26 | 27 | It means that you can use methods in the modules. 28 | 29 | ## Instance methods 30 | 31 | ### `target() -> string` {#prefix} 32 | 33 | It returns processing instruction as `string`. 34 | 35 | Example: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({"root"}) 41 | local processing_instruction = 42 | document:create_processing_instruction("xml-stylesheet", 43 | "href=\"www.test.com/test-style.xsl\" type=\"text/xsl\"") 44 | print(processing_instruction:target()) 45 | -- xml-stylesheet 46 | ``` 47 | 48 | ## See also 49 | 50 | * [`xmlua.Document`][document]: The class for HTML document and XML document. 51 | 52 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 53 | 54 | 55 | [create-processing-instruction]:document.html#create-processing-instruction 56 | 57 | [document]:document.html 58 | 59 | [node]:node.html 60 | -------------------------------------------------------------------------------- /docs/ja/reference/namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.Namespace 3 | --- 4 | 5 | # `xmlua.Namespace` クラス 6 | 7 | ## 概要 8 | 9 | 名前空間用のクラスです。 10 | 11 | 通常、[`xmlua.Document:create_namespace`][create-namespace]を使用して取得します。 12 | 13 | 例: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.Namespace 20 | document:create_namespace() 21 | ``` 22 | 23 | このクラスのオブジェクトは以下のモジュールのメソッドを使えます。 24 | 25 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 26 | 27 | つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。 28 | 29 | ## インスタンスメソッド 30 | 31 | ### `prefix() -> string` {#prefix} 32 | 33 | 名前空間のプレフィックスを `string` として返します。 34 | 35 | 例: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({"root"}) 41 | local namespace = 42 | document:create_namespace("http://www.w3.org/1999/xhtml", 43 | "xhtml") 44 | 45 | print(namespace:prefix()) 46 | -- xhtml 47 | ``` 48 | 49 | ### `href() -> string` {#external_id} 50 | 51 | 名前空間のURIを `string` で返します。 52 | 53 | 例: 54 | 55 | ```lua 56 | local xmlua = require("xmlua") 57 | 58 | local document = xmlua.XML.build({"root"}) 59 | local namespace = 60 | document:create_namespace("http://www.w3.org/1999/xhtml", 61 | "xhtml") 62 | 63 | print(namespace:prefix()) 64 | -- http://www.w3.org/1999/xhtml 65 | ``` 66 | 67 | ## 参照 68 | 69 | * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。 70 | 71 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 72 | 73 | 74 | [create-namespace]:document.html#create-namespace 75 | 76 | [document]:document.html 77 | 78 | [node]:node.html 79 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: none 3 | --- 4 | 5 |
6 |

XMLua

7 |

{{ site.description.en }}

8 |

The latest version 9 | ({{ site.version }}) 10 | has been released at {{ site.release_date }}. 11 |

12 |

13 | Try tutorial 16 | Install 19 |

20 |
21 | 22 | ## About XMLua {#about} 23 | 24 | XMLua is a Lua library for processing XML and HTML. It's based on [libxml2][libxml2]. It uses LuaJIT's FFI module. 25 | 26 | XMLua provides user-friendly API instead of low-level libxml2 API. The user-friendly API is implemented top of low-level libxml2 API. 27 | 28 | ## Documentations {#documentations} 29 | 30 | * [News][news]: It lists release information. 31 | 32 | * [Install][install]: It describes how to install XMLua. 33 | 34 | * [Tutorial][tutorial]: It describes how to use XMLua step by step. 35 | 36 | * [Reference][reference]: It describes details for each features such as classes and methods. 37 | 38 | ## License {#license} 39 | 40 | XMLua is released under [the MIT license][mit-license]. 41 | 42 | See [LICENSE][license] file for details such as copyright holders. 43 | 44 | [libxml2]:http://xmlsoft.org/ 45 | 46 | [news]:news/ 47 | 48 | [install]:install/ 49 | 50 | [tutorial]:tutorial/ 51 | 52 | [reference]:reference/ 53 | 54 | [mit-license]:https://opensource.org/licenses/mit 55 | 56 | [license]:https://github.com/clear-code/xmlua/blob/master/LICENSE 57 | -------------------------------------------------------------------------------- /test/test-comment.lua: -------------------------------------------------------------------------------- 1 | local luaunit = require("luaunit") 2 | local xmlua = require("xmlua") 3 | 4 | TestComment = {} 5 | 6 | function TestComment.test_node_Name() 7 | local document = xmlua.XML.parse([[ 8 | 9 | 10 | 11 | ]]) 12 | local comment = document:search("/root/comment()") 13 | luaunit.assertEquals(comment[1]:node_name(), 14 | "comment") 15 | end 16 | 17 | function TestComment.test_path() 18 | local document = xmlua.XML.parse([[ 19 | 20 | 21 | 22 | ]]) 23 | local comment = document:search("/root/comment()") 24 | luaunit.assertEquals(comment[1]:path(), 25 | "/root/comment()") 26 | end 27 | 28 | function TestComment.test_content() 29 | local document = xmlua.XML.parse([[ 30 | 31 | 32 | 33 | ]]) 34 | local comment = document:search("/root/comment()") 35 | luaunit.assertEquals(comment[1]:content(), 36 | "This is comment!") 37 | end 38 | 39 | function TestComment.test_set_content() 40 | local document = xmlua.XML.parse([[ 41 | 42 | 43 | 44 | ]]) 45 | local comment = document:search("/root/comment()") 46 | comment[1]:set_content("Setting comment!") 47 | luaunit.assertEquals(comment[1]:content(), 48 | "Setting comment!") 49 | end 50 | 51 | function TestComment.test_text() 52 | local document = xmlua.XML.parse([[ 53 | 54 | 55 | 56 | ]]) 57 | local comment = document:search("/root/comment()") 58 | luaunit.assertEquals(comment[1]:text(), 59 | "") 60 | end 61 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_code.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and block) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: $font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 4px; 17 | font-size: 90%; 18 | color: $code-color; 19 | background-color: $code-bg; 20 | border-radius: $border-radius-base; 21 | } 22 | 23 | // User input typically entered via keyboard 24 | kbd { 25 | padding: 2px 4px; 26 | font-size: 90%; 27 | color: $kbd-color; 28 | background-color: $kbd-bg; 29 | border-radius: $border-radius-small; 30 | box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); 31 | 32 | kbd { 33 | padding: 0; 34 | font-size: 100%; 35 | font-weight: bold; 36 | box-shadow: none; 37 | } 38 | } 39 | 40 | // Blocks of code 41 | pre { 42 | display: block; 43 | padding: (($line-height-computed - 1) / 2); 44 | margin: 0 0 ($line-height-computed / 2); 45 | font-size: ($font-size-base - 1); // 14px to 13px 46 | line-height: $line-height-base; 47 | word-break: break-all; 48 | word-wrap: break-word; 49 | color: $pre-color; 50 | background-color: $pre-bg; 51 | border: 1px solid $pre-border-color; 52 | border-radius: $border-radius-base; 53 | 54 | // Account for some code outputs that place code tags in pre tags 55 | code { 56 | padding: 0; 57 | font-size: inherit; 58 | color: inherit; 59 | white-space: pre-wrap; 60 | background-color: transparent; 61 | border-radius: 0; 62 | } 63 | } 64 | 65 | // Enable scrollable blocks of code 66 | .pre-scrollable { 67 | max-height: $pre-scrollable-max-height; 68 | overflow-y: scroll; 69 | } 70 | -------------------------------------------------------------------------------- /sample/parse-html-sax.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local path = arg[1] 6 | local file = assert(io.open(path)) 7 | 8 | local parser = xmlua.HTMLSAXParser.new() 9 | 10 | parser.start_document = function() 11 | print("Start document") 12 | end 13 | 14 | parser.ignorable_whitespace = function(whitespaces) 15 | print("Ignorable whitespaces: " .. "\"" .. whitespaces .. "\"") 16 | print("Ignorable whitespaces length: " .. #whitespaces) 17 | end 18 | 19 | parser.processing_instruction = function(target, data) 20 | print("Processing instruction target: " .. target) 21 | print("Processing instruction data: " .. data) 22 | end 23 | 24 | parser.comment = function(comment) 25 | print("Comment: " .. comment) 26 | end 27 | 28 | parser.cdata_block = function(cdata_block) 29 | print("CDATA block: " .. cdata_block) 30 | end 31 | 32 | parser.start_element = function(name, attributes) 33 | print("Start element: " .. name) 34 | if #attributes > 0 then 35 | print(" Attributes:") 36 | for i, attribute in pairs(attributes) do 37 | print(" " .. attribute.name .. ": " .. (attribute.value or "")) 38 | end 39 | end 40 | end 41 | 42 | parser.end_element = function(name) 43 | print("End element: " .. name) 44 | end 45 | 46 | parser.text = function(text) 47 | print("Text: <" .. text .. ">") 48 | end 49 | 50 | parser.error = function(err) 51 | print("Error: " .. path .. ":" .. err.line .. ": " .. err.message) 52 | end 53 | 54 | parser.end_document = function() 55 | print("End document") 56 | end 57 | 58 | while true do 59 | local line = file:read() 60 | if not line then 61 | parser:finish() 62 | break 63 | end 64 | parser:parse(line) 65 | end 66 | file:close() 67 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/_bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.5 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | // Core variables and mixins 8 | @import "bootstrap/variables"; 9 | @import "bootstrap/mixins"; 10 | 11 | // Reset and dependencies 12 | @import "bootstrap/normalize"; 13 | @import "bootstrap/print"; 14 | @import "bootstrap/glyphicons"; 15 | 16 | // Core CSS 17 | @import "bootstrap/scaffolding"; 18 | @import "bootstrap/type"; 19 | @import "bootstrap/code"; 20 | @import "bootstrap/grid"; 21 | @import "bootstrap/tables"; 22 | @import "bootstrap/forms"; 23 | @import "bootstrap/buttons"; 24 | 25 | // Components 26 | @import "bootstrap/component-animations"; 27 | @import "bootstrap/dropdowns"; 28 | @import "bootstrap/button-groups"; 29 | @import "bootstrap/input-groups"; 30 | @import "bootstrap/navs"; 31 | @import "bootstrap/navbar"; 32 | @import "bootstrap/breadcrumbs"; 33 | @import "bootstrap/pagination"; 34 | @import "bootstrap/pager"; 35 | @import "bootstrap/labels"; 36 | @import "bootstrap/badges"; 37 | @import "bootstrap/jumbotron"; 38 | @import "bootstrap/thumbnails"; 39 | @import "bootstrap/alerts"; 40 | @import "bootstrap/progress-bars"; 41 | @import "bootstrap/media"; 42 | @import "bootstrap/list-group"; 43 | @import "bootstrap/panels"; 44 | @import "bootstrap/responsive-embed"; 45 | @import "bootstrap/wells"; 46 | @import "bootstrap/close"; 47 | 48 | // Components w/ JavaScript 49 | @import "bootstrap/modals"; 50 | @import "bootstrap/tooltip"; 51 | @import "bootstrap/popovers"; 52 | @import "bootstrap/carousel"; 53 | 54 | // Utility classes 55 | @import "bootstrap/utilities"; 56 | @import "bootstrap/responsive-utilities"; 57 | -------------------------------------------------------------------------------- /docs/reference/xmlua.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua 3 | --- 4 | 5 | # `xmlua` module 6 | 7 | ## Summary 8 | 9 | It's the main module. 10 | 11 | ## Module functions 12 | 13 | ### `init() -> nil` {#init} 14 | 15 | It initializes XMLua implicitly. Normally, you don't need to call it because XMLua is initialized explicitly. 16 | 17 | It's needed for supporting multithread. 18 | 19 | If you want to use XMLua in multiple threads, you must call `xmlua.init` in the main thread before you create any thread. 20 | 21 | Example: 22 | 23 | ```lua 24 | local xmlua = require("xmlua") 25 | 26 | -- You must call xmlua.init in main thread before you create threads 27 | -- when you use XMLua with multiple threads. 28 | xmlua.init() 29 | 30 | local thread = require("cqueues.thread") 31 | 32 | -- thread.start(function() ... end) 33 | ``` 34 | 35 | ### `cleanup() -> nil` {#cleanup} 36 | 37 | It frees all resources used by XMLua. Normally, you don't need to call it because your process will be exited soon when you want to call it. 38 | 39 | You must call it in the main thread. 40 | 41 | You must ensure that all threads are finished and all XMLua related objects aren't used anymore when you call it. 42 | 43 | Example: 44 | 45 | ```lua 46 | local xmlua = require("xmlua") 47 | 48 | -- local xml = ... 49 | -- local document = xmlua.XML.parse(xml) 50 | -- document:search(...) 51 | 52 | -- You can call xmlua.cleanup in main thread to free all resources 53 | -- used by XMLua. You must ensure that all threads are finished and 54 | -- all XMLua related objects aren't used anymore. 55 | xmlua.cleanup() 56 | 57 | os.exit() 58 | ``` 59 | 60 | ## See also 61 | 62 | * [Multithread section in Tutorial][tutorial-multithread] 63 | 64 | 65 | [tutorial-multithread]:../tutorial/#multithread 66 | -------------------------------------------------------------------------------- /test/test-cdata-section.lua: -------------------------------------------------------------------------------- 1 | local luaunit = require("luaunit") 2 | local xmlua = require("xmlua") 3 | 4 | TestCDATASection = {} 5 | 6 | function TestCDATASection.test_node_name() 7 | local document = xmlua.XML.parse([=[ 8 | ]]> 9 | ]=]) 10 | local cdata_section = document:search("/root/text()") 11 | luaunit.assertEquals(cdata_section[1]:node_name(), 12 | "cdata-section") 13 | end 14 | 15 | function TestCDATASection.test_path() 16 | local document = xmlua.XML.parse([=[ 17 | ]]> 18 | ]=]) 19 | local cdata_section = document:search("/root/text()") 20 | luaunit.assertEquals(cdata_section[1]:path(), 21 | "/root/text()") 22 | end 23 | 24 | function TestCDATASection.test_content() 25 | local document = xmlua.XML.parse([=[ 26 | ]]> 27 | ]=]) 28 | local cdata_section = document:search("/root/text()") 29 | luaunit.assertEquals(cdata_section[1]:content(), 30 | "This is ") 31 | end 32 | 33 | function TestCDATASection.test_set_content() 34 | local document = xmlua.XML.parse([=[ 35 | ]]> 36 | ]=]) 37 | local cdata_section = document:search("/root/text()") 38 | cdata_section[1]:set_content("Setting new content!") 39 | luaunit.assertEquals(cdata_section[1]:content(), 40 | "Setting new content!") 41 | end 42 | 43 | function TestCDATASection.test_text() 44 | local document = xmlua.XML.parse([=[ 45 | ]]> 46 | ]=]) 47 | local cdata_section = document:search("/root/text()") 48 | luaunit.assertEquals(cdata_section[1]:text(), 49 | "") 50 | end 51 | -------------------------------------------------------------------------------- /xmlua/libxml2/valid.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef void (*xmlValidityErrorFunc) (void *ctx, 5 | const char *msg, 6 | ...); 7 | typedef void (*xmlValidityWarningFunc) (void *ctx, 8 | const char *msg, 9 | ...); 10 | 11 | typedef struct _xmlValidState xmlValidState; 12 | 13 | typedef struct _xmlValidCtxt xmlValidCtxt; 14 | struct _xmlValidCtxt { 15 | void *userData; /* user specific data block */ 16 | xmlValidityErrorFunc error; /* the callback in case of errors */ 17 | xmlValidityWarningFunc warning; /* the callback in case of warning */ 18 | 19 | /* Node analysis stack used when validating within entities */ 20 | xmlNodePtr node; /* Current parsed Node */ 21 | int nodeNr; /* Depth of the parsing stack */ 22 | int nodeMax; /* Max depth of the parsing stack */ 23 | xmlNodePtr *nodeTab; /* array of nodes */ 24 | 25 | unsigned int finishDtd; /* finished validating the Dtd ? */ 26 | xmlDocPtr doc; /* the document */ 27 | int valid; /* temporary validity check result */ 28 | 29 | /* state state used for non-determinist content validation */ 30 | xmlValidState *vstate; /* current state */ 31 | int vstateNr; /* Depth of the validation stack */ 32 | int vstateMax; /* Max depth of the validation stack */ 33 | xmlValidState *vstateTab; /* array of validation states */ 34 | 35 | void *am; 36 | void *state; 37 | }; 38 | ]] 39 | -------------------------------------------------------------------------------- /docs/ja/reference/text.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.Text 3 | --- 4 | 5 | # `xmlua.Text` クラス 6 | 7 | ## 概要 8 | 9 | テキストノードのためのクラスです。[`xmlua.Searchable:search`][searchable-search] と [`xmlua.NodeSet`][node-set] の `[]` を使ってテキストノードを取得できます。 10 | 11 | 例: 12 | 13 | ```lua 14 | local xmlua = require("xmlua") 15 | 16 | local document = xmlua.XML.parse("This is text") 17 | 18 | document:search("/root/text()")[1] -- -> xmlua.Text 19 | ``` 20 | 21 | ## インスタンスメソッド 22 | 23 | ### `concat(content) -> boolean` {#concat} 24 | 25 | 既存のノードの最後に引数で指定した内容を連結します。連結の成否をブーリアンとして返します。`true` は連結の成功を表します。 `false` は連結の失敗を表します。 26 | 27 | 例: 28 | 29 | ```lua 30 | local document = 31 | xmlua.XML.build({"root", {}, "Text1"}) 32 | local text_nodes = document:search("/root/text()") 33 | text_nodes[1]:concat("Text2") 34 | print(document:to_xml()) 35 | -- 36 | --Text1Text2 37 | end 38 | ``` 39 | 40 | ### `merge(content) -> boolean` {#concat} 41 | 42 | レシーバーのノードと引数の内容を1つのテキストノードにマージします。マージの成否をブーリアンとして返します。`true` はマージの成功を表します。 `false` はマージの失敗を表します。 43 | 44 | 例: 45 | 46 | ```lua 47 | local document = xmlua.XML.parse([[ 48 | 49 | Text: 50 | This is child 51 | 52 | ]]) 53 | local text1 = document:search("/root/text()") 54 | local text2 = document:search("/root/child/text()") 55 | 56 | text1[1]:merge(text2[1]) 57 | print(document:to_xml()) 58 | -- 59 | -- 60 | -- Text: 61 | -- This is child 62 | -- 63 | ``` 64 | 65 | ## 参照 66 | 67 | * [`xmlua.NodeSet`][node-set]: 複数ノードを扱うためのクラスです。 68 | 69 | * [`xmlua.Searchable`][searchable]: ノード検索関連のメソッドを提供します。 70 | 71 | 72 | [node-set]:node-set.html 73 | 74 | [searchable-search]:searchable.html#search 75 | 76 | [searchable]:searchable.html 77 | -------------------------------------------------------------------------------- /xmlua/libxml2/encoding.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef enum { 5 | XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */ 6 | XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */ 7 | XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */ 8 | XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */ 9 | XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */ 10 | XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */ 11 | XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */ 12 | XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */ 13 | XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */ 14 | XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */ 15 | XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */ 16 | XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */ 17 | XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */ 18 | XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */ 19 | XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */ 20 | XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */ 21 | XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */ 22 | XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */ 23 | XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */ 24 | XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */ 25 | XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */ 26 | XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */ 27 | XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */ 28 | XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */ 29 | } xmlCharEncoding; 30 | 31 | typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen, 32 | const unsigned char *in, int *inlen); 33 | 34 | typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler; 35 | typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr; 36 | ]] 37 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/mixins/_buttons.scss: -------------------------------------------------------------------------------- 1 | // Button variants 2 | // 3 | // Easily pump out default styles, as well as :hover, :focus, :active, 4 | // and disabled options for all buttons 5 | 6 | @mixin button-variant($color, $background, $border) { 7 | color: $color; 8 | background-color: $background; 9 | border-color: $border; 10 | 11 | &:focus, 12 | &.focus { 13 | color: $color; 14 | background-color: darken($background, 10%); 15 | border-color: darken($border, 25%); 16 | } 17 | &:hover { 18 | color: $color; 19 | background-color: darken($background, 10%); 20 | border-color: darken($border, 12%); 21 | } 22 | &:active, 23 | &.active, 24 | .open > &.dropdown-toggle { 25 | color: $color; 26 | background-color: darken($background, 10%); 27 | border-color: darken($border, 12%); 28 | 29 | &:hover, 30 | &:focus, 31 | &.focus { 32 | color: $color; 33 | background-color: darken($background, 17%); 34 | border-color: darken($border, 25%); 35 | } 36 | } 37 | &:active, 38 | &.active, 39 | .open > &.dropdown-toggle { 40 | background-image: none; 41 | } 42 | &.disabled, 43 | &[disabled], 44 | fieldset[disabled] & { 45 | &, 46 | &:hover, 47 | &:focus, 48 | &.focus, 49 | &:active, 50 | &.active { 51 | background-color: $background; 52 | border-color: $border; 53 | } 54 | } 55 | 56 | .badge { 57 | color: $background; 58 | background-color: $color; 59 | } 60 | } 61 | 62 | // Button sizes 63 | @mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) { 64 | padding: $padding-vertical $padding-horizontal; 65 | font-size: $font-size; 66 | line-height: $line-height; 67 | border-radius: $border-radius; 68 | } 69 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_grid.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Grid system 3 | // -------------------------------------------------- 4 | 5 | 6 | // Container widths 7 | // 8 | // Set the container width, and override it for fixed navbars in media queries. 9 | 10 | .container { 11 | @include container-fixed; 12 | 13 | @media (min-width: $screen-sm-min) { 14 | width: $container-sm; 15 | } 16 | @media (min-width: $screen-md-min) { 17 | width: $container-md; 18 | } 19 | @media (min-width: $screen-lg-min) { 20 | width: $container-lg; 21 | } 22 | } 23 | 24 | 25 | // Fluid container 26 | // 27 | // Utilizes the mixin meant for fixed width containers, but without any defined 28 | // width for fluid, full width layouts. 29 | 30 | .container-fluid { 31 | @include container-fixed; 32 | } 33 | 34 | 35 | // Row 36 | // 37 | // Rows contain and clear the floats of your columns. 38 | 39 | .row { 40 | @include make-row; 41 | } 42 | 43 | 44 | // Columns 45 | // 46 | // Common styles for small and large grid columns 47 | 48 | @include make-grid-columns; 49 | 50 | 51 | // Extra small grid 52 | // 53 | // Columns, offsets, pushes, and pulls for extra small devices like 54 | // smartphones. 55 | 56 | @include make-grid(xs); 57 | 58 | 59 | // Small grid 60 | // 61 | // Columns, offsets, pushes, and pulls for the small device range, from phones 62 | // to tablets. 63 | 64 | @media (min-width: $screen-sm-min) { 65 | @include make-grid(sm); 66 | } 67 | 68 | 69 | // Medium grid 70 | // 71 | // Columns, offsets, pushes, and pulls for the desktop device range. 72 | 73 | @media (min-width: $screen-md-min) { 74 | @include make-grid(md); 75 | } 76 | 77 | 78 | // Large grid 79 | // 80 | // Columns, offsets, pushes, and pulls for the large desktop device range. 81 | 82 | @media (min-width: $screen-lg-min) { 83 | @include make-grid(lg); 84 | } 85 | -------------------------------------------------------------------------------- /docs/reference/namespace.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.Namespace 3 | --- 4 | 5 | # `xmlua.Namespace` class 6 | 7 | ## Summary 8 | 9 | It's a class for namespace node. 10 | 11 | Normaly, you can get document type object by [`xmlua.Document:create_namespace`][create-namespace]. 12 | 13 | Example: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.Namespace 20 | document:create_namespace() 21 | ``` 22 | 23 | It has methods of the following modules: 24 | 25 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 26 | 27 | It means that you can use methods in the modules. 28 | 29 | ## Instance methods 30 | 31 | ### `prefix() -> string` {#prefix} 32 | 33 | It returns prefix of the namespace as `string`. 34 | 35 | Example: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({"root"}) 41 | local namespace = 42 | document:create_namespace("http://www.w3.org/1999/xhtml", 43 | "xhtml") 44 | 45 | print(namespace:prefix()) 46 | -- xhtml 47 | ``` 48 | 49 | ### `href() -> string` {#external_id} 50 | 51 | It returns namespace of uri as `string`. 52 | 53 | Example: 54 | 55 | ```lua 56 | local xmlua = require("xmlua") 57 | 58 | local document = xmlua.XML.build({"root"}) 59 | local namespace = 60 | document:create_namespace("http://www.w3.org/1999/xhtml", 61 | "xhtml") 62 | 63 | print(namespace:prefix()) 64 | -- http://www.w3.org/1999/xhtml 65 | ``` 66 | 67 | ## See also 68 | 69 | * [`xmlua.Document`][document]: The class for HTML document and XML document. 70 | 71 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 72 | 73 | 74 | [create-namespace]:document.html#create-namespace 75 | 76 | [document]:document.html 77 | 78 | [node]:node.html 79 | -------------------------------------------------------------------------------- /docs/reference/error-domain-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SAXParser error domain 3 | --- 4 | 5 | # `xmlua.HTMLSAXParser.error.domain` and `xmlua.XMLSAXParser.error.domain` value list 6 | 7 | `xmlua.HTMLSAXParser.error.domain` and `xmlua.XMLSAXParser.error.domain` have values as below. 8 | 9 | ``` 10 | XML_FROM_NONE = 0 11 | XML_FROM_PARSER = 1 : The XML parser 12 | XML_FROM_TREE = 2 : The tree module 13 | XML_FROM_NAMESPACE = 3 : The XML Namespace module 14 | XML_FROM_DTD = 4 : The XML DTD validation with parser contex 15 | XML_FROM_HTML = 5 : The HTML parser 16 | XML_FROM_MEMORY = 6 : The memory allocator 17 | XML_FROM_OUTPUT = 7 : The serialization code 18 | XML_FROM_IO = 8 : The Input/Output stack 19 | XML_FROM_FTP = 9 : The FTP module 20 | XML_FROM_HTTP = 10 : The HTTP module 21 | XML_FROM_XINCLUDE = 11 : The XInclude processing 22 | XML_FROM_XPATH = 12 : The XPath module 23 | XML_FROM_XPOINTER = 13 : The XPointer module 24 | XML_FROM_REGEXP = 14 : The regular expressions module 25 | XML_FROM_DATATYPE = 15 : The W3C XML Schemas Datatype module 26 | XML_FROM_SCHEMASP = 16 : The W3C XML Schemas parser module 27 | XML_FROM_SCHEMASV = 17 : The W3C XML Schemas validation module 28 | XML_FROM_RELAXNGP = 18 : The Relax-NG parser module 29 | XML_FROM_RELAXNGV = 19 : The Relax-NG validator module 30 | XML_FROM_CATALOG = 20 : The Catalog module 31 | XML_FROM_C14N = 21 : The Canonicalization module 32 | XML_FROM_XSLT = 22 : The XSLT engine from libxslt 33 | XML_FROM_VALID = 23 : The XML DTD validation with valid context 34 | XML_FROM_CHECK = 24 : The error checking module 35 | XML_FROM_WRITER = 25 : The xmlwriter module 36 | XML_FROM_MODULE = 26 : The dynamically loaded module modul 37 | XML_FROM_I18N = 27 : The module handling character conversion 38 | XML_FROM_SCHEMATRONV = 28 : The Schematron validator module 39 | XML_FROM_BUFFER = 29 : The buffers module 40 | XML_FROM_URI = 30 : The URI module 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_alerts.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: $alert-padding; 11 | margin-bottom: $line-height-computed; 12 | border: 1px solid transparent; 13 | border-radius: $alert-border-radius; 14 | 15 | // Headings for larger alerts 16 | h4 { 17 | margin-top: 0; 18 | // Specified for the h4 to prevent conflicts of changing $headings-color 19 | color: inherit; 20 | } 21 | 22 | // Provide class for links that match alerts 23 | .alert-link { 24 | font-weight: $alert-link-font-weight; 25 | } 26 | 27 | // Improve alignment and spacing of inner content 28 | > p, 29 | > ul { 30 | margin-bottom: 0; 31 | } 32 | 33 | > p + p { 34 | margin-top: 5px; 35 | } 36 | } 37 | 38 | // Dismissible alerts 39 | // 40 | // Expand the right padding and account for the close button's positioning. 41 | 42 | .alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. 43 | .alert-dismissible { 44 | padding-right: ($alert-padding + 20); 45 | 46 | // Adjust close link position 47 | .close { 48 | position: relative; 49 | top: -2px; 50 | right: -21px; 51 | color: inherit; 52 | } 53 | } 54 | 55 | // Alternate styles 56 | // 57 | // Generate contextual modifier classes for colorizing the alert. 58 | 59 | .alert-success { 60 | @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); 61 | } 62 | 63 | .alert-info { 64 | @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); 65 | } 66 | 67 | .alert-warning { 68 | @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); 69 | } 70 | 71 | .alert-danger { 72 | @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); 73 | } 74 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | /^xmlua\.VERSION = "(.+?)"/ =~ File.read("xmlua.lua") 4 | version = $1 5 | 6 | desc "Tag for #{version}" 7 | task :tag do 8 | sh("git", "tag", "-a", version, "-m", "#{version} has been released!!!") 9 | sh("git", "push", "--tags") 10 | end 11 | 12 | desc "Upload package to luarocks.org" 13 | task :upload do 14 | api_key = ENV["API_KEY"] 15 | if api_key.nil? 16 | raise "Specify API key as API_KEY environment variable value" 17 | end 18 | 19 | rockspec_version = "" 20 | File.open("xmlua.rockspec") do |rockspec| 21 | rockspec.each_line do |line| 22 | case line 23 | when /package_version = "(.+?)"/ 24 | rockspec_version << $1 25 | when /version = package_version \.\. "(.+?)"/ 26 | rockspec_version << $1 27 | end 28 | end 29 | end 30 | versioned_rockspec_filename = "xmlua-#{rockspec_version}.rockspec" 31 | 32 | begin 33 | cp("xmlua.rockspec", versioned_rockspec_filename) 34 | sh("luarocks", 35 | "upload", 36 | "--api-key=#{api_key}", 37 | versioned_rockspec_filename) 38 | ensure 39 | rm_f(versioned_rockspec_filename) 40 | end 41 | end 42 | 43 | namespace :version do 44 | desc "Update version" 45 | task :update do 46 | new_version = ENV["VERSION"] 47 | if new_version.nil? 48 | raise "Specify new version as VERSION environment variable value" 49 | end 50 | 51 | xmlua_lua_content = File.read("xmlua.lua").gsub(/xmlua\.VERSION = ".+?"/) do 52 | "xmlua.VERSION = \"#{new_version}\"" 53 | end 54 | File.open("xmlua.lua", "w") do |xmlua_lua| 55 | xmlua_lua.print(xmlua_lua_content) 56 | end 57 | 58 | rockspec_content = File.read("xmlua.rockspec").gsub(/package_version = ".+?"/) do 59 | "package_version = \"#{new_version}\"" 60 | end 61 | File.open("xmlua.rockspec", "w") do |rockspec| 62 | rockspec.print(rockspec_content) 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /xmlua/libxml2/html-parser.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | typedef xmlDocPtr htmlDocPtr; 5 | typedef xmlParserCtxt htmlParserCtxt; 6 | typedef xmlParserCtxtPtr htmlParserCtxtPtr; 7 | typedef xmlSAXHandler htmlSAXHandler; 8 | typedef xmlSAXHandlerPtr htmlSAXHandlerPtr; 9 | 10 | typedef enum { 11 | HTML_PARSE_RECOVER = 1<<0, /* Relaxed parsing */ 12 | HTML_PARSE_NODEFDTD = 1<<2, /* do not default a doctype if not found */ 13 | HTML_PARSE_NOERROR = 1<<5, /* suppress error reports */ 14 | HTML_PARSE_NOWARNING= 1<<6, /* suppress warning reports */ 15 | HTML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */ 16 | HTML_PARSE_NOBLANKS = 1<<8, /* remove blank nodes */ 17 | HTML_PARSE_NONET = 1<<11,/* Forbid network access */ 18 | HTML_PARSE_NOIMPLIED= 1<<13,/* Do not add implied html/body... elements */ 19 | HTML_PARSE_COMPACT = 1<<16,/* compact small text nodes */ 20 | HTML_PARSE_IGNORE_ENC=1<<21 /* ignore internal document encoding hint */ 21 | } htmlParserOption; 22 | 23 | htmlParserCtxtPtr htmlNewParserCtxt(void); 24 | htmlParserCtxtPtr htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, 25 | void *user_data, 26 | const char *chunk, 27 | int size, 28 | const char *filename, 29 | xmlCharEncoding enc); 30 | 31 | int htmlParseChunk(htmlParserCtxtPtr ctxt, 32 | const char *chunk, 33 | int size, 34 | int terminate); 35 | 36 | void htmlFreeParserCtxt(htmlParserCtxtPtr context); 37 | 38 | htmlDocPtr htmlCtxtReadMemory(xmlParserCtxtPtr ctxt, 39 | const char *buffer, 40 | int size, 41 | const char *URL, 42 | const char *encoding, 43 | int options); 44 | ]] 45 | -------------------------------------------------------------------------------- /test/test-attribute.lua: -------------------------------------------------------------------------------- 1 | local luaunit = require("luaunit") 2 | local xmlua = require("xmlua") 3 | 4 | TestAttribute = {} 5 | 6 | function TestAttribute.test_node_name() 7 | local document = xmlua.XML.build({"root", {["id"]="1"}}) 8 | local attr = document:search("/root/@id") 9 | luaunit.assertEquals(attr[1]:node_name(), 10 | "attribute") 11 | end 12 | 13 | function TestAttribute.test_path() 14 | local document = 15 | xmlua.XML.build({"root", {["id"]="1"}}) 16 | local attr = document:search("/root/@id") 17 | luaunit.assertEquals(attr[1]:path(), 18 | "/root/@id") 19 | end 20 | 21 | function TestAttribute.test_content() 22 | local document = 23 | xmlua.XML.build({"root", {["id"]="1"}}) 24 | local attr = document:search("/root/@id") 25 | luaunit.assertEquals(attr[1]:content(), 26 | "1") 27 | end 28 | 29 | function TestAttribute.test_set_content() 30 | local document = 31 | xmlua.XML.build({"root", {["id"]="1"}}) 32 | local attr = document:search("/root/@id") 33 | attr[1]:set_content("345") 34 | luaunit.assertEquals(attr[1]:content(), 35 | "345") 36 | end 37 | 38 | function TestAttribute.test_get_owner_element() 39 | local document = 40 | xmlua.XML.build({"root", {["id"]="1"}}) 41 | local attr = document:search("/root/@id") 42 | local owner_element = attr[1]:get_owner_element() 43 | luaunit.assertEquals({ 44 | owner_element:name(), 45 | owner_element:path() 46 | }, 47 | { 48 | "root", 49 | "/root" 50 | }) 51 | end 52 | 53 | function TestAttribute.test_name() 54 | local document = 55 | xmlua.XML.build({"root", {["id"]="1"}}) 56 | local attr = document:search("/root/@id") 57 | luaunit.assertEquals(attr[1]:name(), 58 | "id") 59 | end 60 | -------------------------------------------------------------------------------- /sample/parse-html-cqueues-thread.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local thread = require("cqueues.thread") 4 | local xmlua = require("xmlua") 5 | 6 | -- You must call xmlua.init in main thread before you create threads 7 | -- when you use XMLua with multiple threads. 8 | xmlua.init() 9 | 10 | local n = 10 11 | 12 | local workers = {} 13 | local connections = {} 14 | 15 | for i = 1, n do 16 | local worker, connection = thread.start(function(connection) 17 | -- require("xmlua") isn't thread safe 18 | local xmlua = require("xmlua") 19 | -- Notify that require("xmlua") is finished 20 | connection:write("ready\n") 21 | 22 | for path in connection:lines("*l") do 23 | local file = io.open(path) 24 | local html = file:read("*all") 25 | file:close() 26 | 27 | local success, document = pcall(xmlua.HTML.parse, html) 28 | if success then 29 | local title = document:search("//title")[1] 30 | if title then 31 | print(path .. ": " .. title:to_html()) 32 | else 33 | print(path .. ": no title") 34 | end 35 | else 36 | local message = document 37 | print(path .. ": Failed to parse: " .. message) 38 | end 39 | end 40 | end) 41 | -- Wait until require("xmlua") is finished 42 | connection:read("*l") 43 | table.insert(workers, worker) 44 | table.insert(connections, connection) 45 | end 46 | 47 | for i = 1, #arg do 48 | for _, connection in ipairs(connections) do 49 | connection:write(arg[i] .. "\n") 50 | end 51 | end 52 | 53 | for _, connection in ipairs(connections) do 54 | connection:close() 55 | end 56 | 57 | for _, worker in ipairs(workers) do 58 | worker:join() 59 | end 60 | 61 | -- You can call xmlua.cleanup in main thread to free all resources 62 | -- used by XMLua. You must ensure that all threads are finished and 63 | -- all XMLua related objects aren't used anymore. 64 | xmlua.cleanup() 65 | -------------------------------------------------------------------------------- /docs/_po/ja/install/index.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: PACKAGE VERSION\n" 4 | "Language: ja\n" 5 | "MIME-Version: 1.0\n" 6 | "Content-Type: text/plain; charset=UTF-8\n" 7 | "Content-Transfer-Encoding: 8bit\n" 8 | "Plural-Forms: nplurals=1; plural=0;\n" 9 | 10 | msgid "" 11 | "---\n" 12 | "title: Install\n" 13 | "---" 14 | msgstr "" 15 | "---\n" 16 | "title: インストール\n" 17 | "---" 18 | 19 | msgid "# Install" 20 | msgstr "# インストール" 21 | 22 | msgid "This document how to install XMLua on the following platforms:" 23 | msgstr "このドキュメントでは次のプラットフォーム上でXMLuaをインストールする方法を説明します。" 24 | 25 | msgid " * [Debian GNU/Linux](#debian)" 26 | msgstr "" 27 | 28 | msgid " * [Ubuntu](#ubuntu)" 29 | msgstr "" 30 | 31 | msgid " * [CentOS](#centos)" 32 | msgstr "" 33 | 34 | msgid " * [macOS](#macos)" 35 | msgstr "" 36 | 37 | msgid "" 38 | "You must install [LuaJIT][luajit] and [LuaRocks][luarocks] before installing X" 39 | "MLua." 40 | msgstr "XMLuaをインストールする前に[LuaJIT][luajit]と[LuaRocks][luarocks]をインストールしておいてください。" 41 | 42 | msgid "## Debian GNU/Linux {#debian}" 43 | msgstr "" 44 | 45 | msgid "" 46 | "```console\n" 47 | "% sudo apt install -y -V libxml2\n" 48 | "% sudo luarocks install xmlua\n" 49 | "```" 50 | msgstr "" 51 | 52 | msgid "## Ubuntu {#ubuntu}" 53 | msgstr "" 54 | 55 | msgid "## CentOS {#centos}" 56 | msgstr "" 57 | 58 | msgid "" 59 | "```console\n" 60 | "% sudo yum install -y libxml2\n" 61 | "% sudo luarocks install xmlua\n" 62 | "```" 63 | msgstr "" 64 | 65 | msgid "For CentOS 6 x86_64:" 66 | msgstr "CentOS 6 x86_64の場合:" 67 | 68 | msgid "" 69 | "```console\n" 70 | "% sudo yum install -y libxml2\n" 71 | "% sudo luarocks install xmlua LIBXML2_LIBDIR=/usr/lib64\n" 72 | "```" 73 | msgstr "" 74 | 75 | msgid "## macOS {#macos}" 76 | msgstr "" 77 | 78 | msgid "" 79 | "```console\n" 80 | "% brew install libxml2\n" 81 | "% sudo luarocks install xmlua\n" 82 | "```" 83 | msgstr "" 84 | 85 | msgid "[luajit]:http://luajit.org/" 86 | msgstr "" 87 | 88 | msgid "[luarocks]:https://luarocks.org/" 89 | msgstr "" 90 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | linux: 7 | name: Linux 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | os: 12 | - almalinux-8 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 5 15 | steps: 16 | - uses: actions/checkout@v6 17 | - name: Install XMLua 18 | run: | 19 | docker build \ 20 | -t clear-code/xmlua-${{ matrix.os }} \ 21 | -f dockerfiles/Dockerfile.${{ matrix.os }} \ 22 | . 23 | - name: Test 24 | run: | 25 | docker run \ 26 | clear-code/xmlua-${{ matrix.os }} 27 | macos: 28 | name: macOS 29 | strategy: 30 | fail-fast: false 31 | runs-on: macos-latest 32 | timeout-minutes: 5 33 | steps: 34 | - uses: actions/checkout@v6 35 | with: 36 | path: "xmlua" 37 | - uses: actions/checkout@v6 38 | with: 39 | repository: "clear-code/luacs" 40 | path: "luacs" 41 | - name: Install dependencies 42 | run: | 43 | cd xmlua 44 | brew bundle 45 | - name: Install XMLua 46 | run: | 47 | cd xmlua 48 | LUAROCKS="sudo -H luarocks --tree=$(brew --prefix) --lua-dir=$(brew --prefix luajit)" 49 | VERSION=$(grep VERSION xmlua.lua | sed -e 's/.*"\(.*\)"/\1/g') 50 | cp xmlua.rockspec xmlua-${VERSION}-0.rockspec 51 | ${LUAROCKS} make xmlua-${VERSION}-0.rockspec LIBXML2_DIR=$(brew --prefix libxml2) 52 | rm -rf xmlua.lua xmlua 53 | ${LUAROCKS} install luaunit 54 | ${LUAROCKS} install cqueues \ 55 | CRYPTO_DIR=$(brew --prefix openssl) \ 56 | OPENSSL_DIR=$(brew --prefix openssl) 57 | - name: Test 58 | run: | 59 | cd xmlua 60 | test/run-test.lua 61 | luajit -e 'package.path = "../luacs/?.lua;" .. package.path' \ 62 | sample/parse-html-cqueues-thread.lua sample/sample.html 63 | -------------------------------------------------------------------------------- /docs/_includes/navbar-content.ja.html: -------------------------------------------------------------------------------- 1 | 15 | 51 | -------------------------------------------------------------------------------- /docs/_includes/navbar-content.en.html: -------------------------------------------------------------------------------- 1 | 15 | 51 | -------------------------------------------------------------------------------- /docs/reference/text.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.Text 3 | --- 4 | 5 | # `xmlua.Text` class 6 | 7 | ## Summary 8 | 9 | It's a class for text node. You can get text object by [`xmlua.Searchable:search`][searchable-search] and [`xmlua.NodeSet`][node-set]'s `[]`. 10 | 11 | Example: 12 | 13 | ```lua 14 | local xmlua = require("xmlua") 15 | 16 | local document = xmlua.XML.parse("This is text") 17 | 18 | document:search("/root/text()")[1] -- -> xmlua.Text 19 | ``` 20 | 21 | ## Instance methods 22 | 23 | ### `concat(content) -> boolean` {#concat} 24 | 25 | Concat the given content of argument at the end of the existing node. 26 | It returns the success or failure of the concatenation as a boolean. 27 | `true` is a success of concatenating. `false` is concatenate failure. 28 | 29 | Example: 30 | 31 | ```lua 32 | local document = 33 | xmlua.XML.build({"root", {}, "Text1"}) 34 | local text_nodes = document:search("/root/text()") 35 | text_nodes[1]:concat("Text2") 36 | print(document:to_xml()) 37 | -- 38 | --Text1Text2 39 | end 40 | ``` 41 | 42 | ### `merge(content) -> boolean` {#concat} 43 | 44 | Merge receiver and content of argument into one text node. 45 | It returns the success or failure of the merge as a boolean. 46 | `true` is a success of merge. `false` is merge failure. 47 | 48 | Example: 49 | 50 | ```lua 51 | local document = xmlua.XML.parse([[ 52 | 53 | Text: 54 | This is child 55 | 56 | ]]) 57 | local text1 = document:search("/root/text()") 58 | local text2 = document:search("/root/child/text()") 59 | 60 | text1[1]:merge(text2[1]) 61 | print(document:to_xml()) 62 | -- 63 | -- 64 | -- Text: 65 | -- This is child 66 | -- 67 | ``` 68 | 69 | ## See also 70 | 71 | * [`xmlua.NodeSet`][node-set]: The class for multiple nodes. 72 | 73 | * [`xmlua.Searchable`][searchable]: Provides node search related methods. 74 | 75 | 76 | [node-set]:node-set.html 77 | 78 | [searchable-search]:searchable.html#search 79 | 80 | [searchable]:searchable.html 81 | -------------------------------------------------------------------------------- /docs/assets/javascripts/bootstrap/transition.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: transition.js v3.3.5 3 | * http://getbootstrap.com/javascript/#transitions 4 | * ======================================================================== 5 | * Copyright 2011-2015 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) 14 | // ============================================================ 15 | 16 | function transitionEnd() { 17 | var el = document.createElement('bootstrap') 18 | 19 | var transEndEventNames = { 20 | WebkitTransition : 'webkitTransitionEnd', 21 | MozTransition : 'transitionend', 22 | OTransition : 'oTransitionEnd otransitionend', 23 | transition : 'transitionend' 24 | } 25 | 26 | for (var name in transEndEventNames) { 27 | if (el.style[name] !== undefined) { 28 | return { end: transEndEventNames[name] } 29 | } 30 | } 31 | 32 | return false // explicit for ie8 ( ._.) 33 | } 34 | 35 | // http://blog.alexmaccaw.com/css-transitions 36 | $.fn.emulateTransitionEnd = function (duration) { 37 | var called = false 38 | var $el = this 39 | $(this).one('bsTransitionEnd', function () { called = true }) 40 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) } 41 | setTimeout(callback, duration) 42 | return this 43 | } 44 | 45 | $(function () { 46 | $.support.transition = transitionEnd() 47 | 48 | if (!$.support.transition) return 49 | 50 | $.event.special.bsTransitionEnd = { 51 | bindType: $.support.transition.end, 52 | delegateType: $.support.transition.end, 53 | handle: function (e) { 54 | if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 55 | } 56 | } 57 | }) 58 | 59 | }(jQuery); 60 | -------------------------------------------------------------------------------- /docs/_po/ja/reference/cdata-section.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: PACKAGE VERSION\n" 4 | "Language: ja\n" 5 | "MIME-Version: 1.0\n" 6 | "Content-Type: text/plain; charset=UTF-8\n" 7 | "Content-Transfer-Encoding: 8bit\n" 8 | "Plural-Forms: nplurals=1; plural=0;\n" 9 | 10 | msgid "" 11 | "---\n" 12 | "title: xmlua.CDATASection\n" 13 | "---" 14 | msgstr "" 15 | 16 | msgid "# `xmlua.CDATASection` class" 17 | msgstr "# `xmlua.CDATASection` クラス" 18 | 19 | msgid "## Summary" 20 | msgstr "## 概要" 21 | 22 | msgid "" 23 | "It's a class for cdata section node. Normaly, you can get cdata section object" 24 | " by [`xmlua.Document:create_cdata_section`][create-cdata-section]." 25 | msgstr "" 26 | "cdata sectionノード用のクラスです。通常、[`xmlua.Document:create_cdata_section`][create-cdat" 27 | "a-section]を使用して取得できます。" 28 | 29 | msgid "Example:" 30 | msgstr "例:" 31 | 32 | msgid "" 33 | "```lua\n" 34 | "local xmlua = require(\"xmlua\")" 35 | msgstr "" 36 | 37 | msgid "" 38 | "local document = xmlua.XML.build({\"root\"})\n" 39 | "local cdata_section_node = -- -> xmlua.CDATASection\n" 40 | " document:create_cdata_section(\"This is \")\n" 41 | "```" 42 | msgstr "" 43 | 44 | msgid "It has methods of the following modules:" 45 | msgstr "このクラスのオブジェクトは以下のモジュールのメソッドを使えます。" 46 | 47 | msgid " * [`xmlua.Node`][node]: Provides common methods of each nodes." 48 | msgstr " * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。" 49 | 50 | msgid "It means that you can use methods in the modules." 51 | msgstr "つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。" 52 | 53 | msgid "## Instance methods" 54 | msgstr "## インスタンスメソッド" 55 | 56 | msgid "There are no methods specific to this class." 57 | msgstr "このクラス特有のメソッドはありません。" 58 | 59 | msgid "## See also" 60 | msgstr "## 参照" 61 | 62 | msgid "" 63 | " * [`xmlua.Document`][document]: The class for HTML document and XML document" 64 | "." 65 | msgstr " * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。" 66 | 67 | msgid "[create-cdata-section]:document.html#cdata-section.html" 68 | msgstr "" 69 | 70 | msgid "[document]:document.html" 71 | msgstr "" 72 | 73 | msgid "[node]:node.html" 74 | msgstr "" 75 | -------------------------------------------------------------------------------- /sample/document-add-entity.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | -- Add a new entity to document 6 | local xml = [[ 7 | 8 | 10 | 11 | &Sample; 12 | 13 | ]] 14 | 15 | local parser = xmlua.XMLSAXParser.new() 16 | local is_root = true 17 | parser.start_element = function() 18 | if not is_root then 19 | return 20 | end 21 | 22 | local document = parser.document 23 | -- Setting information for add a entity 24 | local entity = { 25 | name = "Sample", 26 | -- Entity type list 27 | -- INTERNAL_ENTITY 28 | -- EXTERNAL_PARSED_ENTITY 29 | -- EXTERNAL_UNPARSED_ENTITY 30 | -- INTERNAL_PARAMETER_ENTITY 31 | -- EXTERNAL_PARAMETER_ENTITY 32 | -- INTERNAL_PREDEFINED_ENTITY 33 | entity_type = "INTERNAL_ENTITY", 34 | content = "This is test." 35 | } 36 | document:add_entity(entity) 37 | is_root = false 38 | end 39 | parser.text = function(text) 40 | print(text) -- This is test. 41 | end 42 | 43 | parser:parse(xml) 44 | 45 | 46 | -- Add a new entity to document DTD external subset 47 | local xml = [[ 48 | 49 | 50 | 51 | &Sample; 52 | 53 | ]] 54 | 55 | local options = {load_dtd = true} 56 | local parser = xmlua.XMLSAXParser.new(options) 57 | local is_root = true 58 | parser.start_element = function() 59 | if not is_root then 60 | return 61 | end 62 | 63 | local document = parser.document 64 | -- Setting information for add entity 65 | local entity = { 66 | name = "Sample", 67 | -- Entity type list 68 | -- INTERNAL_ENTITY 69 | -- EXTERNAL_PARSED_ENTITY 70 | -- EXTERNAL_UNPARSED_ENTITY 71 | -- INTERNAL_PARAMETER_ENTITY 72 | -- EXTERNAL_PARAMETER_ENTITY 73 | -- INTERNAL_PREDEFINED_ENTITY 74 | entity_type = "INTERNAL_ENTITY", 75 | content = "This is test." 76 | } 77 | document:add_dtd_entity(entity) 78 | is_root = false 79 | end 80 | parser.text = function(text) 81 | print(text) -- This is test. 82 | end 83 | parser:parse(xml) 84 | 85 | -------------------------------------------------------------------------------- /docs/_layouts/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% if page.description %} 5 | {% assign description = page.description %} 6 | {% else %} 7 | {% capture description %}{% include site-description.html %}{% endcapture %} 8 | {% endif %} 9 | 10 | {% capture title %}{% if page.title == "none" %}{{ site.title }} - {{ description }}{% else %}{{ page.title }} | {{ site.title }}{% endif %}{% endcapture %} 11 | {% capture relative_path %}{{ page.url | remove_first: page.path_prefix | remove: "index.html" }}{% endcapture %} 12 | 13 | 14 | 15 | 16 | 17 | {% if page.redirect %} 18 | 19 | {% endif %} 20 | 21 | 25 | 26 | {{ title }} 27 | 30 | 33 | 34 | 35 | 36 | 37 | 42 | 43 |
44 | {{ content }} 45 |
46 | 47 |
48 |
49 |
50 | {% include contribute.html %} 51 | 52 |
53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /sample/xml-build.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local tree 6 | local document 7 | 8 | -- Empty tree 9 | tree = {} 10 | document = xmlua.XML.build(tree) 11 | print(document:to_xml()) 12 | -- 13 | 14 | -- Root only document 15 | tree = {"root"} 16 | document = xmlua.XML.build(tree) 17 | print(document:to_xml()) 18 | -- 19 | -- 20 | 21 | -- Root with attributes 22 | tree = { 23 | "root", 24 | { 25 | attribute1 = "value1", 26 | attribute2 = "value2", 27 | }, 28 | } 29 | document = xmlua.XML.build(tree) 30 | print(document:to_xml()) 31 | -- 32 | -- 33 | 34 | -- Root with namespaces 35 | tree = { 36 | "example:root", 37 | { 38 | ["xmlns:example"] = "http://example.com/", 39 | ["example:attribute"] = "with-namespace", 40 | ["attribute"] = "without-namespace", 41 | }, 42 | } 43 | document = xmlua.XML.build(tree) 44 | print(document:to_xml()) 45 | -- (Indented manually for readability) 46 | -- 47 | -- 48 | -- 52 | 53 | -- Child elements 54 | tree = { 55 | "root", 56 | {}, 57 | { 58 | "child", 59 | { 60 | attribute = "child-value", 61 | }, 62 | }, 63 | } 64 | document = xmlua.XML.build(tree) 65 | print(document:to_xml()) 66 | -- 67 | -- 68 | -- 69 | -- 70 | 71 | -- Child elements 72 | tree = { 73 | "root", 74 | {}, 75 | "root text1", 76 | { 77 | "child", 78 | { 79 | attribute = "child-value", 80 | }, 81 | "child-text", 82 | }, 83 | "root text2", 84 | } 85 | document = xmlua.XML.build(tree) 86 | print(document:to_xml()) 87 | -- (Indented manually for readability) 88 | -- 89 | -- 90 | -- 91 | -- root text1 92 | -- 93 | -- child-text 94 | -- 95 | -- root text2 96 | -- 97 | -------------------------------------------------------------------------------- /docs/ja/reference/document-type.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.DocumentType 3 | --- 4 | 5 | # `xmlua.DocumentType` クラス 6 | 7 | ## 概要 8 | 9 | ドキュメントタイプノード用のクラスです。 10 | 11 | 通常、[`xmlua.Document:create_document_type`][create-document-type]を使って取得します。 12 | 13 | 例: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.DocumentType 20 | document:create_document_type() 21 | ``` 22 | 23 | このクラスのオブジェクトは以下のモジュールのメソッドを使えます。 24 | 25 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 26 | 27 | つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。 28 | 29 | ## インスタンスメソッド 30 | 31 | ### `name() -> string` {#name} 32 | 33 | ルート要素名を `string` として返します。 34 | 35 | 例: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({}) 41 | local document_type = 42 | document:create_document_type("root", 43 | "-//test//This is test//EN" 44 | "//sample.dtd") 45 | print(document_type:name()) 46 | -- root 47 | ``` 48 | 49 | ### `external_id() -> string` {#external_id} 50 | 51 | 外部サブセットの公開識別子を返します。 52 | 53 | 例: 54 | 55 | ```lua 56 | local xmlua = require("xmlua") 57 | 58 | local document = xmlua.XML.build({}) 59 | local document_type = 60 | document:create_document_type("root", 61 | "-//test//This is test//EN" 62 | "//sample.dtd") 63 | print(document_type:external_id()) 64 | -- -//test//This is test//EN 65 | ``` 66 | 67 | ### `system_id() -> string` {#system_id} 68 | 69 | 外部ファイル名を `string` として返します。 70 | 71 | 例: 72 | 73 | ```lua 74 | local xmlua = require("xmlua") 75 | 76 | local document = xmlua.XML.build({}) 77 | local document_type = 78 | document:create_document_type("root", 79 | "-//test//This is test//EN" 80 | "//sample.dtd") 81 | print(document_type:system_id()) 82 | -- //sample.dtd 83 | ``` 84 | 85 | ## 参照 86 | 87 | * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。 88 | 89 | * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。 90 | 91 | 92 | [create-document-type]:document.html#create-document-type 93 | 94 | [document]:document.html 95 | 96 | [node]:node.html 97 | -------------------------------------------------------------------------------- /docs/_po/ja/reference/document-fragment.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: PACKAGE VERSION\n" 4 | "Language: ja\n" 5 | "MIME-Version: 1.0\n" 6 | "Content-Type: text/plain; charset=UTF-8\n" 7 | "Content-Transfer-Encoding: 8bit\n" 8 | "Plural-Forms: nplurals=1; plural=0;\n" 9 | 10 | msgid "" 11 | "---\n" 12 | "title: xmlua.DocumentFragment\n" 13 | "---" 14 | msgstr "" 15 | 16 | msgid "# `xmlua.DocumentFragment` class" 17 | msgstr "# `xmlua.DocumentFragment` クラス" 18 | 19 | msgid "## Summary" 20 | msgstr "## 概要" 21 | 22 | msgid "It's a class for document fragment node." 23 | msgstr "ドキュメントフラグメントノード用のクラスです。" 24 | 25 | msgid "" 26 | "Normaly, you can get document fragment object by [`xmlua.Document:create_docum" 27 | "ent_fragment`][create-document-fragment]." 28 | msgstr "" 29 | "通常、[`xmlua.Document:create_document_fragment`][create-document-fragment]を使用して取" 30 | "得します。" 31 | 32 | msgid "Example:" 33 | msgstr "例:" 34 | 35 | msgid "" 36 | "```lua\n" 37 | "local xmlua = require(\"xmlua\")" 38 | msgstr "" 39 | 40 | msgid "" 41 | "local document = xmlua.XML.build({\"root\"})\n" 42 | "local document_fragment_node = -- -> xmlua.DocumentFragment\n" 43 | " document:create_document_fragment()\n" 44 | "```" 45 | msgstr "" 46 | 47 | msgid "It has methods of the following modules:" 48 | msgstr "このクラスのオブジェクトは以下のモジュールのメソッドを使えます。" 49 | 50 | msgid " * [`xmlua.Node`][node]: Provides common methods of each nodes." 51 | msgstr " * [`xmlua.Node`][node]: それぞれのノードに共通のメソッドを提供します。" 52 | 53 | msgid " * [`xmlua.Element`][element]: The class for element node." 54 | msgstr " * [`xmlua.Element`][element]: 要素ノード用のクラスです。" 55 | 56 | msgid "It means that you can use methods in the modules." 57 | msgstr "つまり、このクラスのオブジェクトで上述のモジュールのメソッドを使えます。" 58 | 59 | msgid "## Instance methods" 60 | msgstr "## インスタンスメソッド" 61 | 62 | msgid "There are no methods specific to this class." 63 | msgstr "このクラス特有のメソッドはありません。" 64 | 65 | msgid "## See also" 66 | msgstr "## 参照" 67 | 68 | msgid "" 69 | " * [`xmlua.Document`][document]: The class for HTML document and XML document" 70 | "." 71 | msgstr " * [`xmlua.Document`][document]: HTMLドキュメントとXMLドキュメント用のクラスです。" 72 | 73 | msgid "[create-document-fragment]:document.html#document-fragment.html" 74 | msgstr "" 75 | 76 | msgid "[document]:document.html" 77 | msgstr "" 78 | 79 | msgid "[node]:node.html" 80 | msgstr "" 81 | 82 | msgid "[element]:element.html" 83 | msgstr "" 84 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_progress-bars.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Progress bars 3 | // -------------------------------------------------- 4 | 5 | 6 | // Bar animations 7 | // ------------------------- 8 | 9 | // WebKit 10 | @-webkit-keyframes progress-bar-stripes { 11 | from { background-position: 40px 0; } 12 | to { background-position: 0 0; } 13 | } 14 | 15 | // Spec and IE10+ 16 | @keyframes progress-bar-stripes { 17 | from { background-position: 40px 0; } 18 | to { background-position: 0 0; } 19 | } 20 | 21 | 22 | // Bar itself 23 | // ------------------------- 24 | 25 | // Outer container 26 | .progress { 27 | overflow: hidden; 28 | height: $line-height-computed; 29 | margin-bottom: $line-height-computed; 30 | background-color: $progress-bg; 31 | border-radius: $progress-border-radius; 32 | @include box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); 33 | } 34 | 35 | // Bar of progress 36 | .progress-bar { 37 | float: left; 38 | width: 0%; 39 | height: 100%; 40 | font-size: $font-size-small; 41 | line-height: $line-height-computed; 42 | color: $progress-bar-color; 43 | text-align: center; 44 | background-color: $progress-bar-bg; 45 | @include box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); 46 | @include transition(width .6s ease); 47 | } 48 | 49 | // Striped bars 50 | // 51 | // `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the 52 | // `.progress-bar-striped` class, which you just add to an existing 53 | // `.progress-bar`. 54 | .progress-striped .progress-bar, 55 | .progress-bar-striped { 56 | @include gradient-striped; 57 | background-size: 40px 40px; 58 | } 59 | 60 | // Call animation for the active one 61 | // 62 | // `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the 63 | // `.progress-bar.active` approach. 64 | .progress.active .progress-bar, 65 | .progress-bar.active { 66 | @include animation(progress-bar-stripes 2s linear infinite); 67 | } 68 | 69 | 70 | // Variations 71 | // ------------------------- 72 | 73 | .progress-bar-success { 74 | @include progress-bar-variant($progress-bar-success-bg); 75 | } 76 | 77 | .progress-bar-info { 78 | @include progress-bar-variant($progress-bar-info-bg); 79 | } 80 | 81 | .progress-bar-warning { 82 | @include progress-bar-variant($progress-bar-warning-bg); 83 | } 84 | 85 | .progress-bar-danger { 86 | @include progress-bar-variant($progress-bar-danger-bg); 87 | } 88 | -------------------------------------------------------------------------------- /sample/html-build.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env luajit 2 | 3 | local xmlua = require("xmlua") 4 | 5 | local tree 6 | local document 7 | 8 | -- Empty tree 9 | tree = {} 10 | document = xmlua.HTML.build(tree) 11 | print(document:to_html()) 12 | -- 13 | 14 | -- Root only document 15 | tree = {"html"} 16 | document = xmlua.HTML.build(tree) 17 | print(document:to_html()) 18 | -- 19 | -- 20 | 21 | -- Root with attributes 22 | tree = { 23 | "html", 24 | { 25 | attribute1 = "value1", 26 | attribute2 = "value2", 27 | }, 28 | } 29 | document = xmlua.HTML.build(tree) 30 | print(document:to_html()) 31 | -- 32 | -- 33 | 34 | -- Specify external subset with system id 35 | local uri = "file:///usr/local/share/test.dtd" 36 | tree = {"html"} 37 | document = xmlua.HTML.build(tree, uri) 38 | print(document:to_html()) 39 | -- 40 | -- 41 | 42 | -- Specify external subset with public id 43 | local uri = "http://www.w3.org/TR/html4/strict.dtd" 44 | local public_id = "-//W3C//DTD HTML 4.01//EN" 45 | tree = {"html"} 46 | document = xmlua.HTML.build(tree, uri, public_id) 47 | print(document:to_html()) 48 | -- 49 | -- 50 | 51 | -- Child elements 52 | tree = { 53 | "html", 54 | {}, 55 | { 56 | "child", 57 | { 58 | attribute = "child-value", 59 | }, 60 | }, 61 | } 62 | document = xmlua.HTML.build(tree) 63 | print(document:to_html()) 64 | -- 65 | -- 66 | -- 67 | -- 68 | 69 | -- Child elements 70 | tree = { 71 | "html", 72 | {}, 73 | { 74 | "title", 75 | {}, 76 | "title-text", 77 | }, 78 | } 79 | document = xmlua.HTML.build(tree) 80 | print(document:to_html()) 81 | -- 82 | -- 83 | -- title-text 84 | -- 85 | -------------------------------------------------------------------------------- /docs/reference/document-type.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: xmlua.DocumentType 3 | --- 4 | 5 | # `xmlua.DocumentType` class 6 | 7 | ## Summary 8 | 9 | It's a class for document type node. 10 | 11 | Normaly, you can get document type object by [`xmlua.Document:create_document_type`][create-document-type]. 12 | 13 | Example: 14 | 15 | ```lua 16 | local xmlua = require("xmlua") 17 | 18 | local document = xmlua.XML.build({"root"}) 19 | local document_type = -- -> xmlua.DocumentType 20 | document:create_document_type() 21 | ``` 22 | 23 | It has methods of the following modules: 24 | 25 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 26 | 27 | It means that you can use methods in the modules. 28 | 29 | ## Instance methods 30 | 31 | ### `name() -> string` {#name} 32 | 33 | It returns name of the root element as `string`. 34 | 35 | Example: 36 | 37 | ```lua 38 | local xmlua = require("xmlua") 39 | 40 | local document = xmlua.XML.build({}) 41 | local document_type = 42 | document:create_document_type("root", 43 | "-//test//This is test//EN" 44 | "//sample.dtd") 45 | print(document_type:name()) 46 | -- root 47 | ``` 48 | 49 | ### `external_id() -> string` {#external_id} 50 | 51 | It returns public id of external subset as `string`. 52 | 53 | Example: 54 | 55 | ```lua 56 | local xmlua = require("xmlua") 57 | 58 | local document = xmlua.XML.build({}) 59 | local document_type = 60 | document:create_document_type("root", 61 | "-//test//This is test//EN" 62 | "//sample.dtd") 63 | print(document_type:external_id()) 64 | -- -//test//This is test//EN 65 | ``` 66 | 67 | ### `system_id() -> string` {#system_id} 68 | 69 | It returns of external file name as `string`. 70 | 71 | Example: 72 | 73 | ```lua 74 | local xmlua = require("xmlua") 75 | 76 | local document = xmlua.XML.build({}) 77 | local document_type = 78 | document:create_document_type("root", 79 | "-//test//This is test//EN" 80 | "//sample.dtd") 81 | print(document_type:system_id()) 82 | -- //sample.dtd 83 | ``` 84 | 85 | ## See also 86 | 87 | * [`xmlua.Document`][document]: The class for HTML document and XML document. 88 | 89 | * [`xmlua.Node`][node]: Provides common methods of each nodes. 90 | 91 | 92 | [create-document-type]:document.html#create-document-type 93 | 94 | [document]:document.html 95 | 96 | [node]:node.html 97 | -------------------------------------------------------------------------------- /xmlua/libxml2/entities.lua: -------------------------------------------------------------------------------- 1 | local ffi = require("ffi") 2 | 3 | ffi.cdef[[ 4 | /* 5 | * The different valid entity types. 6 | */ 7 | typedef enum { 8 | XML_INTERNAL_GENERAL_ENTITY = 1, 9 | XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2, 10 | XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3, 11 | XML_INTERNAL_PARAMETER_ENTITY = 4, 12 | XML_EXTERNAL_PARAMETER_ENTITY = 5, 13 | XML_INTERNAL_PREDEFINED_ENTITY = 6 14 | } xmlEntityType; 15 | 16 | struct _xmlEntity { 17 | void *_private; /* application data */ 18 | xmlElementType type; /* XML_ENTITY_DECL, must be second ! */ 19 | const xmlChar *name; /* Entity name */ 20 | struct _xmlNode *children; /* First child link */ 21 | struct _xmlNode *last; /* Last child link */ 22 | struct _xmlDtd *parent; /* -> DTD */ 23 | struct _xmlNode *next; /* next sibling link */ 24 | struct _xmlNode *prev; /* previous sibling link */ 25 | struct _xmlDoc *doc; /* the containing document */ 26 | 27 | xmlChar *orig; /* content without ref substitution */ 28 | xmlChar *content; /* content or ndata if unparsed */ 29 | int length; /* the content length */ 30 | xmlEntityType etype; /* The entity type */ 31 | const xmlChar *ExternalID; /* External identifier for PUBLIC */ 32 | const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */ 33 | 34 | struct _xmlEntity *nexte; /* unused */ 35 | const xmlChar *URI; /* the full URI as computed */ 36 | int owner; /* does the entity own the childrens */ 37 | int checked; /* was the entity content checked */ 38 | /* this is also used to count entities 39 | * references done from that entity 40 | * and if it contains '<' */ 41 | }; 42 | 43 | 44 | xmlEntityPtr xmlAddDocEntity(xmlDocPtr doc, 45 | const xmlChar *name, 46 | int type, 47 | const xmlChar *ExternalID, 48 | const xmlChar *SystemID, 49 | const xmlChar *content); 50 | xmlEntityPtr xmlAddDtdEntity(xmlDocPtr doc, 51 | const xmlChar *name, 52 | int type, 53 | const xmlChar *ExternalID, 54 | const xmlChar *SystemID, 55 | const xmlChar *content); 56 | xmlEntityPtr xmlGetDocEntity(const xmlDoc *doc, 57 | const xmlChar *name); 58 | xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, 59 | const xmlChar *name); 60 | ]] 61 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_pagination.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Pagination (multiple pages) 3 | // -------------------------------------------------- 4 | .pagination { 5 | display: inline-block; 6 | padding-left: 0; 7 | margin: $line-height-computed 0; 8 | border-radius: $border-radius-base; 9 | 10 | > li { 11 | display: inline; // Remove list-style and block-level defaults 12 | > a, 13 | > span { 14 | position: relative; 15 | float: left; // Collapse white-space 16 | padding: $padding-base-vertical $padding-base-horizontal; 17 | line-height: $line-height-base; 18 | text-decoration: none; 19 | color: $pagination-color; 20 | background-color: $pagination-bg; 21 | border: 1px solid $pagination-border; 22 | margin-left: -1px; 23 | } 24 | &:first-child { 25 | > a, 26 | > span { 27 | margin-left: 0; 28 | @include border-left-radius($border-radius-base); 29 | } 30 | } 31 | &:last-child { 32 | > a, 33 | > span { 34 | @include border-right-radius($border-radius-base); 35 | } 36 | } 37 | } 38 | 39 | > li > a, 40 | > li > span { 41 | &:hover, 42 | &:focus { 43 | z-index: 3; 44 | color: $pagination-hover-color; 45 | background-color: $pagination-hover-bg; 46 | border-color: $pagination-hover-border; 47 | } 48 | } 49 | 50 | > .active > a, 51 | > .active > span { 52 | &, 53 | &:hover, 54 | &:focus { 55 | z-index: 2; 56 | color: $pagination-active-color; 57 | background-color: $pagination-active-bg; 58 | border-color: $pagination-active-border; 59 | cursor: default; 60 | } 61 | } 62 | 63 | > .disabled { 64 | > span, 65 | > span:hover, 66 | > span:focus, 67 | > a, 68 | > a:hover, 69 | > a:focus { 70 | color: $pagination-disabled-color; 71 | background-color: $pagination-disabled-bg; 72 | border-color: $pagination-disabled-border; 73 | cursor: $cursor-disabled; 74 | } 75 | } 76 | } 77 | 78 | // Sizing 79 | // -------------------------------------------------- 80 | 81 | // Large 82 | .pagination-lg { 83 | @include pagination-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $border-radius-large); 84 | } 85 | 86 | // Small 87 | .pagination-sm { 88 | @include pagination-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $border-radius-small); 89 | } 90 | -------------------------------------------------------------------------------- /docs/assets/stylesheets/bootstrap/_print.scss: -------------------------------------------------------------------------------- 1 | /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ 2 | 3 | // ========================================================================== 4 | // Print styles. 5 | // Inlined to avoid the additional HTTP request: h5bp.com/r 6 | // ========================================================================== 7 | 8 | @media print { 9 | *, 10 | *:before, 11 | *:after { 12 | background: transparent !important; 13 | color: #000 !important; // Black prints faster: h5bp.com/s 14 | box-shadow: none !important; 15 | text-shadow: none !important; 16 | } 17 | 18 | a, 19 | a:visited { 20 | text-decoration: underline; 21 | } 22 | 23 | a[href]:after { 24 | content: " (" attr(href) ")"; 25 | } 26 | 27 | abbr[title]:after { 28 | content: " (" attr(title) ")"; 29 | } 30 | 31 | // Don't show links that are fragment identifiers, 32 | // or use the `javascript:` pseudo protocol 33 | a[href^="#"]:after, 34 | a[href^="javascript:"]:after { 35 | content: ""; 36 | } 37 | 38 | pre, 39 | blockquote { 40 | border: 1px solid #999; 41 | page-break-inside: avoid; 42 | } 43 | 44 | thead { 45 | display: table-header-group; // h5bp.com/t 46 | } 47 | 48 | tr, 49 | img { 50 | page-break-inside: avoid; 51 | } 52 | 53 | img { 54 | max-width: 100% !important; 55 | } 56 | 57 | p, 58 | h2, 59 | h3 { 60 | orphans: 3; 61 | widows: 3; 62 | } 63 | 64 | h2, 65 | h3 { 66 | page-break-after: avoid; 67 | } 68 | 69 | // Bootstrap specific changes start 70 | 71 | // Bootstrap components 72 | .navbar { 73 | display: none; 74 | } 75 | .btn, 76 | .dropup > .btn { 77 | > .caret { 78 | border-top-color: #000 !important; 79 | } 80 | } 81 | .label { 82 | border: 1px solid #000; 83 | } 84 | 85 | .table { 86 | border-collapse: collapse !important; 87 | 88 | td, 89 | th { 90 | background-color: #fff !important; 91 | } 92 | } 93 | .table-bordered { 94 | th, 95 | td { 96 | border: 1px solid #ddd !important; 97 | } 98 | } 99 | 100 | // Bootstrap specific changes end 101 | } 102 | -------------------------------------------------------------------------------- /xmlua/html.lua: -------------------------------------------------------------------------------- 1 | local HTML = {} 2 | 3 | local libxml2 = require("xmlua.libxml2") 4 | local ffi = require("ffi") 5 | 6 | local Document = require("xmlua.document") 7 | 8 | local function convert_xml_error(xml_error) 9 | local err = { 10 | domain = xml_error.domain, 11 | code = xml_error.code, 12 | message = ffi.string(xml_error.message), 13 | level = tonumber(xml_error.level), 14 | } 15 | if xml_error.file == ffi.NULL then 16 | err.file = nil 17 | else 18 | err.file = ffi.string(xml_error.file) 19 | end 20 | err.line = xml_error.line 21 | return err 22 | end 23 | 24 | function HTML.build(tree, uri, external_id) 25 | local raw_document = libxml2.htmlNewDoc(uri, external_id) 26 | return Document.build(raw_document, tree) 27 | end 28 | 29 | function HTML.parse(html, options) 30 | local context = libxml2.htmlNewParserCtxt() 31 | if not context then 32 | error("Failed to create context to parse HTML") 33 | end 34 | 35 | local errors = {} 36 | local error_callback = function(user_data, xml_error) 37 | table.insert(errors, convert_xml_error(xml_error)) 38 | end 39 | local c_error_callback = ffi.cast("xmlStructuredErrorFunc", error_callback) 40 | context.sax.initialized = libxml2.XML_SAX2_MAGIC 41 | context.sax.serror = c_error_callback 42 | local raw_document = libxml2.htmlCtxtReadMemory(context, html, options) 43 | c_error_callback:free() 44 | context.sax.serror = nil 45 | if raw_document == ffi.NULL then 46 | if context.lastError.message == ffi.NULL then 47 | error("Failed to parse HTML") 48 | else 49 | error("Failed to parse HTML: " .. ffi.string(context.lastError.message)) 50 | end 51 | end 52 | local document = Document.new(raw_document, errors) 53 | 54 | local prefer_meta_charset = true 55 | if options then 56 | if options["encoding"] then 57 | prefer_meta_charset = false 58 | else 59 | prefer_meta_charset = options["prefer_meta_charset"] 60 | if prefer_meta_charset == nil then 61 | prefer_meta_charset = true 62 | end 63 | end 64 | end 65 | if prefer_meta_charset then 66 | -- TODO: Workaround for issue that 67 | -- libxml2 doesn't support yet. 68 | -- We should feedback it to libxml2. 69 | local meta_charsets = document:search("//meta[@charset]") 70 | if #meta_charsets > 0 then 71 | local new_options = {encoding = meta_charsets[1].charset} 72 | if options then 73 | new_options.url = options.url 74 | end 75 | return HTML.parse(html, new_options) 76 | end 77 | end 78 | 79 | return document 80 | end 81 | 82 | return HTML 83 | --------------------------------------------------------------------------------