XML prettifier in Haskell
I don’t know how many times I’ve gone looking for one of these but my search-fu is weak and I always give up, instead resorting to manual editing in Vim (no I hardly ever need the entire file to be pretty, only one or two tags that I’m interested in). Anyway, here’s a quick hack in Haskell, relying on xml for the heavy lifting:
#! /usr/bin/env runhaskell module Main where import Control.Monad import System.Environment import Text.XML.Light.Input import Text.XML.Light.Output main = do fn <- liftM (!! 0) $ getArgs xml_contents <- readFile fn let (Just doc) = parseXMLDoc xml_contents writeFile ("pretty-" ++ fn) (ppTopElement doc) |
There is an utility command “xmllint” which comes with “libxml2-utils” package on Ubuntu.
As cool as that is, what about Vim’s “gg=G”? It sometimes gets confused by what the proper indentation should be around comments, but aside from that, it’s pretty good.
@Gutkovas, what’s the fun in that? Kidding aside, I didn’t know xmllint did that, thanks for pointing it out.
@ephemient, yes, that’s what I’ve often done, but as you point out, it’s not always reliable.
I’m really just a noob, but what’s the point of using (!! 0) instead of head?
For your first line in main, I recommend:
main = do [fn] <- getArgs …
@endrew & David, every time I use
getArgsI forget it doesn’t includeargv[0]so I always start out withliftM (!! 1)and when reminded (through a run-time exception) I put in the zero. Of course I could always us(_:fn), but pattern matching indo(orlet) still doesn’t come naturally for me.And, of course, you technically can’t pretty-print XML, because all the whitespace is significant. Except for within the tags.
Aha! I knew there was something to it