Add visual indicator to lexical errors in code snippets
This commit is contained in:
parent
76aad9cd8a
commit
2fb095896b
@ -1,10 +1,17 @@
|
|||||||
---
|
---
|
||||||
import { native_highlighter } from "../lexer/highlighter";
|
import { native_highlighter } from "../lexer/highlighter";
|
||||||
|
import CodeError from "./docs/CodeError.astro";
|
||||||
|
|
||||||
const { thpcode } = Astro.props;
|
const { thpcode } = Astro.props;
|
||||||
|
|
||||||
const native_html = await native_highlighter(thpcode);
|
const [native_html, error_message] = await native_highlighter(thpcode);
|
||||||
---
|
---
|
||||||
|
|
||||||
<pre
|
<pre
|
||||||
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp</span></pre>
|
class="language-thp"><code class="language-thp" set:html={native_html} /><span class="absolute top-2 right-2 inline-block text-sm select-none opacity-75">thp
|
||||||
|
</span></pre>
|
||||||
|
{
|
||||||
|
error_message !== null && (
|
||||||
|
<CodeError error_type="Lexical">{error_message}</CodeError>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
8
src/components/docs/CodeError.astro
Normal file
8
src/components/docs/CodeError.astro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
const { error_type = "Unknown" } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="px-4 py-2 rounded bg-red-200 dark:bg-red-950">
|
||||||
|
<span class="inline-block font-bold">{error_type} error:</span>
|
||||||
|
<slot />
|
||||||
|
</div>
|
@ -45,13 +45,13 @@ export interface LexError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function native_highlighter(code: string): Promise<string> {
|
export async function native_highlighter(code: string): Promise<[string, string | null]> {
|
||||||
let formatted_code = leftTrimDedent(code).join("\n");
|
let formatted_code = leftTrimDedent(code).join("\n");
|
||||||
|
|
||||||
const result = await native_lex(formatted_code);
|
const result = await native_lex(formatted_code);
|
||||||
|
|
||||||
if (result.Err) {
|
if (result.Err) {
|
||||||
throw new Error(JSON.stringify(result.Err.Lex) + "\n" + code);
|
return lex_error_highlighter(formatted_code, result.Err!.Lex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokens = result.Ok!;
|
const tokens = result.Ok!;
|
||||||
@ -82,7 +82,27 @@ export async function native_highlighter(code: string): Promise<string> {
|
|||||||
current_pos = token_end;
|
current_pos = token_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return [output, null];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlights code that has a lexic error
|
||||||
|
*/
|
||||||
|
function lex_error_highlighter(code: string, error: LexError): [string, string] {
|
||||||
|
// Create a single error token
|
||||||
|
|
||||||
|
const err_pos = error.position;
|
||||||
|
const before_err = code.substring(0, err_pos);
|
||||||
|
const err_str = code[err_pos];
|
||||||
|
const after_err = code.substring(err_pos + 1);
|
||||||
|
|
||||||
|
const token = `<span class="token underline decoration-wavy decoration-red-500">${err_str}</span>`;
|
||||||
|
|
||||||
|
const all = `${before_err}${token}${after_err}`;
|
||||||
|
|
||||||
|
// TODO: Transform absolute posijion (error.position) into line:column
|
||||||
|
return [all, error.reason + " at position " + error.position]
|
||||||
}
|
}
|
||||||
|
|
||||||
function translate_token_type(tt: TokenType, value: string): string {
|
function translate_token_type(tt: TokenType, value: string): string {
|
||||||
|
@ -5,3 +5,11 @@ title: Readonly
|
|||||||
import Code from "../../../components/Code.astro"
|
import Code from "../../../components/Code.astro"
|
||||||
|
|
||||||
# Readonly
|
# Readonly
|
||||||
|
|
||||||
|
<Code thpcode={`
|
||||||
|
class Caño
|
||||||
|
{
|
||||||
|
}
|
||||||
|
`} />
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,11 +57,11 @@ fun UserDetail(User user) -> HTML
|
|||||||
{
|
{
|
||||||
<div>
|
<div>
|
||||||
@match user.type
|
@match user.type
|
||||||
case ::Admin
|
@case ::Admin
|
||||||
{
|
{
|
||||||
<button>Delete resource</button>
|
<button>Delete resource</button>
|
||||||
}
|
}
|
||||||
case ::User
|
@case ::User
|
||||||
{
|
{
|
||||||
<button disable>Not allowed</button>
|
<button disable>Not allowed</button>
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user