@@ -16,19 +16,23 @@ open Lean Elab
16
16
17
17
namespace Manual
18
18
19
- def Block.example (name : Option String) : Block where
19
+ def Block.example (name : Option String) (opened : Bool) : Block where
20
20
name := `Manual.example
21
- data := ToJson.toJson (name, (none : Option Tag))
21
+ data := ToJson.toJson (name, opened, (none : Option Tag))
22
22
23
23
structure ExampleConfig where
24
24
description : FileMap × TSyntaxArray `inline
25
25
/-- Name for refs -/
26
26
tag : Option String := none
27
27
keep : Bool := false
28
+ opened : Bool := false
28
29
29
30
30
31
def ExampleConfig.parse [Monad m] [MonadInfoTree m] [MonadLiftT CoreM m] [MonadEnv m] [MonadError m] [MonadFileMap m] : ArgParse m ExampleConfig :=
31
- ExampleConfig.mk <$> .positional `description .inlinesString <*> .named `tag .string true <*> (.named `keep .bool true <&> (·.getD false ))
32
+ ExampleConfig.mk <$> .positional `description .inlinesString
33
+ <*> .named `tag .string true
34
+ <*> (.named `keep .bool true <&> (·.getD false ))
35
+ <*> (.named `open .bool true <&> (·.getD false ))
32
36
33
37
def prioritizedElab [Monad m] (prioritize : α → m Bool) (act : α → m β) (xs : Array α) : m (Array β) := do
34
38
let mut out := #[]
@@ -70,35 +74,42 @@ def «example» : DirectiveExpander
70
74
withoutModifyingEnv <| prioritizedElab (isLeanBlock ·) elabBlock contents
71
75
-- Examples are represented using the first block to hold the description. Storing it in the JSON
72
76
-- entails repeated (de)serialization.
73
- pure #[← ``(Block.other (Block.example $(quote cfg.tag)) #[Block.para #[$description,*], $blocks,*])]
77
+ pure #[← ``(Block.other (Block.example $(quote cfg.tag) (opened := $(quote cfg.opened)))
78
+ #[Block.para #[$description,*], $blocks,*])]
74
79
75
80
@[block_extension «example»]
76
81
def example.descr : BlockDescr where
77
82
traverse id data contents := do
78
- match FromJson.fromJson? data (α := Option String × Option Tag) with
83
+ match FromJson.fromJson? data (α := Option String × Bool × Option Tag) with
79
84
| .error e => logError s! "Error deserializing example tag: { e} " ; pure none
80
- | .ok (none, _) => pure none
81
- | .ok (some x, none) =>
85
+ | .ok (none, _, _ ) => pure none
86
+ | .ok (some x, opened, none) =>
82
87
let path ← (·.path) <$> read
83
88
let tag ← Verso.Genre.Manual.externalTag id path x
84
- pure <| some <| Block.other {Block.example none with id := some id, data := toJson (some x, some tag)} contents
85
- | .ok (some _, some _) => pure none
89
+ pure <| some <| Block.other {Block.example none false with id := some id, data := toJson (some x, opened , some tag)} contents
90
+ | .ok (some _, _, some _) => pure none
86
91
toTeX :=
87
92
some <| fun _ go _ _ content => do
88
93
pure <| .seq <| ← content.mapM fun b => do
89
94
pure <| .seq #[← go b, .raw "\n " ]
90
95
toHtml :=
91
96
open Verso.Doc.Html in
92
97
open Verso.Output.Html in
93
- some <| fun goI goB id _data blocks => do
98
+ some <| fun goI goB id data blocks => do
94
99
if h : blocks.size < 1 then
95
100
HtmlT.logError "Malformed example"
96
101
pure .empty
97
102
else
98
103
let .para description := blocks[0 ]
99
104
| HtmlT.logError "Malformed example - description not paragraph" ; pure .empty
105
+ let opened ←
106
+ match FromJson.fromJson? data (α := Option String × Bool × Option Tag) with
107
+ | .error e => HtmlT.logError s! "Error deserializing example data: { e} " ; pure false
108
+ | .ok (_, opened, _) => pure opened
100
109
let xref ← HtmlT.state
101
- let attrs := xref.htmlId id
110
+ let mut attrs := xref.htmlId id
111
+ if opened then
112
+ attrs := attrs.push ("open" , "" )
102
113
pure {{
103
114
<details class ="example" {{attrs}}>
104
115
<summary class ="description" >{{← description.mapM goI}}</summary>
0 commit comments