import Lean.Elab.Command set_option doc.verso true /-! # Verso Docstring Markdown Tests This module tests the Markdown rendering of all the builtin Verso docstring operators. Each section begins with a command that will fail when a new, untested operator is added. ## Helpers -/ section open Lean Elab Command Term private def toMarkdown : VersoDocString → String | .mk bs ps => Doc.MarkdownM.run' do let blockLines ← bs.mapM Doc.ToMarkdown.toMarkdown let partLines ← ps.mapM Doc.ToMarkdown.toMarkdown return Doc.joinBlocks (blockLines ++ partLines) private def manualRw (md : String) : String := md.replace manualRoot "$MANUAL_ROOT/" elab "#verso_to_markdown " name:ident : command => do let env ← getEnv runTermElabM fun _ => do let declName ← realizeGlobalConstNoOverloadWithInfo name match (← findInternalDocString? env declName (includeBuiltin := true)) with | some (.inl ..) => throwError m!"`{.ofConstName declName}` has a Markdown docstring" | some (.inr verso) => logInfo (manualRw (toMarkdown verso)) | none => throwError m!"`{.ofConstName declName}` has no docstring" /-! ## Code Blocks -/ /-- info: #[Lean.Doc.lean, Lean.Doc.leanTerm, Lean.Doc.output] -/ #guard_msgs in #eval show CommandElabM Unit from do let builtinBlocks ← Doc.builtinDocCodeBlocks.get let blockNames := builtinBlocks.keysArray |>.qsort (fun x y => x.toString < y.toString) IO.println blockNames /-- ```lean example : codeblockTest 4 5 = 9 := by rfl ``` ```leanTerm codeblockTest 4 5 ``` ```lean (name := x) #eval codeblockTest 4 5 ``` ```output x 9 ``` -/ def codeblockTest (x y : Nat) := x + y /-- info: ``` example : codeblockTest 4 5 = 9 := by rfl ``` ``` codeblockTest 4 5 ``` ``` #eval codeblockTest 4 5 ``` ``` 9 ``` -/ #guard_msgs in #verso_to_markdown codeblockTest /-! ## Directives There are no builtin directives, but should any be added, they must be tested. -/ /-- info: #[] -/ #guard_msgs in #eval show CommandElabM Unit from do let builtinBlocks ← Doc.builtinDocDirectives.get let blockNames := builtinBlocks.keysArray |>.qsort (fun x y => x.toString < y.toString) IO.println blockNames /-! ## Commands -/ /-- info: #[Lean.Doc.open, Lean.Doc.set_option] -/ #guard_msgs in #eval show CommandElabM Unit from do let builtinBlocks ← Doc.builtinDocCommands.get let blockNames := builtinBlocks.keysArray |>.qsort (fun x y => x.toString < y.toString) IO.println blockNames namespace X def z := 5 end X /-- None of these commands should appear in the output: {open X} {set_option pp.all true} -/ def commandTests (x y : Nat) : Nat := x + y /-- info: None of these commands should appear in the output: -/ #guard_msgs in #verso_to_markdown commandTests /-! ## Roles -/ /-- info: Lean.Doc.assert Lean.Doc.assert' Lean.Doc.attr Lean.Doc.conv Lean.Doc.given Lean.Doc.givenInstance Lean.Doc.kw Lean.Doc.kw! Lean.Doc.kw? Lean.Doc.lean Lean.Doc.lit Lean.Doc.manual Lean.Doc.module Lean.Doc.name Lean.Doc.option Lean.Doc.syntax Lean.Doc.syntaxCat Lean.Doc.tactic -/ #guard_msgs in #eval show CommandElabM Unit from do let builtinRoles ← Doc.builtinDocRoles.get let blockNames := builtinRoles.keysArray |>.qsort (fun x y => x.toString < y.toString) blockNames.forM (IO.println ·) /-- Because {assert}`assertTests 2 4 = 6`, it must certainly be addition. -/ def assertTests (x y : Nat) := x + y /-- info: Because `assertTests 2 4 = 6`, it must certainly be addition. -/ #guard_msgs in #verso_to_markdown assertTests -- assert' not tested here because it's for bootstrapping and doesn't work outside early Prelude /-- The attribute {attr}`simp` registers a simp lemma. Use {attr}`@[simp]`. -/ def attrTests (x y : Nat) := x + y /-- info: The attribute `simp` registers a simp lemma. Use `@[simp]`. -/ #guard_msgs in #verso_to_markdown attrTests /-- The {conv}`fun` tactic -/ def convTests (x y : Nat) := x + y /-- info: The `fun` tactic -/ #guard_msgs in #verso_to_markdown convTests /-- Invisible: {given -show}`m : Nat` Visible: * For {given}`n`, {assert}`givenTests n n = n - n`. * For {given}`n, k : Nat`, {assert}`givenTests n k = n - k`. * For {given}`n, k`, {assert}`givenTests n k = n - k`. * For {given (type:="Nat")}`k`, {assert}`givenTests m k = m - k`. -/ def givenTests (x y : Nat) : Nat := x - y /-- {given -show}`α : Type, β : Type, γ : Type` {given -show}`x : α, y : α, z : α` Invisible: {givenInstance -show}`Add α` {givenInstance -show}`addInst : Add β` There is an {lean}`addInst : Add β` and an {lean}`inferInstance : Add α`, and {lean}`x + y + z`. Visible: {givenInstance}`Add γ`&{givenInstance}`addInst : OfNat γ 5` Check: {lean}`(5 : γ) + 5` -/ def givenInstanceTests (x y : Nat) : Nat := x - y /-- info: ⏎ Invisible: ⏎ There is an `addInst : Add β` and an `inferInstance : Add α`, and `x + y + z`. Visible: `Add γ`&`addInst : OfNat γ 5` Check: `(5 : γ) + 5` -/ #guard_msgs in #verso_to_markdown givenInstanceTests /-- info: Invisible: ⏎ Visible: * For `n`, `givenTests n n = n - n`. * For `n`, `k : Nat`, `givenTests n k = n - k`. * For `n`, `k`, `givenTests n k = n - k`. * For `k`, `givenTests m k = m - k`. -/ #guard_msgs in #verso_to_markdown givenTests /-- info: Hint: Specify the syntax kind: kw?̵ ̲(̲o̲f̲ ̲:̲=̲ ̲P̲a̲r̲s̲e̲r̲.̲T̲a̲c̲t̲i̲c̲.̲C̲o̲n̲v̲.̲f̲u̲n̲)̲ -/ #guard_msgs in /-- * {kw (of := termIfThenElse)}`if` * {kw! (of := Lean.Parser.Term.fun)}`fun` * {kw?}`fun` -/ def kwTests := () /-- info: * `if` * `fun` * `fun` -/ #guard_msgs in #verso_to_markdown kwTests /-- {lit}`$ ls -l`-/ def litTests := () /-- info: `$ ls -l` -/ #guard_msgs in #verso_to_markdown litTests /-- 1. {lean}`2 + 2` 2. {lean (type :="Int")}`2 + 2` -/ def leanRoleTests := () /-- info: 1. `2 + 2` 2. `2 + 2` -/ #guard_msgs in #verso_to_markdown leanRoleTests /-- Link: {manual section "bar"}[link text] and done and {manual errorExplanation "errorId"}[other link] -/ def manualLinkTests := () /-- info: Link: [link text]($MANUAL_ROOT/find/?domain=Verso.Genre.Manual.section&name=bar) and done and [other link]($MANUAL_ROOT/find/?domain=Manual.errorExplanation&name=errorId) -/ #guard_msgs in #verso_to_markdown manualLinkTests /-- {module -checked}`NoModule` and {module}`Init` -/ def moduleTests := () /-- info: `NoModule` and `Init` -/ #guard_msgs in #verso_to_markdown moduleTests /-- Argument names: {name}`x`{name}`z`{name (full := X.z)}`z` -/ def nameTests (x y z : Nat) := x - y + z -- IMPORTANT: This has zero-width spaces between the code inlines. When updating the file, make sure -- they're present. /-- info: Argument names: `x`​`z`​`z` -/ #guard_msgs in #verso_to_markdown nameTests /-- * {option}`pp.all` * {option}`set_option pp.all true` -/ def optionTests := () /-- info: * `pp.all` * `set_option pp.all true` -/ #guard_msgs in #verso_to_markdown optionTests set_option linter.unusedVariables false in /-- Tests: 1. {syntaxCat}`term` 2. {syntax level}`$x + $y` A level: {name}`x` -/ def syntaxTests := () /-- info: Tests: 1. `term` 2. `$x + $y` A level: `x` -/ #guard_msgs in #verso_to_markdown syntaxTests /-- {tactic}`intros` -/ def tacticTests := () /-- info: `intros` -/ #guard_msgs in #verso_to_markdown tacticTests