aboutsummaryrefslogtreecommitdiffstats
path: root/app/Issue/Text.hs
blob: 5d1dddb89037f78febd45e35b741d203a034dff2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module Issue.Text
  ( extractText,
    stripIssueMarkers,
    issueMarkers,
  )
where

import Control.Arrow (first, second)
import Data.List (find)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import Data.Text qualified as T
import TreeGrepper.FileType (FileType)
import TreeGrepper.FileType qualified as G

extractText :: FileType -> Text -> (Text, Maybe Text)
extractText fileType rawText = (title, description)
  where
    text = stripComments fileType $ stripLines rawText
    stripLines = T.intercalate "\n" . map T.strip . T.lines
    (title, description') = second T.stripStart $ T.breakOn "\n" text
    description
      | T.null description' = Nothing
      | otherwise = Just description'

stripComments :: G.FileType -> Text -> Text
stripComments fileType text =
  maybe
    (stripLineComments (G.info fileType).lineStart text)
    ( \(blockInfo, blockStart) ->
        stripBlockComment blockStart blockInfo.blockEnd text
    )
    $ do
      blockInfo <- (G.info fileType).block
      (,) blockInfo <$> find (`T.isPrefixOf` text) blockInfo.blockStart

stripLineComments :: Text -> Text -> Text
stripLineComments lineStart text =
  onLines
    ( \line ->
        fromMaybe line . fmap T.stripStart $
          T.stripPrefix lineStart line
    )
    text
  where
    onLines f = T.intercalate "\n" . map f . T.lines

stripBlockComment :: Text -> Text -> Text -> Text
stripBlockComment blockStart blockEnd text =
  T.strip
    . (fromMaybe text . T.stripSuffix blockEnd)
    . (fromMaybe text . T.stripPrefix blockStart)
    $ text

issueMarkers :: [T.Text]
issueMarkers =
  [ "TODO",
    "FIXME",
    "QUESTION"
  ]

stripIssueMarkers :: T.Text -> ([T.Text], T.Text)
stripIssueMarkers text =
  case [marker | marker <- issueMarkers, T.isPrefixOf marker text] of
    (marker : _) ->
      first (marker :) . stripIssueMarkers $
        T.stripStart (T.drop (T.length marker) text)
    [] ->
      ([], text)