@@ -213,13 +213,12 @@ private def toHighlightedLeanInline (shouldShow : Bool) (hls : Highlighted) (str
213213 ``(Inline.other (Verso.Genre.Manual.InlineLean.Inline.lean $(← quoteHighlightViaSerialization hls)) #[Inline.code $(quote str.getString)])
214214
215215
216- /--
217- Elaborates the provided Lean command in the context of the current Verso module.
218- -/
219- @[code_block]
220- def lean : CodeBlockExpanderOf LeanBlockConfig
221- | config, str => withoutAsync <| do
222-
216+ def elabCommands (config : LeanBlockConfig) (str : StrLit)
217+ (toHighlightedLeanContent : (shouldShow : Bool) → (hls : Highlighted) → (str: StrLit) → DocElabM Term)
218+ (minCommands : Option Nat := none)
219+ (maxCommands : Option Nat := none) :
220+ DocElabM Term :=
221+ withoutAsync <| do
223222 PointOfInterest.save (← getRef) ((config.name.map (·.toString)).getD (abbrevFirstLine 20 str.getString))
224223 (kind := Lsp.SymbolKind.file)
225224 (detail? := some ("Lean code" ++ config.outlineMeta))
@@ -247,14 +246,24 @@ def lean : CodeBlockExpanderOf LeanBlockConfig
247246 let (cmd, ps', messages) := Parser.parseCommand ictx pmctx pstate cmdState.messages
248247 cmds := cmds.push cmd
249248 pstate := ps'
250- cmdState := {cmdState with messages := messages}
249+ cmdState := { cmdState with messages := messages }
251250
252251
253252 cmdState ← withInfoTreeContext (mkInfoTree := pure ∘ InfoTree.node (.ofCommandInfo {elaborator := `Manual.Meta.lean, stx := cmd})) <|
254253 runCommand (Command.elabCommand cmd) cmd cctx cmdState
255254
256255 if Parser.isTerminalCommand cmd then break
257256
257+ let nonTerm := cmds.filter (! Parser.isTerminalCommand ·)
258+ if let some maxCmds := maxCommands then
259+ if h : nonTerm.size > maxCmds then
260+ logErrorAt nonTerm.back m! "Expected at most { maxCmds} commands, but got { nonTerm.size} commands."
261+
262+ if let some minCmds := minCommands then
263+ if h : nonTerm.size < minCmds then
264+ let blame := nonTerm[0 ]? |>.getD (← getRef)
265+ logErrorAt blame m! "Expected at least { minCmds} commands, but got { nonTerm.size} commands."
266+
258267 let origEnv ← getEnv
259268 try
260269 setEnv cmdState.env
@@ -271,7 +280,7 @@ def lean : CodeBlockExpanderOf LeanBlockConfig
271280 hls := hls ++ (← highlightIncludingUnparsed cmd nonSilentMsgs cmdState.infoState.trees (startPos? := lastPos))
272281 lastPos := (cmd.getTrailingTailPos?).getD lastPos
273282
274- toHighlightedLeanBlock config.show hls str
283+ toHighlightedLeanContent config.show hls str
275284 finally
276285 if !config.keep then
277286 setEnv origEnv
@@ -308,6 +317,22 @@ where
308317 | .error _ => pure cmdState
309318 | .ok ((), cmdState) => pure cmdState
310319
320+ /--
321+ Elaborates the provided Lean command in the context of the current Verso module.
322+ -/
323+ @[code_block]
324+ def lean : CodeBlockExpanderOf LeanBlockConfig
325+ | config, str => elabCommands config str toHighlightedLeanBlock
326+
327+ @[role]
328+ def leanCommand : RoleExpanderOf LeanBlockConfig
329+ | config, inls => do
330+ if let some str ← oneCodeStr? inls then
331+ elabCommands config str toHighlightedLeanInline (minCommands := some 1 ) (maxCommands := some 1 )
332+ else
333+ `(sorry )
334+
335+
311336/--
312337Elaborates the provided Lean term in the context of the current Verso module.
313338-/
0 commit comments