import re
import textwrap


def dicToYML(dic, max_length=80, reflow=True, break_long_words=False):
    """Convert a dictionary into a yml string.

    NB: use the pilcrow (¶) to force a line break within dictionary values.

    Args:
        dic (dict): a dictionary of key-value pairs.
        max_length(int): the maximum number of characters a line should contain.
        reflow (bool): if set to False, the original layout
            (line endings, indentation) of the yml string
            will be preserved (useful for files containing bullet lists etc.);
            if set to True, the indentation and line length
            will be standardized.
        break_long_words (bool): if False, long words will be kept on one line
            
    Returns:
        (str): yml string representation of the dic's key-value pairs

    Examples:
        >>> yml_dic = {'00#BOOK#URI######:': '0845Maqrizi.Muqaffa',\
                       '90#BOOK#COMMENT##:': 'multiline value; presence of colons: not a problem¶¶    * bullet point 1¶    * bullet point 2'}
        >>> yml_str = '\
        00#BOOK#URI######: 0845Maqrizi.Muqaffa\\n\
        90#BOOK#COMMENT##: multiline\\n\
            value; presence of colons: not\\n\
            a problem\\n\
        \\n\
            * bullet point 1\\n\
            * bullet point 2\
        '.replace("        ", "") # remove Python indentation for doctest
        >>> dicToYML(yml_dic, max_length=30, reflow=True) == yml_str
        True
        
        >>> yml_str = '\
        00#BOOK#URI######: 0845Maqrizi.Muqaffa\\n\
        90#BOOK#COMMENT##: multiline value; presence of colons: not a problem\\n\
            \\n\
            * bullet point 1\\n\
            * bullet point 2\
        '.replace("        ", "") # remove Python indentation for doctest
        >>> dicToYML(yml_dic, max_length=30, reflow=False) == yml_str
        True
    """
    data = []
    if dic:
        for k,v in dic.items():
            if k.strip().endswith(":"):
                i = "{} {}".format(k.strip(), str(v).strip())
            else:
                i = "{}: {}".format(k.strip(), str(v).strip())

            # split long values into indented multiline values:

            if "#URI#" not in i:

                lines = re.split("¶", i)

                if len(lines) > 1:
                    lines = [lines[0]] + [line if line.startswith((" ", "\t")) else "    "+line
                                          for line in lines[1:]]
                
                if reflow:
                    lines = ["\n    ".join(textwrap.wrap(line.strip(), max_length,
                                                         break_long_words=break_long_words))
                             for line in lines]

                i = "\n    ".join(lines)
            data.append(i)

    return "\n".join(sorted(data))