-
Notifications
You must be signed in to change notification settings - Fork 220
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
Proposal to use a document loader #29
Comments
Well, it's essentially a new markup language - I already thought about this, but intended to do this with XML, not implement my custom non-standard parser. Azul already understands "classes" and "ids", just like HTML, which many people are already familiar with. The CSS can already be hot-reloaded, so the document shouldn't contain any styling information, just content. Then I wanted to write a XML-to-Rust translator that can take the XML and spit out the equivalent Rust code, so you can "compile" these XML documents to standard Rust when you're done with the quick iteration. The thing is that an XML document maps 1:1 to a DOM tree. I want to avoid making my own markup language if possible, because it's yet another learning overhead - and for what, XML parsers are plenty, and XML is widely used and people are familiar with it. So the code in your example would become: <!-- This is a comment -->
<div id="wrapper">
<p id="red">"Hello123"</p>
<div id="sub_wrapper">
<div id="yellow"></div>
<div id="grey"></div>
</div>
<p id="pink">"Lorem Ipsum dolor sit amet"</div>
<img src="Cat01" />
</div> I've also thought about how you'd render custom components, like the spreadsheet. For this I've thought about a trait that "reacts" to a hashmap of key-value pairs, then outputs a impl LoadFromXml for Spreadsheet {
fn component_name() -> &'static str {
"spreadsheet"
}
fn react_to_key_values(kv: &HashMap<String, String>) -> Result<Dom<T>, SyntaxError> {
let columns = kv.get("cols").and_then(|v| v.parse::<usize>().ok()).unwrap_or(0);
let rows = kv.get("rows").and_then(|v| v.parse::<usize>().ok()).unwrap_or(0);
Ok(Spreadsheet::new(columns, rows).dom())
}
// Called by the XML-to-Rust compiler
fn compile_to_rust_code(kv: &HashMap<String, String>) -> String {
let columns = kv.get("cols").and_then(|v| v.parse::<usize>().ok()).unwrap_or(0);
let rows = kv.get("rows").and_then(|v| v.parse::<usize>().ok()).unwrap_or(0);
format!("Spreadsheet::new({}, {}).dom()", columns, rows)
}
} Then you could "inject" this component as a <div id="my_wrapper">
<spreadsheet rows="4" cols="10" />
</div> ... which then could be compile to Rust when you're done with this component: $ azul_to_rust my_ui.xml > my_ui.rs
$ cat my_ui.rs
Dom::new(NodeType::Div).with_id("my_wrapper")
.with_child(Spreadsheet::new(4, 10).dom()) I see little reason why a custom markup language is needed for this instead of just using XML / HTML. The styling information has to be in a seperate CSS file anyways (ok, you could "merge" them together with your custom document loader, but eh...). Your project is certainly cool and I don't want to stop you from developing it, but I wouldn't include this in Azul itself, rather keep it as a third-party plugin (if it turns out that people really do want to use your markup language over XML). |
Oh! Okay then, perhaps I should move my attention to making a plugin that could use an xml parser and emit a dom tree. |
With HTML parsing I could take my desktop GUI and with some small changes make a web application layout from it, while sharing the same stylesheet. Is this HTML/XML parsing already available or still under consideration/implementation? Did not see any references in the documentation. |
No, it's not implemented yet. It's just an idea, because there is already an XML build dependency anyways (necessary for generating opengl bindings). And yes, the plan was to be HTML-friendly, so that people can port existing HTML applications easily. I'll reopen this as a tracking issue so it doesn't get lost. |
Neat, will be following for news on this. :) |
@fschutt is a xml to rust compiler necessary ? wouldnt it be possible to parse xml at compile time in release builds ? |
@diegor8 Cargo does not allow you to modify the source directory in a build.rs file. So yes, you'd need to compile it manually in a separate step. Besides, how would you do variables, callbacks, for loops in XML? Again, XML would just be for prototyping. |
@fschutt i was talking about compile time function execution , compile time serialization of xml documents , not plugging a transpiler into rustc |
@diegor8 Yes, and? You cannot generate compilable Rust code from XML without a separate compliation step. As to your question, no it's not possible. A And you'd still not be able to do for loops in XML, even with |
made me think users could be expected to use the results of this without modifying them . Are there some parts of the ui that could be used as is after being generated by the document loader ? |
Closing this because this is more or less what the XML loader now does: see the <component name="Invoice" args="dueDate: String">
<p>Your invoice is due at {dueDate}</p>
</component>
<app>
<Invoice dueDate="02.03.2019" />
</app> In the future, you will be able to compile that XML code to Rust functions (to have both a performant and type-safe prototyping API), but for now you can use |
Description
Writing the dom code for a document is long and kind of hard to follow. It is nicely formatted, but it is rather cumbersome to write. And so I created a document loader which does the following:
Dom<T>
from the abstract syntax tree emitted by the parserDescribe your solution
A document loader. Kind of like an HTML document loader, but with a less involved syntax (We don't need to be able to use javascript or css in the file).
Here an example of the syntax my loader currently uses:
Are there alternatives or drawbacks?
An alternative solution is to create a different form to define documents. My loader may have some drawbacks in the future for supporting widgets/new features of Azul, not to mention I'm no language specialist, but it may be a start.
Is this a breaking change
All of the current code would still work. This could be a separate module or project completely.
Additional notes
The repo containing the code is available here
The text was updated successfully, but these errors were encountered: