feat: code block, fix encoding, add markdown sample

This commit is contained in:
Artemy Egorov 2024-08-02 16:28:56 +03:00
parent 04757e69ef
commit 1dbb7e2e66
14 changed files with 345 additions and 78 deletions

193
libs/rust/Cargo.lock generated
View file

@ -8,6 +8,55 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "autocfg"
version = "1.3.0"
@ -45,6 +94,52 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "crc32fast"
version = "1.4.2"
@ -59,6 +154,7 @@ name = "dalet"
version = "1.0.0-pre4"
dependencies = [
"bincode",
"clap",
"flate2",
"num_enum",
"rmp-serde",
@ -89,6 +185,12 @@ version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indexmap"
version = "2.2.6"
@ -99,6 +201,12 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "jobserver"
version = "0.1.32"
@ -251,6 +359,12 @@ dependencies = [
"syn",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.72"
@ -285,6 +399,85 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.5.40"

View file

@ -12,6 +12,7 @@ keywords = ["dalet"]
categories = ["compression", "compilers", "encoding"]
[dependencies]
clap = { version = "4.5.13", features = ["derive"] }
num_enum = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
serde_repr = "0.1"

View file

@ -35,6 +35,7 @@ pub enum Tag {
Disc(NotNullBody),
Bl(NotNullBody, AlignArgument),
Carousel(Vec<Tag>),
Code(String, TextOrNullArgument),
}
pub trait ToDaletl {
@ -76,6 +77,7 @@ impl ToDaletlTag for Tag {
Tag::Disc(b) => t_new(Tid::Disc, b.to_daletl_body(), NA),
Tag::Bl(b, a) => t_new(Tid::Bl, b.to_daletl_body(), a.to_daletl_argument()),
Tag::Carousel(b) => t_new(Tid::Carousel, b.to_daletl_body(), NA),
Tag::Code(s, a) => t_new(Tid::Code, s.to_daletl_body(), a.to_daletl_argument()),
}
}
}
@ -91,16 +93,12 @@ pub trait ToDaletlArgument {
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive)]
#[repr(u8)]
pub enum HeadingLevel {
One,
One = 1,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
}
impl ToDaletlArgument for HeadingLevel {
@ -112,10 +110,6 @@ impl ToDaletlArgument for HeadingLevel {
HeadingLevel::Four => 4u8.to_daletl_argument(),
HeadingLevel::Five => 5u8.to_daletl_argument(),
HeadingLevel::Six => 6u8.to_daletl_argument(),
HeadingLevel::Seven => 7u8.to_daletl_argument(),
HeadingLevel::Eight => 8u8.to_daletl_argument(),
HeadingLevel::Nine => 9u8.to_daletl_argument(),
HeadingLevel::Ten => 10u8.to_daletl_argument(),
}
}
}
@ -153,6 +147,21 @@ impl ToDaletlArgument for TextOrNumberArgument {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TextOrNullArgument {
Text(String),
Null,
}
impl ToDaletlArgument for TextOrNullArgument {
fn to_daletl_argument(self) -> daletl::Argument {
match self {
Self::Text(s) => s.to_daletl_argument(),
Self::Null => NA,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Body {
Text(String),

13
libs/rust/src/commands.rs Normal file
View file

@ -0,0 +1,13 @@
use clap::{Parser, Subcommand};
#[derive(Debug, Parser)]
#[command(name = "cimengine", bin_name = "cimengine")]
#[command(about = "CIMEngine build tools")]
pub struct Cli {
#[command(subcommand)]
pub cmd: Commands,
}
#[derive(Debug, Subcommand)]
#[clap(author, version, about)]
pub enum Commands {}

View file

@ -91,4 +91,5 @@ pub enum Tid {
Disc,
Bl,
Carousel,
Code,
}

View file

@ -1,8 +1,13 @@
use crate::daletl::{Argument, Body, IsNull, Tag};
use crate::daletl::{Argument, Body, IsNull, Tag, Tid};
use super::{DaletPackError, TypeId};
pub fn encode(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
Ok(zstd::bulk::compress(&encode_no_compress(root)?, 5)
.map_err(|_| DaletPackError::ZstdCompressError)?)
}
pub fn encode_no_compress(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
if root.len() > 2usize.pow(32) {
return Err(DaletPackError::RootMaxSizeExceeded);
}
@ -13,7 +18,6 @@ pub fn encode(root: &Vec<Tag>) -> Result<Vec<u8>, DaletPackError> {
write_tag(&mut bv, tag)?;
}
// Ok(zstd::bulk::compress(&bv, 200).map_err(|_| DaletPackError::ZstdCompressError)?)
Ok(bv)
}
@ -62,7 +66,9 @@ fn write_array(bv: &mut Vec<u8>, arr: &Vec<Tag>) -> Result<(), DaletPackError> {
}
fn write_tag(bv: &mut Vec<u8>, tag: &Tag) -> Result<(), DaletPackError> {
if tag.body.is_null() && tag.argument.is_null() {
if tag.id == Tid::El {
write_tag_body(bv, &tag.body)?;
} else if tag.body.is_null() && tag.argument.is_null() {
bv.push(TypeId::TagId as u8);
bv.push(tag.id as u8);
} else if tag.argument.is_null() {
@ -87,7 +93,7 @@ fn write_tag_body(bv: &mut Vec<u8>, body: &Body) -> Result<(), DaletPackError> {
match body {
Body::Text(s) => write_str(bv, s)?,
Body::Tags(tags) => write_array(bv, tags)?,
Body::Null => unreachable!("Tag cannot be called with this value"),
Body::Null => Err(DaletPackError::WriteNullBody)?,
};
Ok(())
@ -97,7 +103,7 @@ fn write_tag_argument(bv: &mut Vec<u8>, argument: &Argument) -> Result<(), Dalet
match argument {
Argument::Text(s) => write_str(bv, s)?,
Argument::Number(n) => write_int(bv, *n),
Argument::Null => unreachable!("Tag cannot be called with this value"),
Argument::Null => Err(DaletPackError::WriteNullArgument)?,
};
Ok(())

View file

@ -2,5 +2,5 @@ mod encode;
mod types;
pub mod utils;
pub use encode::encode;
pub use encode::*;
pub use types::*;

View file

@ -6,6 +6,9 @@ pub enum DaletPackError {
ArrMaxSizeExceeded,
RootMaxSizeExceeded,
ZstdCompressError,
WriteNullBody,
WriteNullArgument,
}
#[derive(Debug, Clone, PartialEq, Eq, TryFromPrimitive, Copy)]
@ -17,7 +20,7 @@ pub enum TypeId {
Str32,
TagArray,
TagArrayEnd,
TagId,
TagId = 12,
TagIdBody,
TagIdArgument,
TagIdBodyArgument,

View file

@ -1,3 +1,3 @@
pub fn compress_zstd(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
zstd::bulk::compress(data, 5)
zstd::bulk::compress(data, 22)
}

View file

@ -1 +1,3 @@
mod commands;
fn main() {}

View file

@ -1,6 +1,6 @@
# Heading 1
## Heading 2
**Some bold and *italic* ~~text~~**
Some **bold** *italic* ~~strike~~
`Hello world`
@ -13,8 +13,5 @@
Lorem ipsum [![](https://my-picture)](https://some-link) dolor sit amet consequetur adipiscing elit
| col1 | col2 | col3 |
|:--:|----|---:|
| ----------- | -------- | ---- |
| Never gonna | give you | up |
|Never gonna|let you|down|
|Never gonna|run around|and desert you|
|**abc**|![def](https://some-picture)|*xyz*|

View file

@ -1,9 +1,9 @@
use dalet::{
abstractions::{HeadingLevel, Tag, ToDaletl},
abstractions::{Body, HeadingLevel, NotNullBody, Tag, TextOrNullArgument, ToDaletl},
daletpack::*,
};
use flate2::Compression;
use std::io::Write;
use std::io::{read_to_string, Write};
#[macro_export]
macro_rules! iprint {
@ -31,23 +31,64 @@ pub fn compress_zlib(data: &Vec<u8>) -> std::io::Result<Vec<u8>> {
#[test]
fn bench() {
let mut page: Vec<Tag> = vec![
// Tag::H("I am heading".to_owned(), HeadingLevel::One),
// Tag::H("Heading 2".to_owned(), HeadingLevel::Two),
let page: Vec<Tag> = vec![
Tag::H("I am heading".to_owned(), HeadingLevel::One),
Tag::H("Heading 2".to_owned(), HeadingLevel::Two),
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("Some ".to_owned())),
Tag::B("bold".to_owned()),
Tag::I("italic".to_owned()),
Tag::S("strike".to_owned()),
])),
Tag::Br,
Tag::Code("Hello world".to_owned(), TextOrNullArgument::Null),
Tag::Br,
Tag::Ol(vec![
Tag::El(NotNullBody::Text("abc".to_owned())),
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("def".to_owned())),
Tag::Ol(vec![
Tag::El(NotNullBody::Text("defabc".to_owned())),
Tag::El(NotNullBody::Text("defdef".to_owned())),
]),
])),
Tag::El(NotNullBody::Text("xyz".to_owned())),
]),
Tag::Br,
Tag::El(NotNullBody::Tags(vec![
Tag::El(NotNullBody::Text("Lorem ipsum ".to_owned())),
Tag::Link(
Body::Tags(vec![Tag::Img("https://my-picture".to_owned())]),
"https://some-link".to_owned(),
),
Tag::El(NotNullBody::Text(
" dolor sit amet consequetur adipiscing elit".to_owned(),
)),
])),
Tag::Table(vec![
Tag::Tpcol(vec![
Tag::El(NotNullBody::Text("Col 1".to_owned())),
Tag::El(NotNullBody::Text("Col 2".to_owned())),
Tag::El(NotNullBody::Text("Col 3".to_owned())),
]),
Tag::Tcol(vec![
Tag::El(NotNullBody::Text("Never gonna".to_owned())),
Tag::El(NotNullBody::Text("give you".to_owned())),
Tag::El(NotNullBody::Text("up".to_owned())),
]),
]),
];
for i in 0..500 {
page.push(Tag::H(format!("{}. Heading", i), HeadingLevel::One))
}
let dalet_page = page.to_daletl();
let daletpack = iprint!("Daletpack", encode(&dalet_page).unwrap());
let markdown = iprint!("Markdown", include_str!("./bench.md").as_bytes().to_vec());
let daletpack = iprint!("Daletpack", encode_no_compress(&dalet_page).unwrap());
let messagepack = iprint!("Messagepack", rmp_serde::to_vec(&dalet_page).unwrap());
let bincode = iprint!("Bincode", bincode::serialize(&dalet_page).unwrap());
println!();
iprint!("Markdown zstd", utils::compress_zstd(&markdown).unwrap());
iprint!("Daletpack zstd", utils::compress_zstd(&daletpack).unwrap());
iprint!(
"Messagepack zstd",
@ -57,18 +98,18 @@ fn bench() {
println!();
iprint!("Markdown Zlib", compress_zlib(&markdown).unwrap());
iprint!("Daletpack Zlib", compress_zlib(&daletpack).unwrap());
iprint!("Messagepack Zlib", compress_zlib(&messagepack).unwrap());
iprint!("Bincode Zlib", compress_zlib(&bincode).unwrap());
println!();
iprint!("Markdown deflate", compress_deflate(&markdown).unwrap());
iprint!("Daletpack deflate", compress_deflate(&daletpack).unwrap());
iprint!(
"Messagepack deflate",
compress_deflate(&messagepack).unwrap()
);
iprint!("Bincode deflate", compress_deflate(&bincode).unwrap());
// fs::write("./test.daletpack", daletpack).unwrap();
}

View file

@ -1,6 +1,6 @@
# DaletPack specification for Dalet v1.0-preview
DaletPack is an binary data format for Dalet, that is used for minimizing the size of transmitted data. DaletPack is designed specifically to transfer as little data as possible, it compresses the declaration of tag types into the smallest possible volume. Nothing unnecessary is transferred.
DaletPack is an binary data format for Dalet, that is used for minimizing the size of transmitted data. DaletPack is designed specifically to transfer as little data as possible, it compresses the declaration of tag types into the optimal possible volume.
All apps that supports Dalet must use this format when transmitting data between hosts.
@ -12,8 +12,8 @@ Mime type: `application/dalet-pack`
## Types
- **Integer** (2)
- **String** (5)
- **Integer**
- **String** (3)
- **Tag array**
- **Tags** (4)
- **Tag (id)**
@ -32,26 +32,23 @@ Mime type: `application/dalet-pack`
### Overview
| name | id | id-bits |
| ------------------------ | --- | ------- |
| int 4 | 0 | 0000 |
| int 8 | 1 | 0001 |
| str 3 | 2 | 0010 |
| str 4 | 3 | 0011 |
| str 8 | 4 | 0100 |
| str 16 | 5 | 0101 |
| str 32 | 6 | 0110 |
| tag array | 7 | 0111 |
| tag array end | no | 10 |
| tag (id) | 12 | 1100 |
| tag (id, body) | 13 | 1101 |
| tag (id, argument) | 14 | 1110 |
| tag (id, body, argument) | 15 | 1111 |
| name | id |
| ------------------------ | --- |
| int 8 | 1 |
| str 8 | 4 |
| str 16 | 5 |
| str 32 | 6 |
| tag array | 7 |
| tag array end | 8 |
| tag (id) | 12 |
| tag (id, body) | 13 |
| tag (id, argument) | 14 |
| tag (id, body, argument) | 15 |
### Notation in diagrams
```txt
block of bits (max 8 bits):
byte:
+--------+
| |
+--------+
@ -72,41 +69,28 @@ X - unknown bit
### Integer format
```txt
+--------+------+
| 0000 | XXXX |
+--------+------+
+--------+----------+
| 0001 | XXXXXXXX |
| 1 | XXXXXXXX |
+--------+----------+
```
### String format
```txt
str 3 (up to 8 bytes):
+--------+-----+=========+
| 0010 | XXX | utf-8 |
+--------+-----+=========+
str 4 (up to 16 bytes):
+--------+------+=========+
| 0011 | XXXX | utf-8 |
+--------+------+=========+
str 8 (up to 256 bytes):
+--------+----------+=========+
| 0100 | XXXXXXXX | utf-8 |
| 4 | XXXXXXXX | utf-8 |
+--------+----------+=========+
str 16 (up to 2^16 bytes):
+--------+----------+----------+=========+
| 0101 | XXXXXXXX | XXXXXXXX | utf-8 |
| 5 | XXXXXXXX | XXXXXXXX | utf-8 |
+--------+----------+----------+=========+
str 32 (up to 2^32 bytes):
+--------+----------+----------+----------+----------+=========+
| 0110 | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | utf-8 |
| 6 | XXXXXXXX | XXXXXXXX | XXXXXXXX | XXXXXXXX | utf-8 |
+--------+----------+----------+----------+----------+=========+
```
@ -115,7 +99,7 @@ str 32 (up to 2^32 bytes):
```txt
tag array:
+--------+~~~~~~~~~~~~+------+
| 0111 | elements | 10 |
| 7 | elements | 8 |
+--------+~~~~~~~~~~~~+------+
```
@ -127,21 +111,21 @@ id = XXXXX (5 bits) (can change before release)
tag (id):
+--------+----+
| 1100 | id |
| 12 | id |
+--------+----+
tag (id, body):
+--------+----+~~~~~~~~+
| 1101 | id | body |
| 13 | id | body |
+--------+----+~~~~~~~~+
tag (id, argument):
+--------+----+~~~~~~~~~~~~+
| 1110 | id | argument |
| 14 | id | argument |
+--------+----+~~~~~~~~~~~~+
tag (id, body, argument):
+--------+----+~~~~~~~~+~~~~~~~~~~~~+
| 1111 | id | body | argument |
| 15 | id | body | argument |
+--------+----+~~~~~~~~+~~~~~~~~~~~~+
```

View file

@ -26,7 +26,7 @@ Element also used if no tag is specified.
| name | h |
| id | 1 |
| body | text |
| argument | int x; 1 <= x <= 10 |
| argument | int x; 1 <= x <= 6 |
Heading is used for text formatting.
@ -518,3 +518,20 @@ carousel: {
Example 2,
}
```
## 28. Code
| Property | Description |
| -------- | -------------- |
| name | code |
| id | 28 |
| body | text |
| argument | optional; text |
Creates code block.
**Daleth example**:
```txt
code[js]: let code = "js"
```