discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

New OpenSCAD formatter

M
mkatychev@pm.me
Wed, Jan 22, 2025 10:37 PM

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there was a lack of good formatters out there that meshed well with [openscad-LSP](https://github.com/Leathong/openscad-LSP/pull/33 "openscad-LSP

(https://github.com/Leathong/openscad-LSP/pull/33)"). I’ve since implemented my own OpenSCAD formatter using [Topiary](https://topiary.tweag.io/ "Topiary

(https://topiary.tweag.io/)").



Topiary is a language agnostic formatter that uses ASTs generated by [tree-sitter](https://tree-sitter.github.io/tree-sitter/ "tree-sitter

(https://tree-sitter.github.io/tree-sitter/)") combined with [lisp-like s-expressions](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html "lisp-like s-expressions

(https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html)") that determine the formatting output: https://github.com/tweag/topiary/pull/845 Check it out and let me know what you think. You'll need to install cargo/rustup to get the rust toolchain (for now), please submit any issues/inconsistencies with formatting [here](https://github.com/mkatychev/topiary/issues "here

(https://github.com/mkatychev/topiary/issues)"):

Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc: https://www.rust-lang.org/learn/get-started

Installation

cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the [before](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad "before

(https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad)") and [after](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad "after

(https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad)") inside the pull request linked above to see the stylistic choices and and edge cases covered. Keep in mind that topiary is in active development so there are some features that are still not covered/implemented such as:

  • alternate configurations (ex: curly braces on separate line)

  • alignment of fields

  • alignment of list elements

Hi everyone, \ \ I've been working on my own formatter for OpenSCAD after feeling there was a lack of good formatters out there that meshed well with [openscad-LSP](https://github.com/Leathong/openscad-LSP/pull/33 "openscad-LSP (https://github.com/Leathong/openscad-LSP/pull/33)"). I’ve since implemented my own OpenSCAD formatter using [Topiary](https://topiary.tweag.io/ "Topiary (https://topiary.tweag.io/)"). \ \ ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAE8CAYAAAB96VL7AAAAAXNSR0IArs4c6QAAAGhlWElmTU0AKgAAAAgABAEGAAMAAAABAAIAAAESAAMAAAABAAEAAAEoAAMAAAABAAIAAIdpAAQAAAABAAAAPgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABU6ADAAQAAAABAAABPAAAAACYSW34AAAC5GlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8dGlmZjpDb21wcmVzc2lvbj4xPC90aWZmOkNvbXByZXNzaW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpQaG90b21ldHJpY0ludGVycHJldGF0aW9uPjI8L3RpZmY6UGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjMzOTwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MzE2PC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94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)\ \ Topiary is a language agnostic formatter that uses ASTs generated by [tree-sitter](https://tree-sitter.github.io/tree-sitter/ "tree-sitter (https://tree-sitter.github.io/tree-sitter/)") combined with [lisp-like s-expressions](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html "lisp-like s-expressions (https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html)") that determine the formatting output: [https://github.com/tweag/topiary/pull/845](https://github.com/tweag/topiary/pull/845 "https://github.com/tweag/topiary/pull/845") Check it out and let me know what you think. You'll need to install `cargo`/`rustup` to get the rust toolchain (for now), please submit any issues/inconsistencies with formatting [here](https://github.com/mkatychev/topiary/issues "here (https://github.com/mkatychev/topiary/issues)"): ## **Setup** Install the rust toolchain, this set you up with `rustup`, `cargo` and `rustc`: [https://www.rust-lang.org/learn/get-started](https://www.rust-lang.org/learn/get-started "https://www.rust-lang.org/learn/get-started") ## **Installation** ``` cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad ``` ## **Format** ``` topiary format path/to/my_openscad_file.scad ``` ## **Notes** You can see the [before](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad "before (https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad)") and [after](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad "after (https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad)") inside the pull request linked above to see the stylistic choices and and edge cases covered. Keep in mind that topiary is in active development so there are some features that are still not covered/implemented such as: * alternate configurations (ex: curly braces on separate line) * alignment of fields * alignment of list elements
TS
Tim Schmidt
Thu, Jan 23, 2025 4:44 AM

This is really cool!

I've recently been working on a little rusty CAD kernel (
https://crates.io/crates/csgrs) that works well with the
https://www.dimforge.com/ libraries for physical simulation.

I've started a little OpenSCAD -> AST -> csgrs parser as well, using the
OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at
the moment: https://github.com/timschmidt/openscad_to_csgrs

Awesome to see some similar work!

On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss <
discuss@lists.openscad.org> wrote:

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there was
a lack of good formatters out there that meshed well with openscad-LSP
https://github.com/Leathong/openscad-LSP/pull/33. I’ve since
implemented my own OpenSCAD formatter using Topiary
https://topiary.tweag.io/.

Topiary is a language agnostic formatter that uses ASTs generated by
tree-sitter https://tree-sitter.github.io/tree-sitter/ combined with lisp-like
s-expressions
https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html
that determine the formatting output:
https://github.com/tweag/topiary/pull/845 Check it out and let me know
what you think. You'll need to install cargo/rustup to get the rust
toolchain (for now), please submit any issues/inconsistencies with
formatting here https://github.com/mkatychev/topiary/issues:
Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc:
https://www.rust-lang.org/learn/get-started
Installation

cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the before
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad
and after
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad
inside the pull request linked above to see the stylistic choices and and
edge cases covered. Keep in mind that topiary is in active development so
there are some features that are still not covered/implemented such as:

-

alternate configurations (ex: curly braces on separate line)
-

alignment of fields
-

alignment of list elements

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

This is really cool! I've recently been working on a little rusty CAD kernel ( https://crates.io/crates/csgrs) that works well with the https://www.dimforge.com/ libraries for physical simulation. I've started a little OpenSCAD -> AST -> csgrs parser as well, using the OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at the moment: https://github.com/timschmidt/openscad_to_csgrs Awesome to see some similar work! On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss < discuss@lists.openscad.org> wrote: > Hi everyone, > > I've been working on my own formatter for OpenSCAD after feeling there was > a lack of good formatters out there that meshed well with openscad-LSP > <https://github.com/Leathong/openscad-LSP/pull/33>. I’ve since > implemented my own OpenSCAD formatter using Topiary > <https://topiary.tweag.io/>. > > > > Topiary is a language agnostic formatter that uses ASTs generated by > tree-sitter <https://tree-sitter.github.io/tree-sitter/> combined with lisp-like > s-expressions > <https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html> > that determine the formatting output: > https://github.com/tweag/topiary/pull/845 Check it out and let me know > what you think. You'll need to install cargo/rustup to get the rust > toolchain (for now), please submit any issues/inconsistencies with > formatting here <https://github.com/mkatychev/topiary/issues>: > *Setup* > > Install the rust toolchain, this set you up with rustup, cargo and rustc: > https://www.rust-lang.org/learn/get-started > *Installation* > > cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad > > *Format* > > topiary format path/to/my_openscad_file.scad > > *Notes* > > You can see the before > <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad> > and after > <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad> > inside the pull request linked above to see the stylistic choices and and > edge cases covered. Keep in mind that topiary is in active development so > there are some features that are still not covered/implemented such as: > > - > > alternate configurations (ex: curly braces on separate line) > - > > alignment of fields > - > > alignment of list elements > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > -- Timothy Schmidt (517) 292-4030 timschmidt@gmail.com https://wiki.replimat.org
M
mkatychev
Thu, Jan 23, 2025 5:03 AM

That's also very interesting, Tim! fornjot is another b-rep CAD Kernel I've been following, it could provide some inspiration.

As for the lack of functionality, check out my fork of tree-sitter-openscad:
https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060

My fork covers many more cases than the main repo, I used it to build the aforementioned formatter and tested many popular libraries such as BOSL2 and relativity.scad to ensure it can parse/tokenize the most common grammar variations.

tree-sitter parser/Combinator is a largely inert AST generator (tokens hold minimal/no metadata ) so it may still not fit your use-case even if it handles many more edge cases than the main repo.

Mikhail

-------- Original Message --------
On 2025-01-22 22:44, Tim Schmidt  wrote:

This is really cool!

I've recently been working on a little rusty CAD kernel (https://crates.io/crates/csgrs) that works well with the https://www.dimforge.com/ libraries for physical simulation.
I've started a little OpenSCAD -> AST -> csgrs parser as well, using the OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at the moment: https://github.com/timschmidt/openscad_to_csgrs

Awesome to see some similar work!

On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss discuss@lists.openscad.org wrote:

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there was a lack of good formatters out there that meshed well with openscad-LSP. I’ve since implemented my own OpenSCAD formatter using Topiary.

Topiary is a language agnostic formatter that uses ASTs generated by tree-sitter combined with lisp-like s-expressions that determine the formatting output: https://github.com/tweag/topiary/pull/845 Check it out and let me know what you think. You'll need to install cargo/rustup to get the rust toolchain (for now), please submit any issues/inconsistencies with formatting here:

Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc: https://www.rust-lang.org/learn/get-started

Installation

cargo install --git
https://github.com/mkatychev/topiary
topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the before and after inside the pull request linked above to see the stylistic choices and and edge cases covered. Keep in mind that topiary is in active development so there are some features that are still not covered/implemented such as:

alternate configurations (ex: curly braces on separate line)

alignment of fields

alignment of list elements


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--

Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

That's also very interesting, Tim! fornjot is another b-rep CAD Kernel I've been following, it could provide some inspiration. As for the lack of functionality, check out my fork of tree-sitter-openscad: https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060 My fork covers many more cases than the main repo, I used it to build the aforementioned formatter and tested many popular libraries such as BOSL2 and relativity.scad to ensure it can parse/tokenize the most common grammar variations. tree-sitter parser/Combinator is a largely inert AST generator (tokens hold minimal/no metadata ) so it may still not fit your use-case even if it handles many more edge cases than the main repo. Mikhail -------- Original Message -------- On 2025-01-22 22:44, Tim Schmidt wrote: > This is really cool! > > I've recently been working on a little rusty CAD kernel (https://crates.io/crates/csgrs) that works well with the https://www.dimforge.com/ libraries for physical simulation. > I've started a little OpenSCAD -> AST -> csgrs parser as well, using the OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at the moment: https://github.com/timschmidt/openscad_to_csgrs > > Awesome to see some similar work! > > On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss <discuss@lists.openscad.org> wrote: > >> Hi everyone, >> >> I've been working on my own formatter for OpenSCAD after feeling there was a lack of good formatters out there that meshed well with [openscad-LSP](https://github.com/Leathong/openscad-LSP/pull/33). I’ve since implemented my own OpenSCAD formatter using [Topiary](https://topiary.tweag.io/). >> >> Topiary is a language agnostic formatter that uses ASTs generated by [tree-sitter](https://tree-sitter.github.io/tree-sitter/) combined with [lisp-like s-expressions](https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html) that determine the formatting output: https://github.com/tweag/topiary/pull/845 Check it out and let me know what you think. You'll need to install cargo/rustup to get the rust toolchain (for now), please submit any issues/inconsistencies with formatting [here](https://github.com/mkatychev/topiary/issues): >> >> Setup >> >> Install the rust toolchain, this set you up with rustup, cargo and rustc: https://www.rust-lang.org/learn/get-started >> >> Installation >> >> cargo install --git >> https://github.com/mkatychev/topiary >> topiary-cli --no-default-features --features=openscad >> >> Format >> >> topiary format path/to/my_openscad_file.scad >> >> Notes >> >> You can see the [before](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad) and [after](https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad) inside the pull request linked above to see the stylistic choices and and edge cases covered. Keep in mind that topiary is in active development so there are some features that are still not covered/implemented such as: >> >> - >> >> alternate configurations (ex: curly braces on separate line) >> >> - >> >> alignment of fields >> >> - >> >> alignment of list elements >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > > -- > > Timothy Schmidt > (517) 292-4030 > timschmidt@gmail.com > https://wiki.replimat.org
TS
Tim Schmidt
Thu, Jan 23, 2025 5:26 AM

Thanks for the pointer!  I'll add it to the todo and definitely put it to
use!

I'm aware of fornjot and truck, but just wanted something fast and simple
built around polygons and lines.  Cavalier contours, which I am using for
2d offsetting, does have some curve support which is currently going unused
in csgrs.  The binary space partitioning trees at the heart of csgrs
probably don't lend themselves well to curves anyway.  But it is good
enough for polygons, and very small and fast and relatively simple.

I recently landed per-csg object and per-polygon generic metadata storage,
which should enable color, material type, texture graphics, physical
simulation data, even game engine object handles to be stored alongside the
appropriate polygons in the BSP datastructure.  Should enable CAD for
multi-material printing, and generative designs evolved from physical
constraints among other things.

On Thu, Jan 23, 2025 at 12:03 AM mkatychev mkatychev@pm.me wrote:

That's also very interesting, Tim! fornjot is another b-rep CAD Kernel
I've  been following, it could provide some inspiration.

As for the lack of functionality, check out my fork of
tree-sitter-openscad:

https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060

My fork covers many more cases than the main repo, I used it to build the
aforementioned formatter and tested many popular libraries such as BOSL2
and relativity.scad to ensure it can parse/tokenize the most common grammar
variations.

tree-sitter parser/Combinator is a largely inert AST generator (tokens
hold minimal/no metadata ) so it may still not fit your use-case even if it
handles many more edge cases than the main repo.

Mikhail

-------- Original Message --------
On 2025-01-22 22:44, Tim Schmidt wrote:

This is really cool!

I've recently been working on a little rusty CAD kernel (
https://crates.io/crates/csgrs) that works well with the
https://www.dimforge.com/ libraries for physical simulation.

I've started a little OpenSCAD -> AST -> csgrs parser as well, using the
OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at
the moment: https://github.com/timschmidt/openscad_to_csgrs

Awesome to see some similar work!

On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss <
discuss@lists.openscad.org> wrote:

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there
was a lack of good formatters out there that meshed well with
openscad-LSP https://github.com/Leathong/openscad-LSP/pull/33. I’ve
since implemented my own OpenSCAD formatter using Topiary
https://topiary.tweag.io/.

Topiary is a language agnostic formatter that uses ASTs generated by
tree-sitter https://tree-sitter.github.io/tree-sitter/ combined with lisp-like
s-expressions
https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html
that determine the formatting output:
https://github.com/tweag/topiary/pull/845 Check it out and let me know
what you think. You'll need to install cargo/rustup to get the rust
toolchain (for now), please submit any issues/inconsistencies with
formatting here https://github.com/mkatychev/topiary/issues:
Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc:
https://www.rust-lang.org/learn/get-started
Installation

cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the before
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad
and after
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad
inside the pull request linked above to see the stylistic choices and and
edge cases covered. Keep in mind that topiary is in active development so
there are some features that are still not covered/implemented such as:

-

alternate configurations (ex: curly braces on separate line)
-

alignment of fields
-

alignment of list elements

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

Thanks for the pointer! I'll add it to the todo and definitely put it to use! I'm aware of fornjot and truck, but just wanted something fast and simple built around polygons and lines. Cavalier contours, which I am using for 2d offsetting, does have some curve support which is currently going unused in csgrs. The binary space partitioning trees at the heart of csgrs probably don't lend themselves well to curves anyway. But it is good enough for polygons, and very small and fast and relatively simple. I recently landed per-csg object and per-polygon generic metadata storage, which should enable color, material type, texture graphics, physical simulation data, even game engine object handles to be stored alongside the appropriate polygons in the BSP datastructure. Should enable CAD for multi-material printing, and generative designs evolved from physical constraints among other things. On Thu, Jan 23, 2025 at 12:03 AM mkatychev <mkatychev@pm.me> wrote: > That's also very interesting, Tim! fornjot is another b-rep CAD Kernel > I've been following, it could provide some inspiration. > > As for the lack of functionality, check out my fork of > tree-sitter-openscad: > > https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060 > > My fork covers many more cases than the main repo, I used it to build the > aforementioned formatter and tested many popular libraries such as BOSL2 > and relativity.scad to ensure it can parse/tokenize the most common grammar > variations. > > tree-sitter parser/Combinator is a largely inert AST generator (tokens > hold minimal/no metadata ) so it may still not fit your use-case even if it > handles many more edge cases than the main repo. > > Mikhail > > > -------- Original Message -------- > On 2025-01-22 22:44, Tim Schmidt wrote: > > This is really cool! > > I've recently been working on a little rusty CAD kernel ( > https://crates.io/crates/csgrs) that works well with the > https://www.dimforge.com/ libraries for physical simulation. > > I've started a little OpenSCAD -> AST -> csgrs parser as well, using the > OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at > the moment: https://github.com/timschmidt/openscad_to_csgrs > > Awesome to see some similar work! > > On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss < > discuss@lists.openscad.org> wrote: > >> Hi everyone, >> >> I've been working on my own formatter for OpenSCAD after feeling there >> was a lack of good formatters out there that meshed well with >> openscad-LSP <https://github.com/Leathong/openscad-LSP/pull/33>. I’ve >> since implemented my own OpenSCAD formatter using Topiary >> <https://topiary.tweag.io/>. >> >> >> >> Topiary is a language agnostic formatter that uses ASTs generated by >> tree-sitter <https://tree-sitter.github.io/tree-sitter/> combined with lisp-like >> s-expressions >> <https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html> >> that determine the formatting output: >> https://github.com/tweag/topiary/pull/845 Check it out and let me know >> what you think. You'll need to install cargo/rustup to get the rust >> toolchain (for now), please submit any issues/inconsistencies with >> formatting here <https://github.com/mkatychev/topiary/issues>: >> *Setup* >> >> Install the rust toolchain, this set you up with rustup, cargo and rustc: >> https://www.rust-lang.org/learn/get-started >> *Installation* >> >> cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad >> >> *Format* >> >> topiary format path/to/my_openscad_file.scad >> >> *Notes* >> >> You can see the before >> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad> >> and after >> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad> >> inside the pull request linked above to see the stylistic choices and and >> edge cases covered. Keep in mind that topiary is in active development so >> there are some features that are still not covered/implemented such as: >> >> - >> >> alternate configurations (ex: curly braces on separate line) >> - >> >> alignment of fields >> - >> >> alignment of list elements >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > > > -- > Timothy Schmidt > (517) 292-4030 > timschmidt@gmail.com > https://wiki.replimat.org > > -- Timothy Schmidt (517) 292-4030 timschmidt@gmail.com https://wiki.replimat.org
TS
Tim Schmidt
Thu, Jan 23, 2025 5:56 AM

Also, Dimforge just deals in triangle meshes, basic shapes, and voxels.  So
my focus has been on supporting CSG on those to facilitate easy interaction
with the API.

On Thu, Jan 23, 2025 at 12:26 AM Tim Schmidt timschmidt@gmail.com wrote:

Thanks for the pointer!  I'll add it to the todo and definitely put it to
use!

I'm aware of fornjot and truck, but just wanted something fast and simple
built around polygons and lines.  Cavalier contours, which I am using for
2d offsetting, does have some curve support which is currently going unused
in csgrs.  The binary space partitioning trees at the heart of csgrs
probably don't lend themselves well to curves anyway.  But it is good
enough for polygons, and very small and fast and relatively simple.

I recently landed per-csg object and per-polygon generic metadata storage,
which should enable color, material type, texture graphics, physical
simulation data, even game engine object handles to be stored alongside the
appropriate polygons in the BSP datastructure.  Should enable CAD for
multi-material printing, and generative designs evolved from physical
constraints among other things.

On Thu, Jan 23, 2025 at 12:03 AM mkatychev mkatychev@pm.me wrote:

That's also very interesting, Tim! fornjot is another b-rep CAD Kernel
I've  been following, it could provide some inspiration.

As for the lack of functionality, check out my fork of
tree-sitter-openscad:

https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060

My fork covers many more cases than the main repo, I used it to build the
aforementioned formatter and tested many popular libraries such as BOSL2
and relativity.scad to ensure it can parse/tokenize the most common grammar
variations.

tree-sitter parser/Combinator is a largely inert AST generator (tokens
hold minimal/no metadata ) so it may still not fit your use-case even if it
handles many more edge cases than the main repo.

Mikhail

-------- Original Message --------
On 2025-01-22 22:44, Tim Schmidt wrote:

This is really cool!

I've recently been working on a little rusty CAD kernel (
https://crates.io/crates/csgrs) that works well with the
https://www.dimforge.com/ libraries for physical simulation.

I've started a little OpenSCAD -> AST -> csgrs parser as well, using the
OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at
the moment: https://github.com/timschmidt/openscad_to_csgrs

Awesome to see some similar work!

On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss <
discuss@lists.openscad.org> wrote:

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there
was a lack of good formatters out there that meshed well with
openscad-LSP https://github.com/Leathong/openscad-LSP/pull/33. I’ve
since implemented my own OpenSCAD formatter using Topiary
https://topiary.tweag.io/.

Topiary is a language agnostic formatter that uses ASTs generated by
tree-sitter https://tree-sitter.github.io/tree-sitter/ combined with lisp-like
s-expressions
https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html
that determine the formatting output:
https://github.com/tweag/topiary/pull/845 Check it out and let me know
what you think. You'll need to install cargo/rustup to get the rust
toolchain (for now), please submit any issues/inconsistencies with
formatting here https://github.com/mkatychev/topiary/issues:
Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc:
https://www.rust-lang.org/learn/get-started
Installation

cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the before
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad
and after
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad
inside the pull request linked above to see the stylistic choices and and
edge cases covered. Keep in mind that topiary is in active development so
there are some features that are still not covered/implemented such as:

-

alternate configurations (ex: curly braces on separate line)
-

alignment of fields
-

alignment of list elements

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org

Also, Dimforge just deals in triangle meshes, basic shapes, and voxels. So my focus has been on supporting CSG on those to facilitate easy interaction with the API. On Thu, Jan 23, 2025 at 12:26 AM Tim Schmidt <timschmidt@gmail.com> wrote: > Thanks for the pointer! I'll add it to the todo and definitely put it to > use! > > I'm aware of fornjot and truck, but just wanted something fast and simple > built around polygons and lines. Cavalier contours, which I am using for > 2d offsetting, does have some curve support which is currently going unused > in csgrs. The binary space partitioning trees at the heart of csgrs > probably don't lend themselves well to curves anyway. But it is good > enough for polygons, and very small and fast and relatively simple. > > I recently landed per-csg object and per-polygon generic metadata storage, > which should enable color, material type, texture graphics, physical > simulation data, even game engine object handles to be stored alongside the > appropriate polygons in the BSP datastructure. Should enable CAD for > multi-material printing, and generative designs evolved from physical > constraints among other things. > > On Thu, Jan 23, 2025 at 12:03 AM mkatychev <mkatychev@pm.me> wrote: > >> That's also very interesting, Tim! fornjot is another b-rep CAD Kernel >> I've been following, it could provide some inspiration. >> >> As for the lack of functionality, check out my fork of >> tree-sitter-openscad: >> >> https://github.com/mkatychev/tree-sitter-openscad/blob/master/CHANGELOG.md#version-060 >> >> My fork covers many more cases than the main repo, I used it to build the >> aforementioned formatter and tested many popular libraries such as BOSL2 >> and relativity.scad to ensure it can parse/tokenize the most common grammar >> variations. >> >> tree-sitter parser/Combinator is a largely inert AST generator (tokens >> hold minimal/no metadata ) so it may still not fit your use-case even if it >> handles many more edge cases than the main repo. >> >> Mikhail >> >> >> -------- Original Message -------- >> On 2025-01-22 22:44, Tim Schmidt wrote: >> >> This is really cool! >> >> I've recently been working on a little rusty CAD kernel ( >> https://crates.io/crates/csgrs) that works well with the >> https://www.dimforge.com/ libraries for physical simulation. >> >> I've started a little OpenSCAD -> AST -> csgrs parser as well, using the >> OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at >> the moment: https://github.com/timschmidt/openscad_to_csgrs >> >> Awesome to see some similar work! >> >> On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss < >> discuss@lists.openscad.org> wrote: >> >>> Hi everyone, >>> >>> I've been working on my own formatter for OpenSCAD after feeling there >>> was a lack of good formatters out there that meshed well with >>> openscad-LSP <https://github.com/Leathong/openscad-LSP/pull/33>. I’ve >>> since implemented my own OpenSCAD formatter using Topiary >>> <https://topiary.tweag.io/>. >>> >>> >>> >>> Topiary is a language agnostic formatter that uses ASTs generated by >>> tree-sitter <https://tree-sitter.github.io/tree-sitter/> combined with lisp-like >>> s-expressions >>> <https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html> >>> that determine the formatting output: >>> https://github.com/tweag/topiary/pull/845 Check it out and let me know >>> what you think. You'll need to install cargo/rustup to get the rust >>> toolchain (for now), please submit any issues/inconsistencies with >>> formatting here <https://github.com/mkatychev/topiary/issues>: >>> *Setup* >>> >>> Install the rust toolchain, this set you up with rustup, cargo and rustc: >>> https://www.rust-lang.org/learn/get-started >>> *Installation* >>> >>> cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad >>> >>> *Format* >>> >>> topiary format path/to/my_openscad_file.scad >>> >>> *Notes* >>> >>> You can see the before >>> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad> >>> and after >>> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad> >>> inside the pull request linked above to see the stylistic choices and and >>> edge cases covered. Keep in mind that topiary is in active development so >>> there are some features that are still not covered/implemented such as: >>> >>> - >>> >>> alternate configurations (ex: curly braces on separate line) >>> - >>> >>> alignment of fields >>> - >>> >>> alignment of list elements >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> >> >> -- >> Timothy Schmidt >> (517) 292-4030 >> timschmidt@gmail.com >> https://wiki.replimat.org >> >> > > -- > Timothy Schmidt > (517) 292-4030 > timschmidt@gmail.com > https://wiki.replimat.org > -- Timothy Schmidt (517) 292-4030 timschmidt@gmail.com https://wiki.replimat.org
GS
Guenther Sohler
Thu, Jan 23, 2025 10:18 AM

Instead of parsing AST it's way easier just to output the AST in a
different format.
Maybe we could develop versatile modules to output the AST in other
languages next to OpenSCAD

On Thu, Jan 23, 2025 at 5:45 AM Tim Schmidt via Discuss <
discuss@lists.openscad.org> wrote:

This is really cool!

I've recently been working on a little rusty CAD kernel (
https://crates.io/crates/csgrs) that works well with the
https://www.dimforge.com/ libraries for physical simulation.

I've started a little OpenSCAD -> AST -> csgrs parser as well, using the
OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at
the moment: https://github.com/timschmidt/openscad_to_csgrs

Awesome to see some similar work!

On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss <
discuss@lists.openscad.org> wrote:

Hi everyone,

I've been working on my own formatter for OpenSCAD after feeling there
was a lack of good formatters out there that meshed well with
openscad-LSP https://github.com/Leathong/openscad-LSP/pull/33. I’ve
since implemented my own OpenSCAD formatter using Topiary
https://topiary.tweag.io/.

Topiary is a language agnostic formatter that uses ASTs generated by
tree-sitter https://tree-sitter.github.io/tree-sitter/ combined with lisp-like
s-expressions
https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html
that determine the formatting output:
https://github.com/tweag/topiary/pull/845 Check it out and let me know
what you think. You'll need to install cargo/rustup to get the rust
toolchain (for now), please submit any issues/inconsistencies with
formatting here https://github.com/mkatychev/topiary/issues:
Setup

Install the rust toolchain, this set you up with rustup, cargo and rustc:
https://www.rust-lang.org/learn/get-started
Installation

cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad

Format

topiary format path/to/my_openscad_file.scad

Notes

You can see the before
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad
and after
https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad
inside the pull request linked above to see the stylistic choices and and
edge cases covered. Keep in mind that topiary is in active development so
there are some features that are still not covered/implemented such as:

-

alternate configurations (ex: curly braces on separate line)
-

alignment of fields
-

alignment of list elements

OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

--
Timothy Schmidt
(517) 292-4030
timschmidt@gmail.com
https://wiki.replimat.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Instead of parsing AST it's way easier just to output the AST in a different format. Maybe we could develop versatile modules to output the AST in other languages next to OpenSCAD On Thu, Jan 23, 2025 at 5:45 AM Tim Schmidt via Discuss < discuss@lists.openscad.org> wrote: > This is really cool! > > I've recently been working on a little rusty CAD kernel ( > https://crates.io/crates/csgrs) that works well with the > https://www.dimforge.com/ libraries for physical simulation. > > I've started a little OpenSCAD -> AST -> csgrs parser as well, using the > OpenSCAD tree-sitter grammar, but it is much less functional than csgrs at > the moment: https://github.com/timschmidt/openscad_to_csgrs > > Awesome to see some similar work! > > On Wed, Jan 22, 2025 at 9:54 PM mkatychev--- via Discuss < > discuss@lists.openscad.org> wrote: > >> Hi everyone, >> >> I've been working on my own formatter for OpenSCAD after feeling there >> was a lack of good formatters out there that meshed well with >> openscad-LSP <https://github.com/Leathong/openscad-LSP/pull/33>. I’ve >> since implemented my own OpenSCAD formatter using Topiary >> <https://topiary.tweag.io/>. >> >> >> >> Topiary is a language agnostic formatter that uses ASTs generated by >> tree-sitter <https://tree-sitter.github.io/tree-sitter/> combined with lisp-like >> s-expressions >> <https://tree-sitter.github.io/tree-sitter/using-parsers/queries/1-syntax.html> >> that determine the formatting output: >> https://github.com/tweag/topiary/pull/845 Check it out and let me know >> what you think. You'll need to install cargo/rustup to get the rust >> toolchain (for now), please submit any issues/inconsistencies with >> formatting here <https://github.com/mkatychev/topiary/issues>: >> *Setup* >> >> Install the rust toolchain, this set you up with rustup, cargo and rustc: >> https://www.rust-lang.org/learn/get-started >> *Installation* >> >> cargo install --git https://github.com/mkatychev/topiary topiary-cli --no-default-features --features=openscad >> >> *Format* >> >> topiary format path/to/my_openscad_file.scad >> >> *Notes* >> >> You can see the before >> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/input/openscad.scad> >> and after >> <https://github.com/tweag/topiary/blob/7afe496065b18c12dff8631e8e6a5e94979e19f4/topiary-cli/tests/samples/expected/openscad.scad> >> inside the pull request linked above to see the stylistic choices and and >> edge cases covered. Keep in mind that topiary is in active development so >> there are some features that are still not covered/implemented such as: >> >> - >> >> alternate configurations (ex: curly braces on separate line) >> - >> >> alignment of fields >> - >> >> alignment of list elements >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > > > -- > Timothy Schmidt > (517) 292-4030 > timschmidt@gmail.com > https://wiki.replimat.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >