A compiler for a markup language inspired by Jirai Kei. 🖤 🎀
Find a file
alyxshang 812ccf8ed1
All checks were successful
/ test (push) Successful in 1m22s
Fixed a typo.
2026-02-28 17:47:22 +01:00
.forgejo/workflows Fixed a typo. 2026-02-28 17:47:22 +01:00
sample v.0.1.0 2026-01-13 10:03:54 +01:00
src final checks. 2026-02-28 17:37:07 +01:00
.gitignore Weird. 2026-01-18 17:10:25 +01:00
Cargo.toml Updated TODOs. 2026-02-26 20:05:10 +01:00
LICENSE v.0.1.0 2026-01-13 10:03:54 +01:00
README.markdown final checks. 2026-02-28 17:37:07 +01:00

JIRAI 🖤 🎀

Jirai CI

A compiler for a markup language inspired by Jirai Kei. 🖤 🎀

ABOUT 📚

This repository contains the source code for a compiler for a Markdown-like language inspired by Jirai Kei. The compiler is a Rust crate written without any external dependencies and was made to be light and fast. The language itself was designed by me.

SPECIFICATION 🧮

List of block elements and inline elements

  • Block elements:
    • Heading: A heading starts with the <3 symbol. The number of these symbols marks the heading's level. Example: <3<3 Heading 2
    • Paragraph: Paragraphs start with a piece of text that is not an inline element. Paragraphs end with a newline character.
    • Unordered List: An unordered list can only contain list items.
  • Inline elements:
    • List item: List items start with the ~ symbol followed by a space. List items end with a newline character.
    • Link: A link is enclosed by brackets and reversed angle brackets. The link's information is inside three sections inside the brackets. Each section is delimited by square brackets. To mark the item as a link, the % operator is used to mark the item as a link. The first section is the link text. The second section is the alt text, and the third section is the URL of the link. Example: >(%[Click me!][Alt text here][https://example.com])<.
    • Code: Inline code is surrounded by angle brackets. Example:<inline code here>
    • Bold text: Bold text is surrounded by underscores. Example: _bold text here_
    • Image link: An image link is enclosed by brackets and reversed angle brackets. The image link's information is inside two sections inside the brackets. Each section is delimited by square brackets. To mark the item as an image link, the $ operator is used to mark the item as an image link. The first section is the alt text. The second section is the URL to the image. Example: >($[Alt text here][https://example.com])<.
    • Italic text: Italic text is surrounded by asterisks. Example: *italic text here*

Other rules

  • File ending: Files containing Jirai markup have to end in the .jirai file extension.
  • Comments: Comments have to start with the # operator and end with a newline character.
  • Block elements can contain any number of inline elements.
  • The following inline elements can contain other inline elements: list items, bold text, and italic text.

Extended Jirai

  • The Extended Jirai format is a format that combines a section of data written in the Jirai Markup Language and a section of text written in Jirai. The document has to start and end with the (^-^) symbol and the data section has to be separated from the text section with the same symbol.

USAGE ⚒️

CLI Installation

If you want to use the cli feature this crate offers, you can either install a binary or, assuming you have the Rust toolchain installed, install the compiler as a CLI tool with Rust's package manager, Cargo, by running the command below:

cargo install --git https://source.alyxshang.boo/alyxshang/jirai --features=cli --tag v.0.3.0

There are pre-compiled binaries for the following platforms:

  • Mac OS for Intel chips: Download the appropriate executable from here, rename it, and place it in a directory on your $PATH.
  • Mac OS for Apple chips: Download the appropriate executable from here, rename it, and place it in a directory on your $PATH.
  • Debian for 64-bit chips: Download the file ending in .deb from here and install it with the command sudo dpkg -i file_name.deb, where file_name is the name of the file ending in .deb.
  • Arch Linux for 64-bit chips: Download the file ending in .pkg.tar.zst from here and install it with the command sudo pacman -U file_name.pkg.tar.zst, where file_name is the name of the file ending in .pkg.tar.zst.
  • Windows for 64-bit chips: Download the appropriate executable from here, rename it, and place it in a directory on your $PATH.

CLI Usage

The CLI offers the three following commands:

  • jiraic --help: This will output usage information.
  • jiraic --version: This will output version information.
  • jiraic --lint /path/to/jirai/file.jirai: This will check the specified file for syntactic validity but not compile the Jirai file.
  • jiraic --build /path/to/jirai/file.jirai: This will output an HTML file with the same stem as the input file. You can optionally supply an --out /path/to/output/file.html flag to specify the location of the target HTML file.

Crate Usage

To add the Jirai crate to your Rust project and to compile text written in the Jirai format into HTML, add the following line to the dependencies section of your project's Cargo.toml:

jirai = { git = "https://source.alyxshang.boo/alyxshang/jirai", tag = "v.0.2.0" }

If you want to use the ejirai feature this crate offers, you would add the following line to the dependencies section of your project's Cargo.toml:

jirai = { git = "https://source.alyxshang.boo/alyxshang/jirai", tag = "v.0.2.0", features = ["ejirai"] }

You would use the Jirai crate in your code in a manner similar to the one outlined in the code samples below. These code samples assume that you have a file called sample.jirai in the same directory as your Cargo.toml.

# sample.jirai

<3 Heading 1
# This is a comment.
This is normal text with a very long sentence.
This is a sentence containing *italic* and _bold text_.
This is a link to an image >($[alt][https://alyxshang.boo])<.
This text contains some _bold text_.
This text contains some *italic text*.

<3<3 Heading 2

This paragraph contains some _nested *italic* text_.
And this is a >(%[link to my site][link to my site][https://alyxshang.boo])<.

~ This is item one of an unordered list.
~ This is item two of an unordered list.

The sample below illustrates how to use the to_html function to compile the Jirai code above into HTML code.

use jirai::from_str;
use std::path::PathBuf;
use std::fs::read_to_string;

fn main(){
    let jirai_file_path: PathBuf = PathBuf::new();
    jirai_file_path.push(env!("CARGO_MANIFEST_DIR"));
    jirai_file_path.push(env!("sample.jirai"));
    let file_contents: String = read_to_string(
        &jirai_file_path.display().to_string()
    ).expect("Could not read file.");
    let code: String = to_html(&file_contents)
        .expect("Could not compile Jirai code to HTML.");
    println!("{:?}", &code); // should output HTML code.
}

If you want to use Extended Jirai in your project, you would use the jirai crate in your code in the following manner. These code samples assume that you have a file called sample.ejirai in the same directory as your Cargo.toml.

(^-^)
# sample.ejirai
"layout" >~< "page"
"title" >~< "Page Title"
(^-^)
<3 Heading 1
# This is a comment.
This is normal text with a very long sentence.
This is a sentence containing *italic* and _bold text_.
This is a link to an image >($[alt][https://alyxshang.boo])<.
This text contains some _bold text_.
This text contains some *italic text*.

<3<3 Heading 2

This paragraph contains some _nested *italic* text_.
And this is a >(%[link to my site][link to my site][https://alyxshang.boo])<.

~ This is item one of an unordered list.
~ This is item two of an unordered list.
(^-^)

The Rust code sample below illustrates how you would use this crate and serde to deserialize an Extended Jirai document.

use serde::Deserialize;
use jirai::from_ejirai;
use std::path::PathBuf;
use jirai::ExtendedJirai;
use std::fs::read_to_string;

#[derive(Deserialize, Debug)]
pub struct PageData{
    pub title: String,
    pub layout: String
}

fn main(){
    let ejirai_file_path: PathBuf = PathBuf::new();
    ejirai_file_path.push(env!("CARGO_MANIFEST_DIR"));
    ejirai_file_path.push(env!("sample.ejirai"));
    let file_contents: String = read_to_string(
        &ejirai_file_path.display().to_string()
    );
    let deserialized: ExtendedJirai<PageData> = from_ejirai(&file_contents)
        .expect("Could not deserialize Extended Jirai code.");
    println!("{:?}", &deserialized.data); // should output "PageData"
    println!("{:?)", &deserialized.code); // should output HTML code
}

More information on the entities inside this crate can be obtained by reading the API documentation of this crate. The documentation can be read by cloning this repository and running the command cargo doc --open from the root of the repository.

CHANGELOG ✒️

Version 0.1.0

  • Initial release.
  • Initial upload to Forgejo.

Version 0.2.0

  • Added documentation.
  • Added a CLI to compile a .jirai file into a .html file.
  • Added the above functionality via the cli crate feature.
  • Made it possible for an Extended Jirai document to only have a data section.

Version 0.3.0

  • Restructured documentation.
  • Added documentation about the linter.
  • Added a lint_str function to lint a string of Jirai source.
  • Added an option to the CLI to check a Jirai file for syntactic validity.
  • Added a function to compile a Jirai file with a custom output file name.
  • Added an option to the CLI to supply a custom file name for the output file.
  • Added a function to compile a Jirai file into an HTML file with the same name prefix.
  • Added a lint_file function to lint a string obtained from a file containing Jirai source.

NOTE 📜

  • Jirai 🖤 🎀 by Alyx Shang 🖤.
  • Licensed under the FSL v1.