Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fleche] Support .tex literate documents #727

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@
- Don't show types of un-expanded goals. We should add an option for
this, but we don't have the cycles (@ejgallego, #730, workarounds
#525 #652)
- Support for `.lv / .v.tex` TeX files with embedded Coq code
(@ejgallego, #727)

# coq-lsp 0.1.8.1: Spring fix
-----------------------------
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ document checking, advanced error recovery, hybrid Coq/markdown document
support, multiple workspace support, positional goals and information panel,
performance data, extensible command-line compiler, plugin system, and more.

See the [coq-lsp User Manual](./etc/doc/USER_MANUAL.md) for more information.

`coq-lsp` aims to provide a seamless, modern interactive theorem proving
experience, as well as to serve as a maintainable platform for research and UI
integration with other projects.
Expand Down
7 changes: 6 additions & 1 deletion coq/workspace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ let load_objs libs =
in
List.(iter rq_file (rev libs))

let fleche_chop_extension basename =
match Filename.chop_suffix_opt ~suffix:".v.tex" basename with
| Some file -> file
| None -> Filename.chop_extension basename

(* We need to compute this with the right load path *)
let dirpath_of_uri ~uri =
let f = Lang.LUri.File.to_string_file uri in
Expand All @@ -282,7 +287,7 @@ let dirpath_of_uri ~uri =
with Not_found -> Libnames.default_root_prefix
in
let f =
try Filename.chop_extension (Filename.basename f)
try fleche_chop_extension (Filename.basename f)
with Invalid_argument _ -> f
in
let id = Names.Id.of_string f in
Expand Down
12 changes: 11 additions & 1 deletion editor/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"url": "https://github.com/ejgallego/coq-lsp"
},
"activationEvents": [
"onLanguage:markdown"
"onLanguage:markdown",
"onLanguage:latex"
],
"contributes": {
"languages": [
Expand All @@ -54,6 +55,15 @@
"extensions": [
".mv"
]
},
{
"id": "latex",
"aliases": [
"LaTeX"
],
"extensions": [
".lv"
]
}
],
"grammars": [
Expand Down
2 changes: 2 additions & 0 deletions editor/code/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export namespace CoqSelector {
export const all: TextDocumentFilter[] = [
{ language: "coq" },
{ language: "markdown", pattern: "**/*.mv" },
{ language: "latex", pattern: "**/*.lv" },
{ language: "latex", pattern: "**/*.v.tex" },
];

// Local Coq files, suitable for interaction with a local server
Expand Down
13 changes: 13 additions & 0 deletions etc/doc/USER_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,22 @@ not fully completed. Also, you can work with bullets and `coq-lsp`
will automatically admit unfinished ones, so you can follow the
natural proof structure.

### Server Status



### Embedded Markdown and LaTeX documents

`coq-lsp` supports checking of TeX and Markdown document with embedded
Coq inside. As of today, to enable this feature you must:

- **markdown**: open a file with `.mv` extension, `coq-lsp` will
recognize code blocks starting with ````coq`.
- **TeX**: open a file with `.lv` extension, `coq-lsp` will recognize
code blocks delimited by `\begin{coq} ... \end{coq}`

As of today, delimiters are expected at the beginning of the line,
don't hesitate to request for further changes based on this feature.

## Coq LSP Settings

Expand Down
82 changes: 82 additions & 0 deletions examples/lists.lv
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
\documentclass{article}

\usepackage{listings}

\lstdefinelanguage{Coq}
{morekeywords={Theorem, Definition}}

\lstnewenvironment{coq}
{
\lstset{
language=Coq,
basicstyle=\ttfamily,
breaklines=true,
columns=fullflexible}
}
{
}

\begin{document}

\section{Welcome to Coq LSP}

\begin{itemize}
\item You can edit this document as you please
\item Coq will recognize the code snippets as Coq
\item You will be able to save the document and link to other documents soon
\end{itemize}

\begin{coq}
From Coq Require Import List.
Import ListNotations.
\end{coq}

\subsection{Here is a simple Proof about Lists}

$$
\forall~x~l,
\mathsf{rev}(l \mathrel{++} [x]) = x \mathrel{::} (\mathsf{rev}~l)
$$

\begin{coq}
Lemma rev_snoc_cons A :
forall (x : A) (l : list A), rev (l ++ [x]) = x :: rev l.
Proof.
induction l.
- reflexivity.
- simpl. rewrite IHl. simpl. reflexivity.
Qed.
\end{coq}

\subsection{Here is another proof depending on it}

Try to update \emph{above} and \textbf{below}:

\begin{coq}
Theorem rev_rev A : forall (l : list A), rev (rev l) = l.
Proof.
induction l.
- reflexivity.
- simpl. rewrite rev_snoc_cons. rewrite IHl.
reflexivity.
Qed.
\end{coq}

Please edit your code here!

\section{Here we do some lambda terms, because we can!}

\begin{coq}
Inductive term :=
| Var : nat -> term
| Abs : term -> term
| Lam : term -> term -> term.
\end{coq}

\end{document}


%%% Local Variables:
%%% mode: LaTeX
%%% TeX-master: "lists"
%%% End:
82 changes: 82 additions & 0 deletions examples/lists.v.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
\documentclass{article}

\usepackage{listings}

\lstdefinelanguage{Coq}
{morekeywords={Theorem, Definition}}

\lstnewenvironment{coq}
{
\lstset{
language=Coq,
basicstyle=\ttfamily,
breaklines=true,
columns=fullflexible}
}
{
}

\begin{document}

\section{Welcome to Coq LSP}

\begin{itemize}
\item You can edit this document as you please
\item Coq will recognize the code snippets as Coq
\item You will be able to save the document and link to other documents soon
\end{itemize}

\begin{coq}
From Coq Require Import List.
Import ListNotations.
\end{coq}

\subsection{Here is a simple Proof about Lists}

$$
\forall~x~l,
\mathsf{rev}(l \mathrel{++} [x]) = x \mathrel{::} (\mathsf{rev}~l)
$$

\begin{coq}
Lemma rev_snoc_cons A :
forall (x : A) (l : list A), rev (l ++ [x]) = x :: rev l.
Proof.
induction l.
- reflexivity.
- simpl. rewrite IHl. simpl. reflexivity.
Qed.
\end{coq}

\subsection{Here is another proof depending on it}

Try to update \emph{above} and \textbf{below}:

\begin{coq}
Theorem rev_rev A : forall (l : list A), rev (rev l) = l.
Proof.
induction l.
- reflexivity.
- simpl. rewrite rev_snoc_cons. rewrite IHl.
reflexivity.
Qed.
\end{coq}

Please edit your code here!

\section{Here we do some lambda terms, because we can!}

\begin{coq}
Inductive term :=
| Var : nat -> term
| Abs : term -> term
| Lam : term -> term -> term.
\end{coq}

\end{document}


%%% Local Variables:
%%% mode: LaTeX
%%% TeX-master: "lists"
%%% End:
19 changes: 19 additions & 0 deletions fleche/contents.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ module Markdown = struct
String.concat "\n" lines
end

module LaTeX = struct
let gen l = String.make (String.length l) ' '

let rec tex_map_lines coq l =
match l with
| [] -> []
| l :: ls ->
(* opening vs closing a markdown block *)
let code_marker = if coq then "\\end{coq}" else "\\begin{coq}" in
if String.equal code_marker l then gen l :: tex_map_lines (not coq) ls
else (if coq then l else gen l) :: tex_map_lines coq ls

let process text =
let lines = String.split_on_char '\n' text in
let lines = tex_map_lines false lines in
String.concat "\n" lines
end

module WaterProof = struct
open Fleche_waterproof.Json

Expand Down Expand Up @@ -124,6 +142,7 @@ let process_contents ~uri ~raw =
let ext = Lang.LUri.File.extension uri in
match ext with
| ".v" -> R.Ok raw
| ".lv" | ".tex" -> R.Ok (LaTeX.process raw)
| ".mv" -> R.Ok (Markdown.process raw)
| ".wpn" -> WaterProof.process raw
| _ -> R.Error "unknown file format"
Expand Down
Loading