# Path: xdfile/utils.py
# EOL = '\n'
# COLSEP = '\t'
# COLUMN_SEPARATOR = COLSEP
# WEEKDAYS = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# class bcolors:
# class AttrDict(dict):
# class OutputZipFile(zipfile.ZipFile):
# class OutputFile:
# class OutputDirectory:
# def space_with_nbsp(text):
# def split_xdid(xdid):
# def br_with_n(text):
# def get_log():
# def log(s, minverbose=0, severity='INFO'):
# def info(_s, _m=0):
# def warn(_s, _m=0):
# def error(_s, _m=0):
# def summary(_s, _m=0):
# def debug(s):
# def progress(rest=None, every=1):
# def args_parser(desc=""):
# def get_args(desc="", parser=None):
# def find_files(*paths, **kwargs):
# def to_timet(y, mon=1, d=1, h=0, m=0, s=0):
# def generate_zip_files(data):
# def find_files_with_time(*paths, **kwargs):
# def filetime(fn):
# def iso8601(timet=None):
# def datestr_to_datetime(s):
# def parse_xdid(path):
# def parse_pathname(path):
# def parse_pubid(fn):
# def construct_date(y, m, d):
# def parse_iso8601(s):
# def parse_seqnum(s):
# def parse_date_from_filename(fn):
# def clean_filename(fn):
# def replace_ext(fn, newext):
#     def __init__(self, *args, **kwargs):
# def autoconvert(v):
# def parse_tsv_data(contents, objname=None):
# def parse_tsv(fn, objname=None):
# def parse_tsv_rows(fn, objname=None):
#     def __init__(self, fnzip, toplevel="", log=True):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def __del__(self):
#     def __init__(self, outfp=None):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def write_row(self, fields):
#     def write_html(self, fn, innerhtml, title=""):
# def strip_toplevel(fn):
# def disambiguate_fn(fn, all_filenames):
#     def __init__(self, toplevel_dir):
#     def exists(self, fn):
#     def open_file(self, fn, mode='w'):
#     def close_file(self, fn):
#     def write_file(self, fn, contents, timet=None):
#     def write_html(self, fn, innerhtml, title=""):
#     def write_row(self, fn, headerstr, values):
# def open_output(fnout=None):
# def memoize(obj):
#     def memoizer(*args, **kwargs):
# def __dict_replace(s, d):
# def escape(data, entities={}):
# def consecutive(text):


import re
import xdfile
from urllib.parse import unquote
from lxml import etree
from xdfile.utils import escape, consecutive, xml_escape_table, rev_xml_escape_table
        root = etree.fromstring(xml)

    # init crossword
    # rows = int(root.xpath('//crossword/Height')[0].attrib['v'])
    cols = int(root.xpath('//crossword/Width')[0].attrib['v'])
    xd = xdfile.xdfile('', filename)

    # add meta data
    for item in POSSIBLE_META_DATA:
        elem = root.xpath('//crossword/' + item)
        if elem:
            text = elem[0].attrib['v']
            if text:
                text = escape(text, rev_xml_escape_table)
                xd.set_header(item, unquote(text))

    # add puzzle
    all_answers = root.xpath('//crossword/AllAnswer')[0].attrib['v']
    all_answers = all_answers.replace('-', xdfile.BLOCK_CHAR)
    index = 0
    while index < len(all_answers):
        row = all_answers[index:index + cols]
        xd.grid.append("".join(row))
        index += cols

    # add clues
    for clue_type in ('across', 'down'):
        for clue in root.xpath('//crossword/' + clue_type)[0].getchildren():
            number = int(clue.attrib['cn'])
            text = udecode(clue.attrib['c'].strip())

# Path: xdfile/utils.py
# EOL = '\n'
# COLSEP = '\t'
# COLUMN_SEPARATOR = COLSEP
# WEEKDAYS = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# class bcolors:
# class AttrDict(dict):
# class OutputZipFile(zipfile.ZipFile):
# class OutputFile:
# class OutputDirectory:
# def space_with_nbsp(text):
# def split_xdid(xdid):
# def br_with_n(text):
# def get_log():
# def log(s, minverbose=0, severity='INFO'):
# def info(_s, _m=0):
# def warn(_s, _m=0):
# def error(_s, _m=0):
# def summary(_s, _m=0):
# def debug(s):
# def progress(rest=None, every=1):
# def args_parser(desc=""):
# def get_args(desc="", parser=None):
# def find_files(*paths, **kwargs):
# def to_timet(y, mon=1, d=1, h=0, m=0, s=0):
# def generate_zip_files(data):
# def find_files_with_time(*paths, **kwargs):
# def filetime(fn):
# def iso8601(timet=None):
# def datestr_to_datetime(s):
# def parse_xdid(path):
# def parse_pathname(path):
# def parse_pubid(fn):
# def construct_date(y, m, d):
# def parse_iso8601(s):
# def parse_seqnum(s):
# def parse_date_from_filename(fn):
# def clean_filename(fn):
# def replace_ext(fn, newext):
#     def __init__(self, *args, **kwargs):
# def autoconvert(v):
# def parse_tsv_data(contents, objname=None):
# def parse_tsv(fn, objname=None):
# def parse_tsv_rows(fn, objname=None):
#     def __init__(self, fnzip, toplevel="", log=True):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def __del__(self):
#     def __init__(self, outfp=None):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def write_row(self, fields):
#     def write_html(self, fn, innerhtml, title=""):
# def strip_toplevel(fn):
# def disambiguate_fn(fn, all_filenames):
#     def __init__(self, toplevel_dir):
#     def exists(self, fn):
#     def open_file(self, fn, mode='w'):
#     def close_file(self, fn):
#     def write_file(self, fn, contents, timet=None):
#     def write_html(self, fn, innerhtml, title=""):
#     def write_row(self, fn, headerstr, values):
# def open_output(fnout=None):
# def memoize(obj):
#     def memoizer(*args, **kwargs):
# def __dict_replace(s, d):
# def escape(data, entities={}):
# def consecutive(text):


# Path: xdfile/uxml2xd.py
import re
import xdfile
from urllib.parse import unquote
from lxml import etree
from xdfile.utils import escape, consecutive, xml_escape_table, rev_xml_escape_table

        root = etree.fromstring(xml)

    # init crossword
    # rows = int(root.xpath('//crossword/Height')[0].attrib['v'])
    cols = int(root.xpath('//crossword/Width')[0].attrib['v'])
    xd = xdfile.xdfile('', filename)

    # add meta data
    for item in POSSIBLE_META_DATA:
        elem = root.xpath('//crossword/' + item)
        if elem:
            text = elem[0].attrib['v']
            if text:
                text = escape(text, rev_xml_escape_table)
                xd.set_header(item, unquote(text))

    # add puzzle
    all_answers = root.xpath('//crossword/AllAnswer')[0].attrib['v']
    all_answers = all_answers.replace('-', xdfile.BLOCK_CHAR)
    index = 0
    while index < len(all_answers):
        row = all_answers[index:index + cols]
        xd.grid.append("".join(row))
        index += cols

    # add clues
    for clue_type in ('across', 'down'):
        for clue in root.xpath('//crossword/' + clue_type)[0].getchildren():
            number = int(clue.attrib['cn'])
            text = udecode(clue.attrib['c'].strip())

            text = escape(text, rev_xml_escape_table)