mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-01 20:31:27 +00:00
Improve syntax highlighting in the language reference
Highlight all Slint code and don't do the preview on snippets where it doesn't make sense. Some snippets, such as the bare statement or expression snippets, are now highlighted, but they are continued to be excluded from the doctest.
This commit is contained in:
parent
1891e4489a
commit
ed5b76e7fc
5 changed files with 46 additions and 28 deletions
|
|
@ -59,7 +59,7 @@ Slint comes with a markup language that is specifically designed for user interf
|
|||
powerful way to describe graphical elements, their placement, and the flow of data through the different states. It is a familiar syntax to describe the hierarchy
|
||||
of elements and property bindings. Here's the obligatory "Hello World":
|
||||
|
||||
.. code-block:: slint-no-preview
|
||||
.. code-block:: slint,ignore
|
||||
|
||||
HelloWorld := Window {
|
||||
width: 400px;
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ You can also declare your own properties. The properties declared at the top lev
|
|||
component are public and can be accessed by the component using it as an element, or using the
|
||||
language bindings:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
// declare a property of type int with the name `my-property`
|
||||
property<int> my-property;
|
||||
|
|
@ -186,7 +186,7 @@ together.
|
|||
The right hand side of the `<=>` must be a reference to a property of the same type.
|
||||
The type can be omitted in a property declaration to have the type automatically inferred.
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Window {
|
||||
property<brush> rect-color <=> r.background;
|
||||
// it is allowed to omit the type to have it automatically inferred
|
||||
|
|
@ -227,7 +227,7 @@ Anonymous structs type can be declared with curly braces: `{ identifier1: type2,
|
|||
The trailing semicolon is optional.
|
||||
They can be initialized with a struct literal: `{ identifier1: expression1, identifier2: expression2 }`
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Window {
|
||||
property<{name: string, score: int}> player: { name: "Foo", score: 100 };
|
||||
property<{a: int, }> foo: { a: 3 };
|
||||
|
|
@ -238,7 +238,7 @@ Example := Window {
|
|||
|
||||
It is possible to define a named struct using the `struct` keyword,
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
export struct Player := {
|
||||
name: string,
|
||||
score: int,
|
||||
|
|
@ -254,7 +254,7 @@ Example := Window {
|
|||
The type array is using square brackets for example `[int]` is an array of `int`. In the runtime, they are
|
||||
basically used as models for the `for` expression.
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Window {
|
||||
property<[int]> list-of-int: [1,2,3];
|
||||
property<[{a: int, b: string}]> list-of-structs: [{ a: 1, b: "hello" }, {a: 2, b: "world"}];
|
||||
|
|
@ -280,7 +280,7 @@ Example := Window {
|
|||
* String can be converted to float by using the `to-float` function. That function returns 0 if the string is not
|
||||
a valid number. you can check with `is-float` if the string contains a valid number
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Window {
|
||||
// ok: int converts to string
|
||||
property<{a: string, b: int}> prop1: {a: 12, b: 12 };
|
||||
|
|
@ -341,7 +341,7 @@ element comes with a `clicked` callback, that's emitted when the user touches th
|
|||
it with the mouse. In the example below, the emission of that callback is forwarded to another custom callback (`hello`) by declaring a
|
||||
handler and emitting our custom callback:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
// declare a callback
|
||||
callback hello;
|
||||
|
|
@ -358,7 +358,7 @@ Example := Rectangle {
|
|||
|
||||
It is also possible to add parameters to the callback.
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
// declares a callback
|
||||
callback hello(int, string);
|
||||
|
|
@ -368,7 +368,7 @@ Example := Rectangle {
|
|||
|
||||
And return value.
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
// declares a callback with a return value
|
||||
callback hello(int, int) -> int;
|
||||
|
|
@ -380,7 +380,7 @@ Example := Rectangle {
|
|||
|
||||
It is possible to declare callback aliases in a similar way to two-way bindings:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
callback clicked <=> area.clicked;
|
||||
area := TouchArea {}
|
||||
|
|
@ -394,7 +394,7 @@ are typically used to combine basic arithmetic with access to properties of othe
|
|||
these properties change, the expression is automatically re-evaluated and a new value is assigned
|
||||
to the property the expression is associated with:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
// declare a property of type int
|
||||
property<int> my-property;
|
||||
|
|
@ -409,7 +409,7 @@ If something changes `my-property`, the width will be updated automatically.
|
|||
|
||||
Arithmetic in expression with numbers works like in most programming language with the operators `*`, `+`, `-`, `/`:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
property <int> p: 1 * 2 + 3 * 4; // same as (1 * 2) + (3 * 4)
|
||||
}
|
||||
|
|
@ -422,7 +422,7 @@ There are also the operators `&&` and `||` for logical *and* and *or* between bo
|
|||
|
||||
You can access properties by addressing the associated element, followed by a `.` and the property name:
|
||||
|
||||
```slint
|
||||
```slint,no_run
|
||||
Example := Rectangle {
|
||||
foo := Rectangle {
|
||||
x: 42px;
|
||||
|
|
@ -559,25 +559,25 @@ Inside callback handlers, more complicated statements are allowed:
|
|||
|
||||
Assignment:
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
clicked => { some-property = 42; }
|
||||
```
|
||||
|
||||
Self-assignment with `+=` `-=` `*=` `/=`
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
clicked => { some-property += 42; }
|
||||
```
|
||||
|
||||
Calling a callback
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
clicked => { root.some-callback(); }
|
||||
```
|
||||
|
||||
Conditional statements
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
clicked => {
|
||||
if (condition) {
|
||||
foo = 42;
|
||||
|
|
@ -591,7 +591,7 @@ clicked => {
|
|||
|
||||
Empty expression
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
clicked => { }
|
||||
// or
|
||||
clicked => { ; }
|
||||
|
|
@ -684,11 +684,13 @@ Animation can be configured with the following parameter:
|
|||
|
||||
It is also possible to animate several properties with the same animation:
|
||||
|
||||
```ignore
|
||||
```slint,ignore
|
||||
animate x, y { duration: 100ms; }
|
||||
```
|
||||
|
||||
is the same as
|
||||
```ignore
|
||||
|
||||
```slint,ignore
|
||||
animate x { duration: 100ms; }
|
||||
animate y { duration: 100ms; }
|
||||
```
|
||||
|
|
@ -1017,7 +1019,7 @@ instructions the Slint compiler to include the font and makes the font families
|
|||
|
||||
For example:
|
||||
|
||||
```slint,notest
|
||||
```slint,ignore
|
||||
import "./NotoSans-Regular.ttf";
|
||||
|
||||
Example := Window {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<link rel="stylesheet" href="https://slint-ui.com/resources/highlightjs/11.0.1/default.min.css">
|
||||
<script src="https://slint-ui.com/resources/highlightjs/11.0.1/highlight.min.js"></script>
|
||||
<script>
|
||||
hljs.registerLanguage("slint", function (hljs) {
|
||||
function highlight_slint(hljs) {
|
||||
const KEYWORDS = {
|
||||
keyword:
|
||||
'struct export import signal property animate for in if states transitions parent root self',
|
||||
|
|
@ -49,13 +49,19 @@
|
|||
],
|
||||
illegal: /@/
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Tags used in fenced code blocks
|
||||
for (let tag of ["slint", "slint,no_run", "slint,ignore"]) {
|
||||
hljs.registerLanguage(tag, highlight_slint);
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const rustDoc = document.querySelector('meta[name="generator"]')?.content == "rustdoc";
|
||||
if (rustDoc) {
|
||||
// Only highlight .slint blocks, leave the others to rustdoc
|
||||
for (slintBlock of document.querySelectorAll(".language-slint")) {
|
||||
for (slintBlock of document.querySelectorAll("[class*=language-slint]")) {
|
||||
hljs.highlightElement(slintBlock)
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +95,7 @@
|
|||
|
||||
// The Sphinx/my_st generated HTML for code blocks does not use <code> tags, so highlight.js'
|
||||
// default selector "pre code" does not match. Let's do it by hand:
|
||||
for (block of document.querySelectorAll("div.highlight-slint div.highlight pre, div.highlight-slint-no-preview div.highlight pre")) {
|
||||
for (block of document.querySelectorAll("div[class*=highlight-slint] div.highlight pre")) {
|
||||
hljs.highlightElement(block)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@
|
|||
|
||||
async function run() {
|
||||
await slint.default();
|
||||
var elements = document.querySelectorAll("code.language-slint, .rustdoc pre.language-slint, div.highlight-slint");
|
||||
let selector = ["code.language-slint", ".rustdoc pre.language-slint", "div.highlight-slint"]
|
||||
.map((sel) => `${sel}:not([class*=slint\\,ignore]):not([class*=slint\\,no_run])`).join(",");
|
||||
var elements = document.querySelectorAll(selector);
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
let source = elements[i].innerText;
|
||||
let div = document.createElement("div");
|
||||
|
|
|
|||
|
|
@ -27,9 +27,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let file = file.replace('\r', ""); // Remove \r, because Windows.
|
||||
let mut rest = file.as_str();
|
||||
let mut count = 0;
|
||||
const BEGIN_MARKER: &str = "\n```slint\n";
|
||||
const BEGIN_MARKER: &str = "\n```slint";
|
||||
while let Some(begin) = rest.find(BEGIN_MARKER) {
|
||||
rest = rest[begin..].strip_prefix(BEGIN_MARKER).unwrap();
|
||||
|
||||
// Permit `slint,no_run` but skip `slint,ignore` and others.
|
||||
rest = match rest.split_once('\n') {
|
||||
Some((",no_run", rest)) => rest,
|
||||
Some(("", _)) => rest,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let end = rest.find("\n```\n").ok_or_else(|| {
|
||||
format!("Could not find the end of a code snippet in {}", path.display())
|
||||
})?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue