Source code for cioxml.lib.cioset

"""Cioset management."""

from re import sub as re_sub

from lxml import etree

from chrysalio.lib.utils import normalize_spaces, make_id
from cioprocessor.relaxng import RELAXNG_CIOSET
from .utils import special_unprotect


# =============================================================================
[docs]def cioset_update(original, values): """Update original Cioset XML according to values. :type original: lxml.etree._ElementTree :param original: Initial content of the file as a XML DOM object. :param dict values: Values of the form. :rtype: lxml.etree._ElementTree """ # Title value = normalize_spaces(values['cioset_title'].replace(' ', '‧')) title_elt = original.find( '{{{0}}}title'.format(RELAXNG_CIOSET['namespace'])) if not value and title_elt is not None: original.getroot().remove(title_elt) elif value: if title_elt is None: title_elt = etree.Element('title') original.getroot().insert(0, title_elt) title_elt.text = value # Division namespaces = {'set': RELAXNG_CIOSET['namespace']} for elt in original.xpath('//set:division', namespaces=namespaces): num = int(elt.xpath( 'count(preceding::set:division|ancestor::set:division)', namespaces=namespaces)) _update_title(values, 'division{0}'.format(num), elt) # Resources, copies and values for tag in ('resources', 'copies', 'values'): for num, elt in enumerate(original.xpath( '//set:{0}'.format(tag), namespaces=namespaces)): _update_title(values, '{0}{1}'.format(tag, num), elt) value = make_id( values.get('cioset_{0}{1}_for'.format(tag, num), ''), 'class') if value: elt.set('for', value) else: elt.attrib.pop('for', None) # Defines and values for tag in ('define', 'value'): for num, elt in enumerate(original.xpath( '//set:{0}'.format(tag), namespaces=namespaces)): elt.text = value2string( elt, values.get('cioset_{0}{1}'.format(tag, num))) return etree.ElementTree(etree.fromstring(re_sub( r'<file>\s+<path>([^<]+)</path>\s+</file>', r'<file><path>\1</path></file>', special_unprotect(etree.tostring( original, pretty_print=True, encoding='utf-8').decode('utf8')))))
# =============================================================================
[docs]def value2string(elt, value): """Convert a string value according to type ``type_``. :type elt: lxml.etree.Element :param elt: DOM element owner of the value. :param str value: Type of the value. :rtype: str """ type_ = elt.get('type') value = value.replace('\r\n', '\n') if value else '' if type_ == 'boolean': value = value.strip() not in ('', 'false', 'False', '0') return 'true' if value else 'false' if type_ == 'text': indent = ' ' * 2 * (int(elt.xpath('count(ancestor::*)')) + 1) value = value.split('\n') for num, line in enumerate(value): line = normalize_spaces(line.replace(' ', '‧')) value[num] = '{indent}{line}'.format(indent=indent, line=line) return '\n{0}\n{1}'.format( '\n'.join(value).rstrip(), indent[2:]) \ if ''.join(value).strip() else '' return value.strip()
# ============================================================================= def _update_title(values, name, root_elt): """Update or remove a title. :param dict values: Values of the form. :param str name: Name of the value representing the title. :type root_elt: lxml.etree.Element :param root_elt: DOM element owner of the title. """ value = normalize_spaces( values.get('cioset_{0}'.format(name), '').replace(' ', '‧')) title_elt = root_elt.find( '{{{0}}}title'.format(RELAXNG_CIOSET['namespace'])) if not value and title_elt is not None: root_elt.remove(title_elt) elif value: if title_elt is None: title_elt = etree.Element('title') root_elt.insert(0, title_elt) title_elt.text = value