-- lx-bundle:true

-- This file is part of Lx, created by Liqube <www.liqube.com>
-- Copyright Liqube Audio. All rights reserved.
-- Lx Interim License. See LICENSE for details.

--- Shared Office Open XML helpers
-- @module plugins.msoutils.ooxml

local ooxml = {}

--- Return whether one codepoint is allowed in XML 1.0 text
-- @param value number Unicode codepoint
-- @return boolean valid
local function is_valid_xml_character(value)
	return value == 0x09
		or value == 0x0A
		or value == 0x0D
		or value >= 0x20 and value <= 0xD7FF
		or value >= 0xE000 and value <= 0xFFFD
		or value >= 0x10000 and value <= 0x10FFFF
end

--- Reject text that XML 1.0 does not permit
-- @param text string decoded XML text
-- @param message string error text
-- @return string text unchanged valid text
function ooxml.validate_text(text, message)
	if not utf8.len(text) then
		error(message, 0)
	end

	for _, value in utf8.codes(text) do
		if not is_valid_xml_character(value) then
			error(message, 0)
		end
	end

	return text
end

--- Walk sibling XML nodes with an optional qualified-name filter
-- @param parent userdata|nil XML parent node
-- @param name string|nil qualified child name
-- @return function iterator child iterator
function ooxml.child_nodes(parent, name)
	local next_node = parent and parent:first_child(name) or nil

	return function()
		local node = next_node
		if node then
			next_node = node:next_sibling(name)
		end

		return node
	end
end

return ooxml
