Crates.io | elements-lang |
lib.rs | elements-lang |
version | 0.2.3 |
source | src |
created_at | 2024-08-21 00:25:26.396699 |
updated_at | 2024-10-29 17:49:13.610541 |
description | A geometry markup language and diagram renderer. |
homepage | |
repository | https://hg.sr.ht/~lnjng/elements |
max_upload_size | |
id | 1345939 |
size | 72,963 |
A geometry markup language and diagram renderer.
There are two main parts to this project: the markup language and the diagram renderer. The functions that make up the markup
language are mostly defined in the lang
folder, while the lexing and interpreting functions are defined in lexer.rs
and
interpreter.rs
in the main src
folder respectively. These functions first convert a source string into a vector of Token
s,
and then interpret these tokens into a set of Value
s. These Value
s then implement the Element
trait, which will turn them
into Svg
objects that hold the Render
trait. The rendering system, located in the file renderer.rs
, then takes these objects
and outputs the correct svg code.
Note: main repository is developed using Mercurial, at https://hg.sr.ht/~lnjng/elements.
To install the program, simply use cargo:
cargo install elements-lang
To run the program, use the following command:
elements <input file>
The program will then output the svg code to stdout as well as to a file called out.svg
. To enable the labelling system, the
--label
flag can be used.
Here is an example to render a triangle:
(setq A (point 0 0))
(setq B (point 0 3))
(setq C (point 4 0))
(triangle A B C)
More examples can be found under the examples
directory.
The language is written in simple lisp syntax. Notably, however, you can simply write out the variable name with no parantheses, and the interpreter will automatically substitute the value of the variable and render the appropriate object. For example, the following code will render a triangle with vertices at (0, 0), (0, 3), and (4, 0):
; this is a triangle
(setq A (point 0 0))
(setq B (point 0 3))
(setq C (point 4 0))
(setq T (triangle A B C))
T
Notice how the setq
function is used to set variables, and how comments are started with a semicolon.
Functions are also often overloaded to provide more functionality with the same easy syntax. The following are the available geometric functions:
point
(point [Int/Float] [Int/Float]) -> Point
The point
function creates a point with the given x and y coordinates in the first and second parameters respectively.
circumcenter
(circumcenter [Triangle]) -> Point
The circumcenter
function takes in a triangle and returns the circumcenter of that triangle.
orthocenter
(orthocenter [Triangle]) -> Point
The orthocenter
function takes in a triangle and returns the orthocenter of that triangle.
centroid
(centroid [Triangle]) -> Point
The centroid
function takes in a triangle and returns the centroid of that triangle.
inradius
(inradius [Triangle]) -> Int/Float
The inradius
function takes in a triangle and returns the inradius of that triangle.
incenter
(incenter [Triangle]) -> Point
The incenter
function takes in a triangle and returns the incenter of that triangle.
lineseg
(lineseg [Point] [Point]) -> Lineseg
The lineseg
function creates a line segment with the given two points as the endpoints.
midpoint
(midpoint [Point] [Point]) -> Point
The midpoint
function returns a point that is the midpoint of the two given points.
triangle
(triangle [Point] [Point] [Point]) -> Triangle
The first case for creating a triangle involves three parameters. The three parameters are the three vertices of the triangle.
(triangle [Angle]) -> Triangle
The second case for creating a triangle is given an angle (i.e. two connected line segments), the function will create a triangle with the angle as the vertex.
(triangle [Circle]) -> Triangle
The third and ambiguous case, when given a circle, the function will return a randomly generated inscribed triangle. The triangle will have points that are greater than half the radius apart.
circle
(circle [Point] [Int/Float]) -> Circle
The first case for creating a circle involves two parameters. The first is a parameter denoting the center of the circle. The second parameter is a number denoting the radius of the circle.
(circle) -> Circle
An ambiguous case for this function, when no parameters are given this function will create a standard circle at (0, 0) with radius 5.
angle
(angle [Point] [Point] [Point]) -> Angle
The angle
function creates an angle from three points denoted in the three parameters.
iangle
(iangle [Circle] [Int/Float]) -> Angle
The iangle
function creates an inscribed angle in a circle. The first parameter is the circle, and the second parameter is the
angle in degrees.
intersect
(intersect [Lineseg] [Circle] [Int]) -> Point
The first case for the intersect
function involves three parameters. The first parameter is a line segment, the second is a circle,
and the third is an int representing either 0 or 1, the index of the point of intersection. As a line can maximally meet a circle at
two points, the index is used to determine which point to return.
(intersect [Lineseg] [Lineseg]) -> Point
The second case for the intersect
function involves two line segments. The function will return the point of intersection between
the two line segments.