renderDirIndex :: String -> FilePath -> [(FilePath, TarIndex.TarIndexEntry)] -> XHtml.Html
renderDirIndex descr topdir topentries =
    hackagePage title
      [ XHtml.h2 << title
      , XHtml.h3 << addTrailingPathSeparator topdir
      , renderForest "" topentries]
  where
    title = "Directory listing for " ++ descr
    renderForest _   [] = XHtml.noHtml
    renderForest dir ts = XHtml.ulist ! [ XHtml.theclass "directory-list" ]
                           << map (uncurry (renderTree dir)) ts

    renderTree dir entryname (TarIndex.TarFileEntry _) =
      XHtml.li << XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << entryname
    renderTree dir entryname (TarIndex.TarDir entries) =
      XHtml.li << [ XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << addTrailingPathSeparator entryname
                  , renderForest (dir </> entryname) entries ]
renderDirIndex :: String -> FilePath -> [(FilePath, TarIndex.TarIndexEntry)] -> XHtml.Html
renderDirIndex descr topdir topentries =
    hackagePage title
      [ XHtml.h2 << title
      , XHtml.h3 << addTrailingPathSeparator topdir
      , renderForest "" topentries]
  where
    title = "Directory listing for " ++ descr
    renderForest _   [] = XHtml.noHtml
    renderForest dir ts = XHtml.ulist ! [ XHtml.theclass "directory-list" ]
                           << map (uncurry (renderTree dir)) ts

    renderTree dir entryname (TarIndex.TarFileEntry _) =
      XHtml.li << XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << entryname
    renderTree dir entryname (TarIndex.TarDir entries) =
      XHtml.li << [ XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << addTrailingPathSeparator entryname
                  , renderForest (dir </> entryname) entries ]
renderDirIndex descr topdir topentries =
    hackagePage title
      [ XHtml.h2 << title
      , XHtml.h3 << addTrailingPathSeparator topdir
      , renderForest "" topentries]
  where
    title = "Directory listing for " ++ descr
    renderForest _   [] = XHtml.noHtml
    renderForest dir ts = XHtml.ulist ! [ XHtml.theclass "directory-list" ]
                           << map (uncurry (renderTree dir)) ts

    renderTree dir entryname (TarIndex.TarFileEntry _) =
      XHtml.li << XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << entryname
    renderTree dir entryname (TarIndex.TarDir entries) =
      XHtml.li << [ XHtml.anchor ! [XHtml.href (dir </> entryname)]
                              << addTrailingPathSeparator entryname
                  , renderForest (dir </> entryname) entries ]