Rapid Outliner

ZorkFanDM
2010-10-06
2013-01-25
  • ZorkFanDM
    ZorkFanDM
    2010-10-06

    This is a script to auto generate .txt outlines commonly seen in readme files, guides, video game walkthroughs, etc.
    Its prompt-based and allows for custom brackets and separators as well as an option to cancel if you mis-clicked. I'm new to python so much of the code is probably convoluted and not "pythonic", but nevertheless I think it may be useful.

    layers = []
    title = "Auto-Outline"
    FLAG_RUN = True
    YNC = notepad.messageBox("Welcome to the Auto-Outliner.\nDefault enclosures are [x.y.z...]\nIs this OK?",
        title, MESSAGEBOXFLAGS.YESNOCANCEL)
    if YNC == MESSAGEBOXFLAGS.RESULTYES: op, sep, cl  = ("[", ".", "]")
    elif YNC == MESSAGEBOXFLAGS.RESULTCANCEL: FLAG_RUN = False
    else:
        while YNC == MESSAGEBOXFLAGS.RESULTNO:
            op = notepad.prompt("Enter opening string:", title, "[")
            sep = notepad.prompt("Format:" + op + "x...\nEnter separator string:", title, ".")
            cl = notepad.prompt("Format:" + op + "x" + sep + "y...\nEnter separator string:"
                , title, "]")
            YNC = notepad.messageBox("Format: " + op + sep.join(["x","y","z"]) +"..." +
                cl + " OK?", title, MESSAGEBOXFLAGS.YESNO)
    if FLAG_RUN is True:
        def as_tag(ids, OpCl = False):
            """Used to take a list of [x,y,z,...] integers and turn
            it into a string using sep and optionally op/cl"""
            if OpCl is False: return sep.join([str(x) for x in ids])
            elif OpCl is True: return op + sep.join([str(x) for x in ids]) + cl
        title2 = title + "(Use Cancel to end a section)"
        YN = MESSAGEBOXFLAGS.RESULTYES
    
        # Loop through while user agrees to add layers.
        while YN == MESSAGEBOXFLAGS.RESULTYES:
            cur_layer = {}
            cur_name = ""
    
            # First time through, no previous section to display
            if len(layers) == 0:
                id_cur_name = 1
                while not cur_name is None:
                    cur_name = notepad.prompt("Current sections: " + ",".join(cur_layer.values()) +
                        "\nEnter section " + str(id_cur_name) + ":",
                        title2)
                    if cur_name == "": cur_name = None
                    if not cur_name is None: cur_layer[str(id_cur_name)] = cur_name
                    id_cur_name += 1
    
            # Otherwise, display previous section title
            else:
                id_prv_layer = len(layers) - 1
                cur_layer = {}
                prv_layer = layers[id_prv_layer].keys()
                prv_layer.sort()
                for tag in prv_layer:
                    cur_name = ""
                    id_cur_name = 1
                    cur_sublayer = {}
                    ids_cur = []
                    while not cur_name is None:
                        cur_name = notepad.prompt(op + tag + cl + " = " +  layers[id_prv_layer][tag] +
                            "\nCurrent subsections: " +
                            ",".join([x + " " + cur_sublayer[x] for x in ids_cur]) +
                            " ... " + as_tag([tag,str(id_cur_name)]) + " = ?",
                            title2)
                        if cur_name == "": cur_name = None
                        ids_cur.append(as_tag([tag,id_cur_name]))
                        if not cur_name is None: cur_sublayer[as_tag([tag,id_cur_name])] = cur_name
                        id_cur_name += 1
                    cur_layer.update(cur_sublayer)
    
            layers.append(cur_layer)
            YN = notepad.messageBox("Add another layer?", title, MESSAGEBOXFLAGS.YESNO)
    
        #Begin output file...
        notepad.new()
        tot_layers = len(layers)-1
    
        def write_subs_main(cur_tag, layer_num, just_val, body = False):
            """This function should recursively call itself, writing 3 space
            indented outline parts until finished."""
            if body is False:
                editor.addText("".join(["   " for x in range(layer_num)]) + 
                    as_tag([str(cur_tag)], OpCl = True) +
                    " " + layers[layer_num][cur_tag] + "\n")
            elif body is True:
                editor.addText("\t\tSection " + 
                    as_tag([str(cur_tag)], OpCl = True).rjust(just_val) +
                    " " + layers[layer_num][cur_tag] + "\n"*3)
            if layer_num < tot_layers:
                next_layer = layers[layer_num + 1]
                next_tags = next_layer.keys()
                next_tags.sort()
                for next_tag in next_tags:
                    if cur_tag in next_tag[0:len(cur_tag)]:
                        write_subs_main(next_tag, layer_num+1,just_val, body)
    
        main_tags = layers[0].keys()
        main_tags.sort()
        # This code grabs the length of the longest tagline and uses it to justify outputs
        max_len = max([len(as_tag([x], OpCl = True)) for x in layers[tot_layers].keys()])
        for tag in main_tags: write_subs_main(tag, 0, max_len)
        editor.addText("\n"*3)
        for tag in main_tags: write_subs_main(tag, 0, max_len, body = True)
    
    else: pass
    
     
  • Very handy!  I'm no Python expert either, but the auto-type-conversion can come in very handy to make things shorter and more readable.  For instance, and empty string and None are converted to False when a boolean is needed, a non-empty string is converted to true, so you can say

    if not body:
       ...
    elif body:
      ...