From 9ed8aec16a94afde716de2b4ebf64236859a6123 Mon Sep 17 00:00:00 2001
From: Guillaume Petiot
Date: Wed, 21 Feb 2024 15:30:51 +0000
Subject: [PATCH 1/7] Add test
---
test/generators/cases/markup.mli | 2 ++
test/generators/html/Markup.html | 5 +++++
test/generators/latex/Markup.tex | 3 +++
test/generators/man/Markup.3o | 3 +++
4 files changed, 13 insertions(+)
diff --git a/test/generators/cases/markup.mli b/test/generators/cases/markup.mli
index 81d20ec473..2a824cce19 100644
--- a/test/generators/cases/markup.mli
+++ b/test/generators/cases/markup.mli
@@ -57,6 +57,8 @@
Code can appear {b inside [other] markup}. Its display shouldn't be
affected.
+ There is no differences between [a b] and [a
+ b].
{1 Links and references}
diff --git a/test/generators/html/Markup.html b/test/generators/html/Markup.html
index 056e53af61..f41ac6a7a7 100644
--- a/test/generators/html/Markup.html
+++ b/test/generators/html/Markup.html
@@ -123,6 +123,11 @@
Code can appear inside other
markup. Its display
shouldn't be affected.
+ There is no differences between a b
and
+ a
+ b
+ .
+
Links and references
diff --git a/test/generators/latex/Markup.tex b/test/generators/latex/Markup.tex
index 70ecd380fd..a0ae689609 100644
--- a/test/generators/latex/Markup.tex
+++ b/test/generators/latex/Markup.tex
@@ -34,6 +34,9 @@ \subsection{Styling\label{styling}}%
Code can appear \bold{inside \ocamlinlinecode{other} markup}. Its display shouldn't be affected.
+There is no differences between \ocamlinlinecode{a b} and \ocamlinlinecode{a
+ b}.
+
\subsection{Links and references\label{links-and-references}}%
This is a \href{\#}{link}\footnote{\url{\#}}. It sends you to the top of this page. Links can have markup inside them: \href{\#}{\bold{bold}}\footnote{\url{\#}}, \href{\#}{\emph{italics}}\footnote{\url{\#}}, \href{\#}{\emph{emphasis}}\footnote{\url{\#}}, \href{\#}{super\textsuperscript{script}}\footnote{\url{\#}}, \href{\#}{sub\textsubscript{script}}\footnote{\url{\#}}, and \href{\#}{\ocamlinlinecode{code}}\footnote{\url{\#}}. Links can also be nested \emph{\href{\#}{inside}\footnote{\url{\#}}} markup. Links cannot be nested inside each other. This link has no replacement text: \href{\#}{\#}\footnote{\url{\#}}. The text is filled in by odoc. This is a shorthand link: \href{\#}{\#}\footnote{\url{\#}}. The text is also filled in by odoc in this case.
diff --git a/test/generators/man/Markup.3o b/test/generators/man/Markup.3o
index e28eb65f17..cb2cdc6a0f 100644
--- a/test/generators/man/Markup.3o
+++ b/test/generators/man/Markup.3o
@@ -85,6 +85,9 @@ It's possible for two markup elements to appear \fBnext\fR \fIto\fR each other a
This is also true between non-code markup and code\.
.sp
Code can appear \fBinside other markup\fR\. Its display shouldn't be affected\.
+.sp
+There is no differences between a b and a
+ b\.
.nf
.sp
.in 3
From 3acdd04e0c6372fc1e402b78b975ca52fc4f62bf Mon Sep 17 00:00:00 2001
From: Guillaume Petiot
Date: Wed, 21 Feb 2024 15:41:30 +0000
Subject: [PATCH 2/7] Normalize tests in code spans
---
CHANGES.md | 2 ++
src/parser/lexer.mll | 8 +++++---
src/parser/test/test.ml | 6 ++----
test/generators/html/Markup.html | 5 +----
test/generators/latex/Markup.tex | 3 +--
test/generators/man/Markup.3o | 3 +--
6 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index b567b5957b..ad192926be 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,8 @@
- Updated colors for code fragments (@EmileTrotignon, #1023)
- Fixed complexity of looking up `.odoc` files (@panglesd, #1075)
+- Normalize whitespaces in codespans (@gpetiot, #1085)
+ A newline followed by any whitespaces is normalized as one space character.
### Changed
diff --git a/src/parser/lexer.mll b/src/parser/lexer.mll
index 0cde0b4343..ec24c5c3e3 100644
--- a/src/parser/lexer.mll
+++ b/src/parser/lexer.mll
@@ -263,6 +263,8 @@ let horizontal_space =
[' ' '\t']
let newline =
'\n' | "\r\n"
+let whitespace =
+ horizontal_space | newline
let reference_start =
"{!" | "{{!" | "{:" | "{{:"
@@ -609,13 +611,13 @@ and code_span buffer nesting_level start_offset input = parse
{ Buffer.add_char buffer c;
code_span buffer nesting_level start_offset input lexbuf }
- | newline newline
+ | newline whitespace+ as sp
{ warning
input
(Parse_error.not_allowed
- ~what:(Token.describe (`Blank_line "\n\n"))
+ ~what:(Token.describe (`Blank_line sp))
~in_what:(Token.describe (`Code_span "")));
- Buffer.add_char buffer '\n';
+ Buffer.add_char buffer ' ';
code_span buffer nesting_level start_offset input lexbuf }
| eof
diff --git a/src/parser/test/test.ml b/src/parser/test/test.ml
index caed0e7f6e..80403a11b2 100644
--- a/src/parser/test/test.ml
+++ b/src/parser/test/test.ml
@@ -817,8 +817,7 @@ let%expect_test _ =
{|
((output
(((f.ml (1 0) (3 4))
- (paragraph (((f.ml (1 0) (3 4)) (code_span "foo\
- \nbar")))))))
+ (paragraph (((f.ml (1 0) (3 4)) (code_span "foo bar")))))))
(warnings
( "File \"f.ml\", line 1, character 4 to line 3, character 0:\
\nBlank line is not allowed in '[...]' (code)."))) |}]
@@ -829,8 +828,7 @@ let%expect_test _ =
{|
((output
(((f.ml (1 0) (3 4))
- (paragraph (((f.ml (1 0) (3 4)) (code_span "foo\
- \nbar")))))))
+ (paragraph (((f.ml (1 0) (3 4)) (code_span "foo bar")))))))
(warnings
( "File \"f.ml\", line 1, character 4 to line 3, character 0:\
\nBlank line is not allowed in '[...]' (code)."))) |}]
diff --git a/test/generators/html/Markup.html b/test/generators/html/Markup.html
index f41ac6a7a7..0de80bf90f 100644
--- a/test/generators/html/Markup.html
+++ b/test/generators/html/Markup.html
@@ -123,10 +123,7 @@
Code can appear inside other
markup. Its display
shouldn't be affected.
- There is no differences between a b
and
- a
- b
- .
+
There is no differences between a b
and a b
.
Links and references
diff --git a/test/generators/latex/Markup.tex b/test/generators/latex/Markup.tex
index a0ae689609..e69a3afea8 100644
--- a/test/generators/latex/Markup.tex
+++ b/test/generators/latex/Markup.tex
@@ -34,8 +34,7 @@ \subsection{Styling\label{styling}}%
Code can appear \bold{inside \ocamlinlinecode{other} markup}. Its display shouldn't be affected.
-There is no differences between \ocamlinlinecode{a b} and \ocamlinlinecode{a
- b}.
+There is no differences between \ocamlinlinecode{a b} and \ocamlinlinecode{a b}.
\subsection{Links and references\label{links-and-references}}%
This is a \href{\#}{link}\footnote{\url{\#}}. It sends you to the top of this page. Links can have markup inside them: \href{\#}{\bold{bold}}\footnote{\url{\#}}, \href{\#}{\emph{italics}}\footnote{\url{\#}}, \href{\#}{\emph{emphasis}}\footnote{\url{\#}}, \href{\#}{super\textsuperscript{script}}\footnote{\url{\#}}, \href{\#}{sub\textsubscript{script}}\footnote{\url{\#}}, and \href{\#}{\ocamlinlinecode{code}}\footnote{\url{\#}}. Links can also be nested \emph{\href{\#}{inside}\footnote{\url{\#}}} markup. Links cannot be nested inside each other. This link has no replacement text: \href{\#}{\#}\footnote{\url{\#}}. The text is filled in by odoc. This is a shorthand link: \href{\#}{\#}\footnote{\url{\#}}. The text is also filled in by odoc in this case.
diff --git a/test/generators/man/Markup.3o b/test/generators/man/Markup.3o
index cb2cdc6a0f..7e95963afc 100644
--- a/test/generators/man/Markup.3o
+++ b/test/generators/man/Markup.3o
@@ -86,8 +86,7 @@ This is also true between non-code markup and code\.
.sp
Code can appear \fBinside other markup\fR\. Its display shouldn't be affected\.
.sp
-There is no differences between a b and a
- b\.
+There is no differences between a b and a b\.
.nf
.sp
.in 3
From 5a77807392e7f0278ff42d8f2e62d310df03e843 Mon Sep 17 00:00:00 2001
From: Guillaume Petiot
Date: Wed, 21 Feb 2024 15:42:41 +0000
Subject: [PATCH 3/7] Add a test for consecutive spaces
---
test/generators/cases/markup.mli | 2 ++
test/generators/html/Markup.html | 3 +++
test/generators/latex/Markup.tex | 2 ++
test/generators/man/Markup.3o | 2 ++
4 files changed, 9 insertions(+)
diff --git a/test/generators/cases/markup.mli b/test/generators/cases/markup.mli
index 2a824cce19..233d122a60 100644
--- a/test/generators/cases/markup.mli
+++ b/test/generators/cases/markup.mli
@@ -60,6 +60,8 @@
There is no differences between [a b] and [a
b].
+ Consecutive whitespaces not after a newline are conserved as they are: [a b].
+
{1 Links and references}
This is a {{:#} link}. It sends you to the top of this page. Links can have
diff --git a/test/generators/html/Markup.html b/test/generators/html/Markup.html
index 0de80bf90f..5b71cd28ce 100644
--- a/test/generators/html/Markup.html
+++ b/test/generators/html/Markup.html
@@ -125,6 +125,9 @@
There is no differences between a b
and a b
.
+ Consecutive whitespaces not after a newline are conserved as they
+ are: a b
.
+
Links and references
diff --git a/test/generators/latex/Markup.tex b/test/generators/latex/Markup.tex
index e69a3afea8..86767faf45 100644
--- a/test/generators/latex/Markup.tex
+++ b/test/generators/latex/Markup.tex
@@ -36,6 +36,8 @@ \subsection{Styling\label{styling}}%
There is no differences between \ocamlinlinecode{a b} and \ocamlinlinecode{a b}.
+Consecutive whitespaces not after a newline are conserved as they are: \ocamlinlinecode{a b}.
+
\subsection{Links and references\label{links-and-references}}%
This is a \href{\#}{link}\footnote{\url{\#}}. It sends you to the top of this page. Links can have markup inside them: \href{\#}{\bold{bold}}\footnote{\url{\#}}, \href{\#}{\emph{italics}}\footnote{\url{\#}}, \href{\#}{\emph{emphasis}}\footnote{\url{\#}}, \href{\#}{super\textsuperscript{script}}\footnote{\url{\#}}, \href{\#}{sub\textsubscript{script}}\footnote{\url{\#}}, and \href{\#}{\ocamlinlinecode{code}}\footnote{\url{\#}}. Links can also be nested \emph{\href{\#}{inside}\footnote{\url{\#}}} markup. Links cannot be nested inside each other. This link has no replacement text: \href{\#}{\#}\footnote{\url{\#}}. The text is filled in by odoc. This is a shorthand link: \href{\#}{\#}\footnote{\url{\#}}. The text is also filled in by odoc in this case.
diff --git a/test/generators/man/Markup.3o b/test/generators/man/Markup.3o
index 7e95963afc..01f2f3e068 100644
--- a/test/generators/man/Markup.3o
+++ b/test/generators/man/Markup.3o
@@ -87,6 +87,8 @@ This is also true between non-code markup and code\.
Code can appear \fBinside other markup\fR\. Its display shouldn't be affected\.
.sp
There is no differences between a b and a b\.
+.sp
+Consecutive whitespaces not after a newline are conserved as they are: a b\.
.nf
.sp
.in 3
From 8cdb9c9987572990f95b6752ae72b5b5663615b8 Mon Sep 17 00:00:00 2001
From: Guillaume Petiot
Date: Mon, 25 Mar 2024 15:32:23 +0000
Subject: [PATCH 4/7] Only emit a warning when multiple linebreaks
---
src/parser/lexer.mll | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/parser/lexer.mll b/src/parser/lexer.mll
index ec24c5c3e3..f5729289d1 100644
--- a/src/parser/lexer.mll
+++ b/src/parser/lexer.mll
@@ -263,8 +263,6 @@ let horizontal_space =
[' ' '\t']
let newline =
'\n' | "\r\n"
-let whitespace =
- horizontal_space | newline
let reference_start =
"{!" | "{{!" | "{:" | "{{:"
@@ -611,14 +609,17 @@ and code_span buffer nesting_level start_offset input = parse
{ Buffer.add_char buffer c;
code_span buffer nesting_level start_offset input lexbuf }
- | newline whitespace+ as sp
+ | newline horizontal_space* (newline horizontal_space*)+
{ warning
input
(Parse_error.not_allowed
- ~what:(Token.describe (`Blank_line sp))
+ ~what:(Token.describe (`Blank_line "\n\n"))
~in_what:(Token.describe (`Code_span "")));
Buffer.add_char buffer ' ';
code_span buffer nesting_level start_offset input lexbuf }
+ | newline horizontal_space+
+ { Buffer.add_char buffer ' ';
+ code_span buffer nesting_level start_offset input lexbuf }
| eof
{ warning
From 750343e2f5bb54ed3f00a2cf32eeeb10d674d8d2 Mon Sep 17 00:00:00 2001
From: "Guillaume \"Liam\" Petiot"
Date: Mon, 25 Mar 2024 16:30:49 +0000
Subject: [PATCH 5/7] Update src/parser/lexer.mll
Co-authored-by: panglesd
---
src/parser/lexer.mll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/parser/lexer.mll b/src/parser/lexer.mll
index f5729289d1..6e678463d8 100644
--- a/src/parser/lexer.mll
+++ b/src/parser/lexer.mll
@@ -617,7 +617,7 @@ and code_span buffer nesting_level start_offset input = parse
~in_what:(Token.describe (`Code_span "")));
Buffer.add_char buffer ' ';
code_span buffer nesting_level start_offset input lexbuf }
- | newline horizontal_space+
+ | newline horizontal_space*
{ Buffer.add_char buffer ' ';
code_span buffer nesting_level start_offset input lexbuf }
From 88db2e73cd8f7fc49ba88d889b3793115792a0f9 Mon Sep 17 00:00:00 2001
From: Paul-Elliot
Date: Tue, 26 Mar 2024 18:33:44 +0100
Subject: [PATCH 6/7] Promote tests for normalized whitespace in code spans
Signed-off-by: Paul-Elliot
---
src/parser/test/test.ml | 6 ++----
test/model/semantics/test.ml | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/parser/test/test.ml b/src/parser/test/test.ml
index 80403a11b2..5d74485c16 100644
--- a/src/parser/test/test.ml
+++ b/src/parser/test/test.ml
@@ -797,8 +797,7 @@ let%expect_test _ =
{|
((output
(((f.ml (1 0) (2 4))
- (paragraph (((f.ml (1 0) (2 4)) (code_span "foo\
- \nbar")))))))
+ (paragraph (((f.ml (1 0) (2 4)) (code_span "foo bar")))))))
(warnings ())) |}]
let cr_lf_preserved =
@@ -807,8 +806,7 @@ let%expect_test _ =
{|
((output
(((f.ml (1 0) (2 4))
- (paragraph (((f.ml (1 0) (2 4)) (code_span "foo\r\
- \nbar")))))))
+ (paragraph (((f.ml (1 0) (2 4)) (code_span "foo bar")))))))
(warnings ())) |}]
let no_double_new_line =
diff --git a/test/model/semantics/test.ml b/test/model/semantics/test.ml
index 5460e18824..d9bafb990a 100644
--- a/test/model/semantics/test.ml
+++ b/test/model/semantics/test.ml
@@ -551,7 +551,7 @@ let%expect_test _ =
test "{2 [foo\nbar\r\nbaz]}";
[%expect
{|
- {"value":[{"`Heading":[{"heading_level":"`Subsection","heading_label_explicit":"false"},{"`Label":[{"`Page":["None","f.ml"]},"foo-bar--baz"]},[{"`Code_span":"foo\nbar\r\nbaz"}]]}],"warnings":[]} |}]
+ {"value":[{"`Heading":[{"heading_level":"`Subsection","heading_label_explicit":"false"},{"`Label":[{"`Page":["None","f.ml"]},"foo-bar-baz"]},[{"`Code_span":"foo bar baz"}]]}],"warnings":[]} |}]
let nested_style =
test "{2 {e foo bar}}";
From c0cd9dc9703d2d332631c3ac937db853577c5e98 Mon Sep 17 00:00:00 2001
From: Paul-Elliot
Date: Tue, 26 Mar 2024 18:38:52 +0100
Subject: [PATCH 7/7] Mention line breaks in code spans in the documentation
Signed-off-by: Paul-Elliot
---
doc/odoc_for_authors.mld | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/doc/odoc_for_authors.mld b/doc/odoc_for_authors.mld
index 11d32bbbd2..0e39402ee7 100644
--- a/doc/odoc_for_authors.mld
+++ b/doc/odoc_for_authors.mld
@@ -276,6 +276,22 @@ For inline, language agnostic source code style, use square brackets: [ [ ... ]
(** Here, [f 0] is [None] *)
]}
+Two newlines in a row in an inline codeblock are forbidden, but in the interest
+of the 80 char rule, a single newline followed by horizontal space in an inline
+codeblock is considered as a single space:
+
+{[
+(**
+ A very loooooooooooooooooooooooong line and [List.map (fun x -> x +1)].
+
+ is equivalent to:
+
+ A very loooooooooooooooooooooooong line and [List.map
+ (fun x -> x +1)].
+
+*)
+]}
+
All the other existing ways to insert code are meant to be used for code blocks,
not inline code fragments. Those will be formatted as a code block and will end
the paragraph. Attempting to use them inline will trigger a warning.