Search code examples
markdownsublimetext3sublimetext

Sort Nested Markdown List?


I am looking for a script, method or tool to sort nested markdown lists. I use sublime text, which has a built sort lines function, but this function destroys the order of any nested list. For instance, if I want to sort:

* Zoo Animals
    * Herbivores
        * Zebra
        * Gazelle
    * Carnivores
        * Tiger
        * Lion
    * Omnivores
        * Gorilla
        * Baboon
        * Chimpanzee
* Domestic Animals
    * Canines
        * German Shepherd
        * Cocker Spaniel

Using sublime sort lines function, I get:

        * Baboon
        * Chimpanzee
        * Cocker Spaniel
        * Gazelle
        * German Shepherd
        * Gorilla
        * Lion
        * Tiger
        * Zebra
    * Canines
    * Carnivores
    * Herbivores
    * Omnivores
* Domestic Animals
* Zoo Animals

Clearly, this is not what I want. What I want is a "scoped sort" which sorts relative to each bullet level, without destroying the nested relationships, like so:

* Domestic Animals
    * Canines
        * Cocker Spaniel
        * German Shepherd
* Zoo Animals
    * Carnivores
        * Lion
        * Tiger
    * Herbivores
        * Gazelle
        * Zebra
    * Omnivores
        * Baboon
        * Chimpanzee
        * Gorilla

Here's some things I've looked into and my thoughts on each:

  • Use a sublime package to sort. I can't find one. However, maybe there's a way to use CSSComb package and adapt it to a markdown list?
  • Use a manual process in sublime to sort the list, perhaps by selecting bullet levels and sorting by those? The problem with this is that the selection of lines to be sorted must be at the same indentation level, and must not be separated by any other line of another indentation level, otherwise the sort is completely messed up. Unless I am missing something?
  • Use a script to sort the lines. I am familiar with ruby, so maybe there's a way to import this list into ruby, and treat the nested list like a nested hash along the lines of this post. I'm sure I could accomplish my goal using a ruby script, but I didn't want to go down that road if there was already a solution available.

How would you go about sorting a large nested markdown list?

UPDATE #1:

@J4G created a great Atom package that solved the original sort problem, see his answer for the link.

The previous list is a simple list without code blocks and numbered lists. However, when sorting a real life markdown list, we have code blocks and numbered lists and lines starting with special characters - nested within the list like so:

* Commands
    * Migrations
        * `rake db:migrate` - push all migrations to the database
        * 'STEP=3' - revert the last 3 migrations
    * `Rails`
        * `c` - start rails console, run code from your app!
    * `Rake`
        * Rake Task
        ```ruby
        desc 'process csv'
        task process_csv: :environment do
            Node.process_csv
        end
        ```
* Package Upgrade Status:
    1. Install Package
    2. Attach Plugin
    3. Review Installation
    ~~~
    |Install|Status|
    |Yes|Pending|
    ~~~

After sorting, I would think the above markdown list should return unchanged since tick marks and quotes have no sort significance and code blocks / numbered lists are already created in their proper order.


Solution

  • If you're interested in using Atom (I highly recommend it as a free alternative to Sublime), I just made a package to do what you need.

    https://atom.io/packages/markdown-sort-list