def _reorder_automatic(items, start=None, keep=None): """Reorder a document's items automatically. :param items: items to reorder :param start: level to start numbering (None = use current start) :param keep: item to keep over duplicates """ nlevel = plevel = None for clevel, item in Document._items_by_level(items, keep=keep): log.debug("current level: {}".format(clevel)) # Determine the next level if not nlevel: # Use the specified or current starting level nlevel = Level(start) if start else clevel nlevel.heading = clevel.heading log.debug("next level (start): {}".format(nlevel)) else: # Adjust the next level to be the same depth if len(clevel) > len(nlevel): nlevel >>= len(clevel) - len(nlevel) log.debug("matched current indent: {}".format(nlevel)) elif len(clevel) < len(nlevel): nlevel <<= len(nlevel) - len(clevel) # nlevel += 1 log.debug("matched current dedent: {}".format(nlevel)) nlevel.heading = clevel.heading # Check for a level jump _size = min(len(clevel.value), len(plevel.value)) for index in range(max(_size - 1, 1)): if clevel.value[index] > plevel.value[index]: nlevel <<= len(nlevel) - 1 - index nlevel += 1 nlevel >>= len(clevel) - len(nlevel) msg = "next level (jump): {}".format(nlevel) log.debug(msg) break # Check for a normal increment else: if len(nlevel) <= len(plevel): nlevel += 1 msg = "next level (increment): {}".format(nlevel) log.debug(msg) else: msg = "next level (indent/dedent): {}".format(nlevel) log.debug(msg) # Apply the next level if clevel == nlevel: log.info("{}: {}".format(item, clevel)) else: log.info("{}: {} to {}".format(item, clevel, nlevel)) item.level = nlevel.copy() # Save the current level as the previous level plevel = clevel.copy()