/- Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved. Released under Apache 2.0 license. Authors: Joseph Tooby-Smith -/ import Mathlib.Lean.Expr.Basic /-! ## Underlying structure for notes This file contains the necessary structures that must be imported into a file for it to be turned into a Lean note. It allows for the - `note ...` command to be used to add notes to a Lean file - `note_attr` attribute to be used to display formally verified commands within a note. - `note_attr_informal` attribute to be used to display informal commands within a note. Other results relating to notes are in other files. -/ namespace HepLean open Lean /-- The information from a `note ...` command. To be used in a note file-/ structure NoteInfo where /-- The content of the note. -/ content : String /-- The file name where the note came from. -/ fileName : Name /-- The line from where the note came from. -/ line : Nat /-- Environment extension to store `note ...`. -/ initialize noteExtension : SimplePersistentEnvExtension NoteInfo (Array NoteInfo) ← registerSimplePersistentEnvExtension { name := `noteExtension addEntryFn := fun arr nodeInfor => arr.push nodeInfor addImportedFn := fun es => es.foldl (· ++ ·) #[] } /-- Syntax for the `note ...` command -/ syntax (name := note_comment) "note " str : command /-- Elaborator for the `note ...` command -/ @[command_elab note_comment] def elabNote : Lean.Elab.Command.CommandElab := fun stx => match stx with | `(note $s) => do let str : String := s.getString let pos := stx.getPos? match pos with | some pos => do let env ← getEnv let fileMap ← getFileMap let filePos := fileMap.toPosition pos let line := filePos.line let modName := env.mainModule let noteInfo : NoteInfo := { content := str, fileName := modName, line := line } modifyEnv fun env => noteExtension.addEntry env noteInfo | none => throwError "Invalid syntax for `note` command" | _ => throwError "Invalid syntax for `note` command" /-! ## Note attribute -/ /-- Environment extension to store `note_attr`. -/ initialize noteDeclExtension : SimplePersistentEnvExtension Name (Array Name) ← registerSimplePersistentEnvExtension { name := `noteDeclExtension addEntryFn := fun arr nodeInfor => arr.push nodeInfor addImportedFn := fun es => es.foldl (· ++ ·) #[] } /-- The `note_attr` attribute is used to display formally verified commands within a note. -/ initialize noteAttribute : Unit ← registerBuiltinAttribute { name := `note_attr descr := "Note attribute" applicationTime := AttributeApplicationTime.afterCompilation add := fun declName _ _ => do modifyEnv fun env => noteDeclExtension.addEntry env declName } /-- Environment extension to store `note_attr_informal`. -/ initialize noteInformalDeclExtension : SimplePersistentEnvExtension Name (Array Name) ← registerSimplePersistentEnvExtension { name := `noteInformalDeclExtension addEntryFn := fun arr nodeInfor => arr.push nodeInfor addImportedFn := fun es => es.foldl (· ++ ·) #[] } /-- The `note_attr_informal` attribute is used to display informal commands within a note. -/ initialize noteInformalAttribute : Unit ← registerBuiltinAttribute { name := `note_attr_informal descr := "Informal note attribute" applicationTime := AttributeApplicationTime.afterCompilation add := fun declName _ _ => do modifyEnv fun env => noteInformalDeclExtension.addEntry env declName } end HepLean