render :: Maybe R.Region -> R.Region -> String -> Doc
render maybeSubRegion region@(R.Region start end) source =
  let
    (R.Position startLine startColumn) = start
    (R.Position endLine endColumn) = end

    relevantLines =
        lines source
          |> drop (startLine - 1)
          |> take (endLine - startLine + 1)
  in
    case relevantLines of
      [] ->
          empty

      [sourceLine] ->
          singleLineRegion startLine sourceLine $
            case maybeSubRegion of
              Nothing ->
                  (0, startColumn, endColumn, length sourceLine)

              Just (R.Region s e) ->
                  (startColumn, R.column s, R.column e, endColumn)

      firstLine : rest ->
          let
            filteredFirstLine =
                replicate (startColumn - 1) ' '
                ++ drop (startColumn - 1) firstLine

            filteredLastLine =
                take (endColumn) (last rest)

            focusedRelevantLines =
                filteredFirstLine : init rest ++ [filteredLastLine]

            lineNumbersWidth =
                length (show endLine)

            subregion =
                maybeSubRegion <|> Just region

            numberedLines =
                zipWith
                  (addLineNumber subregion lineNumbersWidth)
                  [startLine .. endLine]
                  focusedRelevantLines
          in
            foldr (<==>) empty numberedLines
render :: Maybe R.Region -> R.Region -> String -> Doc
render maybeSubRegion region@(R.Region start end) source =
  let
    (R.Position startLine startColumn) = start
    (R.Position endLine endColumn) = end

    relevantLines =
        lines source
          |> drop (startLine - 1)
          |> take (endLine - startLine + 1)
  in
    case relevantLines of
      [] ->
          empty

      [sourceLine] ->
          singleLineRegion startLine sourceLine $
            case maybeSubRegion of
              Nothing ->
                  (0, startColumn, endColumn, length sourceLine)

              Just (R.Region s e) ->
                  (startColumn, R.column s, R.column e, endColumn)

      firstLine : rest ->
          let
            filteredFirstLine =
                replicate (startColumn - 1) ' '
                ++ drop (startColumn - 1) firstLine

            filteredLastLine =
                take (endColumn) (last rest)

            focusedRelevantLines =
                filteredFirstLine : init rest ++ [filteredLastLine]

            lineNumbersWidth =
                length (show endLine)

            subregion =
                maybeSubRegion <|> Just region

            numberedLines =
                zipWith
                  (addLineNumber subregion lineNumbersWidth)
                  [startLine .. endLine]
                  focusedRelevantLines
          in
            foldr (<==>) empty numberedLines
render maybeSubRegion region@(R.Region start end) source =
  let
    (R.Position startLine startColumn) = start
    (R.Position endLine endColumn) = end

    relevantLines =
        lines source
          |> drop (startLine - 1)
          |> take (endLine - startLine + 1)
  in
    case relevantLines of
      [] ->
          empty

      [sourceLine] ->
          singleLineRegion startLine sourceLine $
            case maybeSubRegion of
              Nothing ->
                  (0, startColumn, endColumn, length sourceLine)

              Just (R.Region s e) ->
                  (startColumn, R.column s, R.column e, endColumn)

      firstLine : rest ->
          let
            filteredFirstLine =
                replicate (startColumn - 1) ' '
                ++ drop (startColumn - 1) firstLine

            filteredLastLine =
                take (endColumn) (last rest)

            focusedRelevantLines =
                filteredFirstLine : init rest ++ [filteredLastLine]

            lineNumbersWidth =
                length (show endLine)

            subregion =
                maybeSubRegion <|> Just region

            numberedLines =
                zipWith
                  (addLineNumber subregion lineNumbersWidth)
                  [startLine .. endLine]
                  focusedRelevantLines
          in
            foldr (<==>) empty numberedLines