1
1
{-# LANGUAGE OverloadedStrings #-}
2
+ {-# LANGUAGE ViewPatterns #-}
2
3
module Shake.Highlights (renderHighlights ) where
3
4
4
5
import Control.Monad.Trans
5
6
6
7
import qualified Data.Map.Strict as Map
8
+ import qualified Data.Set as Set
7
9
import qualified Data.Text as Text
8
10
import Data.Traversable
9
11
import Data.Map.Strict (Map )
12
+ import Data.Set (Set )
10
13
import Data.Text (Text )
11
14
import Data.Maybe
12
15
import Data.Char
@@ -21,6 +24,37 @@ import Definitions
21
24
22
25
import Debug.Trace
23
26
27
+ -- | Make some 'Text' title-cased.
28
+ titleCase :: Text -> Text
29
+ titleCase txt =
30
+ case Text. uncons txt of
31
+ Just (c, cs) -> Text. cons (toUpper c) cs
32
+ Nothing -> " "
33
+
34
+ -- | Construct a title for a highlighting block.
35
+ -- The rules for titles are:
36
+ -- 1. If the highlighting icon has an @aria-label@, then we use that as the root of the label.
37
+ -- 2. If there is no @aria-label@, then we title-case the highlighting class name.
38
+ -- 3. If the highlighting block has an @id@ attribute, then title case it, and concatenate it on.
39
+ -- This is used to display the definition name in @definition@ blocks.
40
+ highlightText
41
+ :: Text
42
+ -- ^ Highlighting class of the block.
43
+ -> [TagTree Text ]
44
+ -- ^ The highlight SVG for the block.
45
+ -> [Attribute Text ]
46
+ -- ^ Highlight block attributes.
47
+ -> Text
48
+ highlightText clz svg attr =
49
+ fromMaybe (titleCase clz) ariaLabel <>
50
+ maybe " " (" : " <> ) (lookup " id" attr)
51
+ where
52
+ ariaLabel :: Maybe Text
53
+ ariaLabel =
54
+ case svg of
55
+ (TagBranch _ svgAttr _: _) -> lookup " aria-label" svgAttr
56
+ _ -> Nothing
57
+
24
58
-- | Expands away @<div class="warning">@ and @<details warning>@. Any
25
59
-- icon under @support/web/highlights@ is supported; the @definition@
26
60
-- icon will additionally include the principal label being defined (the
@@ -40,17 +74,18 @@ renderHighlights input stream = do
40
74
isHighlight (xs, " " ) = isIcon xs
41
75
isHighlight _ = Nothing
42
76
43
- readIcon icn = do
44
- tree <- parseTree . Text. pack <$> readFile' (" support/web/highlights" </> Text. unpack icn -<.> " svg" )
45
- case tree of
46
- (TagBranch _ attr _: _) | Just label <- lookup " aria-label" attr -> pure (tree, label)
47
- _ -> pure (tree, Text. cons (toUpper (Text. head icn)) (Text. tail icn))
48
- iconSpan icn = do
49
- (icon, name') <- readIcon icn
50
- let name = TagText name'
77
+ titleCase (Text. uncons -> Just (c, cs)) = Text. cons (toUpper c) cs
78
+ titleCase _ = " "
79
+
80
+ readIcon icn =
81
+ parseTree . Text. pack <$> readFile' (" support/web/highlights" </> Text. unpack icn -<.> " svg" )
82
+
83
+ highlightSpan icn attr = do
84
+ svg <- readIcon icn
85
+ let text = TagText (highlightText icn svg attr)
51
86
pure $ TagBranch " span" [(" class" , " highlight-header" )]
52
- [ TagBranch " span" [(" class" , " highlight-icon" )] icon
53
- , TagBranch " span" [(" class" , " highlight-text" )] [TagLeaf name ]
87
+ [ TagBranch " span" [(" class" , " highlight-icon" )] svg
88
+ , TagBranch " span" [(" class" , " highlight-text" )] [TagLeaf text ]
54
89
]
55
90
56
91
go :: TagTree Text -> Action (TagTree Text )
@@ -59,15 +94,15 @@ renderHighlights input stream = do
59
94
let clzs = Text. words clz,
60
95
[icn] <- mapMaybe isIcon clzs
61
96
= do
62
- icon <- iconSpan icn
97
+ icon <- highlightSpan icn attr
63
98
children <- traverse go children
64
99
pure $ TagBranch " div" ((" class" , " highlighted " <> clz): attr) $ icon: children
65
100
66
101
go t@ (TagBranch " details" attr children)
67
102
| Just (sattr, schild, rest) <- summary children
68
103
, [icn] <- mapMaybe isHighlight attr
69
104
= do
70
- icon <- iconSpan icn
105
+ icon <- highlightSpan icn attr
71
106
schild <- traverse go schild
72
107
rest <- traverse go rest
73
108
pure $ TagBranch " details" ((" class" , icn): attr) $
0 commit comments