computeFlattenedOutput
  :: T.Text
  -> T.Text
  -> Maybe T.Text
  -> Maybe [(T.Text, T.Text)]
  -> OutputSection
  -> [(T.Text, FlattenedOutputSection)]
computeFlattenedOutput
    tableOfContentsIdentifier
    symbolIndexIdentifier
    maybeParentNumber
    maybeParentTitle
    section =
  [(outputSectionID section,
    FlattenedOutputSection {
        flattenedOutputSectionTitle =
          case (outputSectionNumber section, outputSectionTitle section) of
            (Just number, Just title) ->
              T.concat [number,
                        " ",
                        T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Just number, Nothing) ->
              T.concat [number,
                        " | Modern Data the Reference"]
            (Nothing, Just title) ->
              T.concat [T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Nothing, Nothing) -> "Modern Data the Reference",
        flattenedOutputSectionNavigation =
          let titleParts title =
                map (\(identifier, name) ->
                        linkIfNotHere identifier name)
                    title
              linkIfNotHere identifier name =
                if outputSectionID section == identifier
                  then Text name
                  else Link identifier [Text name]
              overallNavigation =
                [[linkIfNotHere tableOfContentsIdentifier
                                "Modern Data the Reference"]]
              maybeDrillDownNumber =
                case outputSectionNumber section of
                  Nothing ->
                    case maybeParentNumber of
                      Nothing -> Nothing
                      Just parentNumber -> Just [Text parentNumber]
                  Just number -> Just [Text number]
              maybeDrillDownParts =
                case outputSectionTitle section of
                  Just title -> Just $
                    intersperse (Text titleSeparator)
                                (titleParts title)
                  Nothing -> Nothing
              maybeDrillDownLine =
                case (maybeDrillDownNumber, maybeDrillDownParts) of
                  (Nothing, Nothing) -> Nothing
                  (Just number, Nothing) -> Just number
                  (Nothing, Just parts) -> Just parts
                  (Just number, Just parts) ->
                    Just $ number ++ [Text " "] ++ parts
              maybeProperLine =
                case outputSectionProperTitle section of
                  Just properTitle -> Just [Text properTitle]
                  Nothing -> Nothing
          in overallNavigation
             ++ maybeToList maybeDrillDownLine
             ++ maybeToList maybeProperLine,
        flattenedOutputSectionBody = outputSectionSelfBody section
      })]
  ++ concatMap (computeFlattenedOutput tableOfContentsIdentifier
                                       symbolIndexIdentifier
                                       (outputSectionNumber section)
                                       (outputSectionTitle section))
               (outputSectionChildren section)
computeFlattenedOutput
  :: T.Text
  -> T.Text
  -> Maybe T.Text
  -> Maybe [(T.Text, T.Text)]
  -> OutputSection
  -> [(T.Text, FlattenedOutputSection)]
computeFlattenedOutput
    tableOfContentsIdentifier
    symbolIndexIdentifier
    maybeParentNumber
    maybeParentTitle
    section =
  [(outputSectionID section,
    FlattenedOutputSection {
        flattenedOutputSectionTitle =
          case (outputSectionNumber section, outputSectionTitle section) of
            (Just number, Just title) ->
              T.concat [number,
                        " ",
                        T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Just number, Nothing) ->
              T.concat [number,
                        " | Modern Data the Reference"]
            (Nothing, Just title) ->
              T.concat [T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Nothing, Nothing) -> "Modern Data the Reference",
        flattenedOutputSectionNavigation =
          let titleParts title =
                map (\(identifier, name) ->
                        linkIfNotHere identifier name)
                    title
              linkIfNotHere identifier name =
                if outputSectionID section == identifier
                  then Text name
                  else Link identifier [Text name]
              overallNavigation =
                [[linkIfNotHere tableOfContentsIdentifier
                                "Modern Data the Reference"]]
              maybeDrillDownNumber =
                case outputSectionNumber section of
                  Nothing ->
                    case maybeParentNumber of
                      Nothing -> Nothing
                      Just parentNumber -> Just [Text parentNumber]
                  Just number -> Just [Text number]
              maybeDrillDownParts =
                case outputSectionTitle section of
                  Just title -> Just $
                    intersperse (Text titleSeparator)
                                (titleParts title)
                  Nothing -> Nothing
              maybeDrillDownLine =
                case (maybeDrillDownNumber, maybeDrillDownParts) of
                  (Nothing, Nothing) -> Nothing
                  (Just number, Nothing) -> Just number
                  (Nothing, Just parts) -> Just parts
                  (Just number, Just parts) ->
                    Just $ number ++ [Text " "] ++ parts
              maybeProperLine =
                case outputSectionProperTitle section of
                  Just properTitle -> Just [Text properTitle]
                  Nothing -> Nothing
          in overallNavigation
             ++ maybeToList maybeDrillDownLine
             ++ maybeToList maybeProperLine,
        flattenedOutputSectionBody = outputSectionSelfBody section
      })]
  ++ concatMap (computeFlattenedOutput tableOfContentsIdentifier
                                       symbolIndexIdentifier
                                       (outputSectionNumber section)
                                       (outputSectionTitle section))
               (outputSectionChildren section)
computeFlattenedOutput
    tableOfContentsIdentifier
    symbolIndexIdentifier
    maybeParentNumber
    maybeParentTitle
    section =
  [(outputSectionID section,
    FlattenedOutputSection {
        flattenedOutputSectionTitle =
          case (outputSectionNumber section, outputSectionTitle section) of
            (Just number, Just title) ->
              T.concat [number,
                        " ",
                        T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Just number, Nothing) ->
              T.concat [number,
                        " | Modern Data the Reference"]
            (Nothing, Just title) ->
              T.concat [T.intercalate titleSeparator $ map snd title,
                        " | Modern Data the Reference"]
            (Nothing, Nothing) -> "Modern Data the Reference",
        flattenedOutputSectionNavigation =
          let titleParts title =
                map (\(identifier, name) ->
                        linkIfNotHere identifier name)
                    title
              linkIfNotHere identifier name =
                if outputSectionID section == identifier
                  then Text name
                  else Link identifier [Text name]
              overallNavigation =
                [[linkIfNotHere tableOfContentsIdentifier
                                "Modern Data the Reference"]]
              maybeDrillDownNumber =
                case outputSectionNumber section of
                  Nothing ->
                    case maybeParentNumber of
                      Nothing -> Nothing
                      Just parentNumber -> Just [Text parentNumber]
                  Just number -> Just [Text number]
              maybeDrillDownParts =
                case outputSectionTitle section of
                  Just title -> Just $
                    intersperse (Text titleSeparator)
                                (titleParts title)
                  Nothing -> Nothing
              maybeDrillDownLine =
                case (maybeDrillDownNumber, maybeDrillDownParts) of
                  (Nothing, Nothing) -> Nothing
                  (Just number, Nothing) -> Just number
                  (Nothing, Just parts) -> Just parts
                  (Just number, Just parts) ->
                    Just $ number ++ [Text " "] ++ parts
              maybeProperLine =
                case outputSectionProperTitle section of
                  Just properTitle -> Just [Text properTitle]
                  Nothing -> Nothing
          in overallNavigation
             ++ maybeToList maybeDrillDownLine
             ++ maybeToList maybeProperLine,
        flattenedOutputSectionBody = outputSectionSelfBody section
      })]
  ++ concatMap (computeFlattenedOutput tableOfContentsIdentifier
                                       symbolIndexIdentifier
                                       (outputSectionNumber section)
                                       (outputSectionTitle section))
               (outputSectionChildren section)