Skip to content

Commit

Permalink
vdoc: fix issues related to markdown codeblocks in vdoc generate (#21248
Browse files Browse the repository at this point in the history
)
  • Loading branch information
ttytm authored Apr 11, 2024
1 parent d33ad62 commit af4111b
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 9 deletions.
17 changes: 9 additions & 8 deletions cmd/tools/vdoc/html.v
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,13 @@ fn html_highlight(code string, tb &ast.Table) string {
}

buf.write_string('<span class="token ${final_tok_typ}">')
write_token(tok, tok_typ, mut buf)
if tok_typ == .string {
// Make sure to escape html in strings. Otherwise it will rendered in the
// html documentation outputs / its style rules will affect the readme.
buf.write_string("'${html.escape(tok.lit.str())}'")
} else {
write_token(tok, tok_typ, mut buf)
}
buf.write_string('</span>')
}

Expand Down Expand Up @@ -627,15 +633,10 @@ fn (f &MdHtmlCodeHighlighter) transform_attribute(p markdown.ParentType, name st
}

fn (f &MdHtmlCodeHighlighter) transform_content(parent markdown.ParentType, text string) string {
// NOTE: markdown.default_html_transformer uses html.escape internally.
initial_transformed_text := markdown.default_html_transformer.transform_content(parent,
text)
if parent is markdown.MD_BLOCKTYPE && parent == .md_block_code {
if f.language == 'v' || f.language == 'vlang' {
return html_highlight(html.unescape(initial_transformed_text), f.table)
}
return html_highlight(text, f.table)
}
return initial_transformed_text
return text
}

fn (mut f MdHtmlCodeHighlighter) config_set(key string, val string) {
Expand Down
51 changes: 51 additions & 0 deletions cmd/tools/vdoc/tests/testdata/output_formats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,54 @@ fn auth_verify(secret string, token string) bool {
return hmac.equal(signature_from_token, signature_mirror)
}
```

### Other language specifiers

```cpp
#include <iostream>
#include <map>

std::map<std::string, int> my_map {
{"KEY_1", 0},
{"KEY_2", 10},
};

for (const auto &[key, value] : my_map) {
std::cout << key << ": " << value << ", ";
}
std::cout << "\n";
```

```v ignore
doc1 := toml.parse_text(<string content>) or { panic(err) }
doc2 := toml.parse_file(<file path>) or { panic(err) }
```

### Escape html in strings

```v
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
background: linear-gradient(to right, #274060, #1B2845);
color: GhostWhite;
font-family: sans-serif;
text-align: center;
}
</style>
</head>
<body>
<h1>Your App Content!</h1>
<button onclick="callV()">Call V!</button>
</body>
<script>
async function callV() {
// Call a V function that takes an argument and returns a value.
const res = await window.my_v_func(\'Hello from JS!\');
console.log(res);
}
</script>
</html>'
```
94 changes: 94 additions & 0 deletions cmd/tools/vdoc/tests/testdata/output_formats/main.ansi
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,49 @@ fn auth_verify(secret string, token string) bool {
signature_from_token := base64.url_decode(token_split[2])
return hmac.equal(signature_from_token, signature_mirror)
}

Other language specifiers
#include <iostream>
#include <map>

std::map<std::string, int> my_map {
{"KEY_1", 0},
{"KEY_2", 10},
};

for (const auto &[key, value] : my_map) {
std::cout << key << ": " << value << ", ";
}
std::cout << "\n";

doc1 := toml.parse_text(<string content>) or { panic(err) }
doc2 := toml.parse_file(<file path>) or { panic(err) }

Escape html in strings
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
background: linear-gradient(to right, #274060, #1B2845);
color: GhostWhite;
font-family: sans-serif;
text-align: center;
}
</style>
</head>
<body>
<h1>Your App Content!</h1>
<button onclick="callV()">Call V!</button>
</body>
<script>
async function callV() {
// Call a V function that takes an argument and returns a value.
const res = await window.my_v_func(\'Hello from JS!\');
console.log(res);
}
</script>
</html>'
module main
## Description

Expand Down Expand Up @@ -149,6 +192,57 @@ fn auth_verify(secret string, token string) bool {
}
```

### Other language specifiers

```cpp
#include <iostream>
#include <map>

std::map<std::string, int> my_map {
{"KEY_1", 0},
{"KEY_2", 10},
};

for (const auto &[key, value] : my_map) {
std::cout << key << ": " << value << ", ";
}
std::cout << "\n";
```

```v ignore
doc1 := toml.parse_text(<string content>) or { panic(err) }
doc2 := toml.parse_file(<file path>) or { panic(err) }
```

### Escape html in strings

```v
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
background: linear-gradient(to right, #274060, #1B2845);
color: GhostWhite;
font-family: sans-serif;
text-align: center;
}
</style>
</head>
<body>
<h1>Your App Content!</h1>
<button onclick="callV()">Call V!</button>
</body>
<script>
async function callV() {
// Call a V function that takes an argument and returns a value.
const res = await window.my_v_func(\'Hello from JS!\');
console.log(res);
}
</script>
</html>'
```


const omega = 3 // should be first
const alpha = 5 // should be in the middle
Expand Down
35 changes: 34 additions & 1 deletion cmd/tools/vdoc/tests/testdata/output_formats/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,40 @@ <h2>Description</h2><p>This is an example of a an .md file, used for adding more
sha256<span class="token punctuation">.</span>sum<span class="token punctuation">,</span> sha256<span class="token punctuation">.</span>block_size<span class="token punctuation">)</span>
signature_from_token <span class="token operator">:=</span> base64<span class="token punctuation">.</span><span class="token function">url_decode</span><span class="token punctuation">(</span>token_split<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> hmac<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span>signature_from_token<span class="token punctuation">,</span> signature_mirror<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<span class="token punctuation">}</span></code></pre><h3>Other language specifiers</h3><pre><code class="language-cpp">##
std<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token builtin">map</span><span class="token operator"><</span>std<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token operator">></span> <span class="token symbol">my_map</span> <span class="token punctuation">{</span>
<span class="token punctuation">{</span><span class="token string">'KEY_1'</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span><span class="token string">'KEY_2'</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> auto <span class="token operator">&</span><span class="token punctuation">[</span>key<span class="token punctuation">,</span> value<span class="token punctuation">]</span> <span class="token punctuation">:</span> my_map<span class="token punctuation">)</span> <span class="token punctuation">{</span>
std<span class="token punctuation">:</span><span class="token punctuation">:</span>cout <span class="token operator"><<</span> key <span class="token operator"><<</span> <span class="token string">': '</span> <span class="token operator"><<</span> value <span class="token operator"><<</span> <span class="token string">', '</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
std<span class="token punctuation">:</span><span class="token punctuation">:</span>cout <span class="token operator"><<</span> <span class="token string">'\n'</span><span class="token punctuation">;</span></code></pre><pre><code class="language-v">doc1 <span class="token operator">:=</span> toml<span class="token punctuation">.</span><span class="token function">parse_text</span><span class="token punctuation">(</span><span class="token operator"><</span><span class="token builtin">string</span> content<span class="token operator">></span><span class="token punctuation">)</span> <span class="token keyword">or</span> <span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span>
doc2 <span class="token operator">:=</span> toml<span class="token punctuation">.</span><span class="token function">parse_file</span><span class="token punctuation">(</span><span class="token operator"><</span>file path<span class="token operator">></span><span class="token punctuation">)</span> <span class="token keyword">or</span> <span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span></code></pre><h3>Escape html in strings</h3><pre><code class="language-v"><span class="token keyword">const</span> html <span class="token operator">=</span> <span class="token string">'&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;en&#34;&gt;
&lt;head&gt;
&lt;style&gt;
body {
background: linear-gradient(to right, #274060, #1B2845);
color: GhostWhite;
font-family: sans-serif;
text-align: center;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Your App Content!&lt;/h1&gt;
&lt;button onclick=&#34;callV()&#34;&gt;Call V!&lt;/button&gt;
&lt;/body&gt;
&lt;script&gt;
async function callV() {
// Call a V function that takes an argument and returns a value.
const res = await window.my_v_func(\&#39;Hello from JS!\&#39;);
console.log(res);
}
&lt;/script&gt;
&lt;/html&gt;'</span></code></pre>

</section>

Expand Down
51 changes: 51 additions & 0 deletions cmd/tools/vdoc/tests/testdata/output_formats/main.text
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,57 @@ module main
}
```

### Other language specifiers

```cpp
#include <iostream>
#include <map>

std::map<std::string, int> my_map {
{"KEY_1", 0},
{"KEY_2", 10},
};

for (const auto &[key, value] : my_map) {
std::cout << key << ": " << value << ", ";
}
std::cout << "\n";
```

```v ignore
doc1 := toml.parse_text(<string content>) or { panic(err) }
doc2 := toml.parse_file(<file path>) or { panic(err) }
```

### Escape html in strings

```v
const html = '<!DOCTYPE html>
<html lang="en">
<head>
<style>
body {
background: linear-gradient(to right, #274060, #1B2845);
color: GhostWhite;
font-family: sans-serif;
text-align: center;
}
</style>
</head>
<body>
<h1>Your App Content!</h1>
<button onclick="callV()">Call V!</button>
</body>
<script>
async function callV() {
// Call a V function that takes an argument and returns a value.
const res = await window.my_v_func(\'Hello from JS!\');
console.log(res);
}
</script>
</html>'
```


const omega = 3 // should be first
const alpha = 5 // should be in the middle
Expand Down

0 comments on commit af4111b

Please sign in to comment.