Compare commits
No commits in common. "master" and "postion" have entirely different histories.
8
.github/dependabot.yml
vendored
8
.github/dependabot.yml
vendored
|
@ -1,8 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: cargo
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
time: "09:00"
|
|
||||||
open-pull-requests-limit: 10
|
|
10
.github/workflows/rust.yml
vendored
10
.github/workflows/rust.yml
vendored
|
@ -1,13 +1,17 @@
|
||||||
name: Rust
|
name: Rust
|
||||||
|
|
||||||
on: [push, pull_request]
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
format:
|
format:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: Run rustfmt
|
- name: Run rustfmt
|
||||||
run: cargo fmt -- --check
|
run: cargo fmt -- --check
|
||||||
|
@ -16,7 +20,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
|
|
34
.github/workflows/wasm.yml
vendored
34
.github/workflows/wasm.yml
vendored
|
@ -1,34 +0,0 @@
|
||||||
name: Wasm
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: wasm
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: "14"
|
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: |
|
|
||||||
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
|
||||||
yarn
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
wasm-pack build --target web --out-dir wasm/pkg -- --features wasm
|
|
||||||
yarn build
|
|
||||||
|
|
||||||
- name: Deploy to gh pages
|
|
||||||
uses: JamesIves/github-pages-deploy-action@4.1.5
|
|
||||||
with:
|
|
||||||
branch: gh-pages
|
|
||||||
folder: wasm/lib
|
|
45
Cargo.toml
45
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "orgize"
|
name = "orgize"
|
||||||
version = "0.9.0"
|
version = "0.8.4"
|
||||||
authors = ["PoiScript <poiscript@gmail.com>"]
|
authors = ["PoiScript <poiscript@gmail.com>"]
|
||||||
description = "A Rust library for parsing orgmode files."
|
description = "A Rust library for parsing orgmode files."
|
||||||
repository = "https://github.com/PoiScript/orgize"
|
repository = "https://github.com/PoiScript/orgize"
|
||||||
|
@ -8,7 +8,6 @@ readme = "README.md"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
keywords = ["orgmode", "emacs", "parser"]
|
keywords = ["orgmode", "emacs", "parser"]
|
||||||
exclude = ["/wasm", "/.github"]
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
@ -16,36 +15,24 @@ all-features = true
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "PoiScript/orgize" }
|
travis-ci = { repository = "PoiScript/orgize" }
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["cdylib", "rlib"]
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
# Tell `rustc` to optimize for small code size.
|
|
||||||
opt-level = "s"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ser"]
|
default = ["ser"]
|
||||||
wasm = ["serde-wasm-bindgen", "wasm-bindgen", "wee_alloc"]
|
ser = ["serde", "serde_indextree"]
|
||||||
ser = ["serde", "serde_indextree", "indexmap/serde-1"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytecount = "0.6"
|
bytecount = "0.6.0"
|
||||||
chrono = { version = "0.4", optional = true }
|
chrono = { version = "0.4.11", optional = true }
|
||||||
indextree = "4.3"
|
indextree = "4.0.0"
|
||||||
jetscii = "0.5"
|
jetscii = "0.4.4"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4.0"
|
||||||
memchr = "2.4"
|
memchr = "2.3.3"
|
||||||
nom = { version = "7.0", default-features = false, features = ["std"] }
|
# we don't need to parse any float number, so lexical crate is redundant
|
||||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
nom = { version = "5.1.1", default-features = false, features = ["std"] }
|
||||||
serde_indextree = { version = "0.2", optional = true }
|
serde = { version = "1.0.106", optional = true, features = ["derive"] }
|
||||||
syntect = { version = "4.6", optional = true }
|
serde_indextree = { version = "0.2.0", optional = true }
|
||||||
indexmap = { version = "1.7", features = ["serde-1"], optional = true }
|
syntect = { version = "4.1.0", optional = true }
|
||||||
# wasm stuff
|
|
||||||
serde-wasm-bindgen = { version = "0.3", optional = true }
|
|
||||||
wasm-bindgen = { version = "0.2", optional = true }
|
|
||||||
wee_alloc = { version = "0.4", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.0"
|
pretty_assertions = "0.6.1"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0.51"
|
||||||
slugify = "0.1"
|
slugify = "0.1.0"
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2021 Alex Lin (poi)
|
Copyright (c) 2019 Alex Lin (poi)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -195,7 +195,7 @@ println!("{}", to_string(&org).unwrap());
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
By now, orgize provides four features:
|
By now, orgize provides three features:
|
||||||
|
|
||||||
+ `ser`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default.
|
+ `ser`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default.
|
||||||
|
|
||||||
|
@ -203,8 +203,6 @@ By now, orgize provides four features:
|
||||||
|
|
||||||
+ `syntect`: provides `SyntectHtmlHandler` for highlighting code block, disabled by default.
|
+ `syntect`: provides `SyntectHtmlHandler` for highlighting code block, disabled by default.
|
||||||
|
|
||||||
+ `indexmap`: Uses `IndexMap` instead of `HashMap` for properties to preserve their order, disabled by default.
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT
|
MIT
|
||||||
|
|
942
docs/SYNTAX.md
942
docs/SYNTAX.md
|
@ -1,942 +0,0 @@
|
||||||
# Table of Contents
|
|
||||||
|
|
||||||
1. [Headlines and Sections](#Headlines_and_Sections)
|
|
||||||
2. [Affiliated Keywords](#Affiliated_keywords)
|
|
||||||
3. [Greater Elements](#Greater_Elements)
|
|
||||||
1. [Greater Blocks](#Greater_Blocks)
|
|
||||||
2. [Drawers and Property Drawers](#Drawers)
|
|
||||||
3. [Dynamic Blocks](#Dynamic_Blocks)
|
|
||||||
4. [Footnote Definitions](#Footnote_Definitions)
|
|
||||||
5. [Inlinetasks](#Inlinetasks)
|
|
||||||
6. [Plain Lists and Items](#Plain_Lists_and_Items)
|
|
||||||
7. [Property Drawers](#Property_Drawers)
|
|
||||||
8. [Tables](#Tables)
|
|
||||||
4. [Elements](#Elements)
|
|
||||||
1. [Babel Call](#Babel_Call)
|
|
||||||
2. [Blocks](#Blocks)
|
|
||||||
3. [Clock, Diary Sexp and Planning](#Clock,_Diary_Sexp_and_Planning)
|
|
||||||
4. [Comments](#Comments)
|
|
||||||
5. [Fixed Width Areas](#Fixed_Width_Areas)
|
|
||||||
6. [Horizontal Rules](#Horizontal_Rules)
|
|
||||||
7. [Keywords](#Keywords)
|
|
||||||
8. [LaTeX Environments](#LaTeX_Environments)
|
|
||||||
9. [Node Properties](#Node_Properties)
|
|
||||||
10. [Paragraphs](#Paragraphs)
|
|
||||||
11. [Table Rows](#Table_Rows)
|
|
||||||
5. [Objects](#Objects)
|
|
||||||
1. [Entities and LaTeX Fragments](#Entities_and_LaTeX_Fragments)
|
|
||||||
2. [Export Snippets](#Export_Snippets)
|
|
||||||
3. [Footnote References](#Footnote_References)
|
|
||||||
4. [Inline Babel Calls and Source
|
|
||||||
Blocks](#Inline_Babel_Calls_and_Source_Blocks)
|
|
||||||
5. [Line Breaks](#Line_Breaks)
|
|
||||||
6. [Links](#Links)
|
|
||||||
7. [Macros](#Macros)
|
|
||||||
8. [Targets and Radio Targets](#Targets_and_Radio_Targets)
|
|
||||||
9. [Statistics Cookies](#Statistics_Cookies)
|
|
||||||
10. [Subscript and Superscript](#Subscript_and_Superscript)
|
|
||||||
11. [Table Cells](#Table_Cells)
|
|
||||||
12. [Timestamps](#Timestamp)
|
|
||||||
13. [Text Markup](#Emphasis_Markers)
|
|
||||||
|
|
||||||
This document describes and comments Org syntax as it is currently read by its
|
|
||||||
parser (Org Elements) and, therefore, by the export framework. It also includes
|
|
||||||
a few comments on that syntax.
|
|
||||||
|
|
||||||
A core concept in this syntax is that only headlines, sections, planning lines
|
|
||||||
and property drawers are context-free<sup><a id="fnr.1" class="footref"
|
|
||||||
href="#fn.1">1</a></sup><sup>, </sup><sup><a id="fnr.2" class="footref"
|
|
||||||
href="#fn.2">2</a></sup>. Every other syntactical part only exists within
|
|
||||||
specific environments.
|
|
||||||
|
|
||||||
Three categories are used to classify these environments: **Greater elements**,
|
|
||||||
**elements**, and **objects**, from the broadest scope to the narrowest. The
|
|
||||||
word **element** is used for both Greater and non-Greater elements, the context
|
|
||||||
should make that clear.
|
|
||||||
|
|
||||||
The paragraph is the unit of measurement. An element defines syntactical parts
|
|
||||||
that are at the same level as a paragraph, i.e. which cannot contain or be
|
|
||||||
included in a paragraph. An object is a part that could be included in an
|
|
||||||
element. Greater elements are all parts that can contain an element.
|
|
||||||
|
|
||||||
Empty lines belong to the largest element ending before them. For example, in a
|
|
||||||
list, empty lines between items belong are part of the item before them, but
|
|
||||||
empty lines at the end of a list belong to the plain list element.
|
|
||||||
|
|
||||||
Unless specified otherwise, case is not significant.
|
|
||||||
|
|
||||||
<a id="Headlines_and_Sections"></a>
|
|
||||||
|
|
||||||
# Headlines and Sections
|
|
||||||
|
|
||||||
A headline is defined as:
|
|
||||||
|
|
||||||
STARS KEYWORD PRIORITY TITLE TAGS
|
|
||||||
|
|
||||||
STARS is a string starting at column 0, containing at least one asterisk (and up
|
|
||||||
to `org-inlinetask-min-level` if `org-inlinetask` library is loaded) and ended
|
|
||||||
by a space character. The number of asterisks is used to define the level of the
|
|
||||||
headline. It's the sole compulsory part of a headline.
|
|
||||||
|
|
||||||
KEYWORD is a TODO keyword, which has to belong to the list defined in
|
|
||||||
`org-todo-keywords-1`. Case is significant.
|
|
||||||
|
|
||||||
PRIORITY is a priority cookie, i.e. a single letter preceded by a hash sign #
|
|
||||||
and enclosed within square brackets.
|
|
||||||
|
|
||||||
TITLE can be made of any character but a new line. Though, it will match after
|
|
||||||
every other part have been matched.
|
|
||||||
|
|
||||||
TAGS is made of words containing any alpha-numeric character, underscore, at
|
|
||||||
sign, hash sign or percent sign, and separated with colons.
|
|
||||||
|
|
||||||
Examples of valid headlines include:
|
|
||||||
|
|
||||||
*
|
|
||||||
|
|
||||||
** DONE
|
|
||||||
|
|
||||||
*** Some e-mail
|
|
||||||
|
|
||||||
**** TODO [#A] COMMENT Title :tag:a2%:
|
|
||||||
|
|
||||||
If the first word appearing in the title is `COMMENT`, the headline will be
|
|
||||||
considered as **commented**. Case is significant.
|
|
||||||
|
|
||||||
If its title is `org-footnote-section`, it will be considered as a **footnote
|
|
||||||
section**. Case is significant.
|
|
||||||
|
|
||||||
If `ARCHIVE` is one of its tags, it will be considered as **archived**. Case is
|
|
||||||
significant.
|
|
||||||
|
|
||||||
A headline contains directly one section (optionally), followed by any number of
|
|
||||||
deeper level headlines.
|
|
||||||
|
|
||||||
A section contains directly any greater element or element. Only a headline can
|
|
||||||
contain a section. As an exception, text before the first headline in the
|
|
||||||
document also belongs to a section.
|
|
||||||
|
|
||||||
As an example, consider the following document:
|
|
||||||
|
|
||||||
An introduction.
|
|
||||||
|
|
||||||
* A Headline
|
|
||||||
|
|
||||||
Some text.
|
|
||||||
|
|
||||||
** Sub-Topic 1
|
|
||||||
|
|
||||||
** Sub-Topic 2
|
|
||||||
|
|
||||||
*** Additional entry
|
|
||||||
|
|
||||||
Its internal structure could be summarized as:
|
|
||||||
|
|
||||||
(document
|
|
||||||
(section)
|
|
||||||
(headline
|
|
||||||
(section)
|
|
||||||
(headline)
|
|
||||||
(headline
|
|
||||||
(headline))))
|
|
||||||
|
|
||||||
<a id="Affiliated_keywords"></a>
|
|
||||||
|
|
||||||
# Affiliated Keywords
|
|
||||||
|
|
||||||
With the exception of [inlinetasks](#Inlinetasks),
|
|
||||||
[items](#Plain_Lists_and_Items), [planning](#Clock,_Diary_Sexp_and_Planning),
|
|
||||||
[clocks](#Clock,_Diary_Sexp_and_Planning), [node properties](#Node_Properties)
|
|
||||||
and [table rows](#Table_Rows), every other element type can be assigned
|
|
||||||
attributes.
|
|
||||||
|
|
||||||
This is done by adding specific keywords, named **affiliated keywords**, just
|
|
||||||
above the element considered, no blank line allowed.
|
|
||||||
|
|
||||||
Affiliated keywords are built upon one of the following patterns: `#+KEY: VALUE`,
|
|
||||||
`#+KEY[OPTIONAL]: VALUE` or `#+ATTR_BACKEND: VALUE`.
|
|
||||||
|
|
||||||
KEY is either `CAPTION`, `HEADER`, `NAME`, `PLOT` or `RESULTS` string.
|
|
||||||
|
|
||||||
BACKEND is a string constituted of alpha-numeric characters, hyphens or
|
|
||||||
underscores.
|
|
||||||
|
|
||||||
OPTIONAL and VALUE can contain any character but a new line. Only `CAPTION` and
|
|
||||||
`RESULTS` keywords can have an optional value.
|
|
||||||
|
|
||||||
An affiliated keyword can appear more than once if KEY is either `CAPTION` or
|
|
||||||
`HEADER` or if its pattern is `#+ATTR_BACKEND: VALUE`.
|
|
||||||
|
|
||||||
`CAPTION`, `AUTHOR`, `DATE` and `TITLE` keywords can contain objects in their
|
|
||||||
value and their optional value, if applicable.
|
|
||||||
|
|
||||||
<a id="Greater_Elements"></a>
|
|
||||||
|
|
||||||
# Greater Elements
|
|
||||||
|
|
||||||
Unless specified otherwise, greater elements can contain directly any other
|
|
||||||
element or greater element excepted:
|
|
||||||
|
|
||||||
- elements of their own type,
|
|
||||||
- [node properties](#Node_Properties), which can only be found in [property
|
|
||||||
drawers](#Property_Drawers),
|
|
||||||
- [items](#Plain_Lists_and_Items), which can only be found in [plain
|
|
||||||
lists](#Plain_Lists_and_Items).
|
|
||||||
|
|
||||||
<a id="Greater_Blocks"></a>
|
|
||||||
|
|
||||||
## Greater Blocks
|
|
||||||
|
|
||||||
Greater blocks consist in the following pattern:
|
|
||||||
|
|
||||||
#+BEGIN_NAME PARAMETERS
|
|
||||||
CONTENTS
|
|
||||||
#+END_NAME
|
|
||||||
|
|
||||||
NAME can contain any non-whitespace character.
|
|
||||||
|
|
||||||
PARAMETERS can contain any character other than new line, and can be omitted.
|
|
||||||
|
|
||||||
If NAME is `CENTER`, it will be a **center block**. If it is `QUOTE`, it will be
|
|
||||||
a **quote block**.
|
|
||||||
|
|
||||||
If the block is neither a center block, a quote block or a [block
|
|
||||||
element](#Blocks), it will be a **special block**.
|
|
||||||
|
|
||||||
CONTENTS can contain any element, except : a line `#+END_NAME` on its own. Also
|
|
||||||
lines beginning with STARS must be quoted by a comma.
|
|
||||||
|
|
||||||
<a id="Drawers"></a>
|
|
||||||
|
|
||||||
## Drawers and Property Drawers
|
|
||||||
|
|
||||||
Pattern for drawers is:
|
|
||||||
|
|
||||||
:NAME:
|
|
||||||
CONTENTS
|
|
||||||
:END:
|
|
||||||
|
|
||||||
NAME can contain word-constituent characters, hyphens and underscores.
|
|
||||||
|
|
||||||
CONTENTS can contain any element but another drawer.
|
|
||||||
|
|
||||||
<a id="Dynamic_Blocks"></a>
|
|
||||||
|
|
||||||
## Dynamic Blocks
|
|
||||||
|
|
||||||
Pattern for dynamic blocks is:
|
|
||||||
|
|
||||||
#+BEGIN: NAME PARAMETERS
|
|
||||||
CONTENTS
|
|
||||||
#+END:
|
|
||||||
|
|
||||||
NAME cannot contain any whitespace character.
|
|
||||||
|
|
||||||
PARAMETERS can contain any character and can be omitted.
|
|
||||||
|
|
||||||
<a id="Footnote_Definitions"></a>
|
|
||||||
|
|
||||||
## Footnote Definitions
|
|
||||||
|
|
||||||
Pattern for footnote definitions is:
|
|
||||||
|
|
||||||
[fn:LABEL] CONTENTS
|
|
||||||
|
|
||||||
It must start at column 0.
|
|
||||||
|
|
||||||
LABEL is either a number or follows the pattern `fn:WORD`, where word can
|
|
||||||
contain any word-constituent character, hyphens and underscore characters.
|
|
||||||
|
|
||||||
CONTENTS can contain any element excepted another footnote definition. It ends
|
|
||||||
at the next footnote definition, the next headline, two consecutive empty lines
|
|
||||||
or the end of buffer.
|
|
||||||
|
|
||||||
<a id="Inlinetasks"></a>
|
|
||||||
|
|
||||||
## Inlinetasks
|
|
||||||
|
|
||||||
Inlinetasks are defined by `org-inlinetask-min-level` contiguous asterisk
|
|
||||||
characters starting at column 0, followed by a whitespace character.
|
|
||||||
|
|
||||||
Optionally, inlinetasks can be ended with a string constituted of
|
|
||||||
`org-inlinetask-min-level` contiguous asterisk characters starting at column 0,
|
|
||||||
followed by a space and the `END` string.
|
|
||||||
|
|
||||||
Inlinetasks are recognized only after `org-inlinetask` library is loaded.
|
|
||||||
|
|
||||||
<a id="Plain_Lists_and_Items"></a>
|
|
||||||
|
|
||||||
## Plain Lists and Items
|
|
||||||
|
|
||||||
Items are defined by a line starting with the following pattern:
|
|
||||||
`BULLET COUNTER-SET CHECK-BOX TAG`, in which only BULLET is mandatory.
|
|
||||||
|
|
||||||
BULLET is either an asterisk, a hyphen, a plus sign character or follows either
|
|
||||||
the pattern `COUNTER.` or `COUNTER)`. In any case, BULLET is follwed by a
|
|
||||||
whitespace character or line ending.
|
|
||||||
|
|
||||||
COUNTER can be a number or a single letter.
|
|
||||||
|
|
||||||
COUNTER-SET follows the pattern [@COUNTER].
|
|
||||||
|
|
||||||
CHECK-BOX is either a single whitespace character, a `X` character or a hyphen,
|
|
||||||
enclosed within square brackets.
|
|
||||||
|
|
||||||
TAG follows `TAG-TEXT ::` pattern, where TAG-TEXT can contain any character but
|
|
||||||
a new line.
|
|
||||||
|
|
||||||
An item ends before the next item, the first line less or equally indented than
|
|
||||||
its starting line, or two consecutive empty lines. Indentation of lines within
|
|
||||||
other greater elements do not count, neither do inlinetasks boundaries.
|
|
||||||
|
|
||||||
A plain list is a set of consecutive items of the same indentation. It can only
|
|
||||||
directly contain items.
|
|
||||||
|
|
||||||
If first item in a plain list has a counter in its bullet, the plain list will
|
|
||||||
be an **ordered plain-list**. If it contains a tag, it will be a **descriptive
|
|
||||||
list**. Otherwise, it will be an **unordered list**. List types are mutually
|
|
||||||
exclusive.
|
|
||||||
|
|
||||||
For example, consider the following excerpt of an Org document:
|
|
||||||
|
|
||||||
1. item 1
|
|
||||||
2. [X] item 2
|
|
||||||
- some tag :: item 2.1
|
|
||||||
|
|
||||||
Its internal structure is as follows:
|
|
||||||
|
|
||||||
(ordered-plain-list
|
|
||||||
(item)
|
|
||||||
(item
|
|
||||||
(descriptive-plain-list
|
|
||||||
(item))))
|
|
||||||
|
|
||||||
<a id="Property_Drawers"></a>
|
|
||||||
|
|
||||||
## Property Drawers
|
|
||||||
|
|
||||||
Property drawers are a special type of drawer containing properties attached to
|
|
||||||
a headline. They are located right after a [headline](#Headlines_and_Sections)
|
|
||||||
and its [planning](#Clock,_Diary_Sexp_and_Planning) information.
|
|
||||||
|
|
||||||
HEADLINE
|
|
||||||
PROPERTYDRAWER
|
|
||||||
|
|
||||||
HEADLINE
|
|
||||||
PLANNING
|
|
||||||
PROPERTYDRAWER
|
|
||||||
|
|
||||||
PROPERTYDRAWER follows the pattern
|
|
||||||
|
|
||||||
:PROPERTIES:
|
|
||||||
CONTENTS
|
|
||||||
:END:
|
|
||||||
|
|
||||||
where CONTENTS consists of zero or more [node properties](#Node_Properties).
|
|
||||||
|
|
||||||
<a id="Tables"></a>
|
|
||||||
|
|
||||||
## Tables
|
|
||||||
|
|
||||||
Tables start at lines beginning with either a vertical bar or the `+-` string
|
|
||||||
followed by plus or minus signs only, assuming they are not preceded with lines
|
|
||||||
of the same type. These lines can be indented.
|
|
||||||
|
|
||||||
A table starting with a vertical bar has `org` type. Otherwise it has `table.el`
|
|
||||||
type.
|
|
||||||
|
|
||||||
Org tables end at the first line not starting with a vertical bar. Table.el
|
|
||||||
tables end at the first line not starting with either a vertical line or a plus
|
|
||||||
sign. Such lines can be indented.
|
|
||||||
|
|
||||||
An org table can only contain table rows. A table.el table does not contain
|
|
||||||
anything.
|
|
||||||
|
|
||||||
One or more `#+TBLFM: FORMULAS` lines, where `FORMULAS` can contain any
|
|
||||||
character, can follow an org table.
|
|
||||||
|
|
||||||
<a id="Elements"></a>
|
|
||||||
|
|
||||||
# Elements
|
|
||||||
|
|
||||||
Elements cannot contain any other element.
|
|
||||||
|
|
||||||
Only [keywords](#Keywords) whose name belongs to
|
|
||||||
`org-element-document-properties`, [verse blocks](#Blocks) ,
|
|
||||||
[paragraphs](#Paragraphs) and [table rows](#Table_Rows) can contain objects.
|
|
||||||
|
|
||||||
<a id="Babel_Call"></a>
|
|
||||||
|
|
||||||
## Babel Call
|
|
||||||
|
|
||||||
Pattern for babel calls is:
|
|
||||||
|
|
||||||
#+CALL: VALUE
|
|
||||||
|
|
||||||
VALUE is optional. It can contain any character but a new line.
|
|
||||||
|
|
||||||
<a id="Blocks"></a>
|
|
||||||
|
|
||||||
## Blocks
|
|
||||||
|
|
||||||
Like [greater blocks](#Greater_Blocks), pattern for blocks is:
|
|
||||||
|
|
||||||
#+BEGIN_NAME DATA
|
|
||||||
CONTENTS
|
|
||||||
#+END_NAME
|
|
||||||
|
|
||||||
NAME cannot contain any whitespace character.
|
|
||||||
|
|
||||||
1. If NAME is `COMMENT`, it will be a **comment block**.
|
|
||||||
2. If it is `EXAMPLE`, it will be an **example block**.
|
|
||||||
3. If it is `EXPORT`, it will be an **export block**.
|
|
||||||
4. If it is `SRC`, it will be a **source block**.
|
|
||||||
5. If it is `VERSE`, it will be a **verse block**.
|
|
||||||
|
|
||||||
DATA can contain any character but a new line. It can be ommitted, unless the
|
|
||||||
block is either a **source block** or an **export block**.
|
|
||||||
|
|
||||||
In the latter case, it should be constituted of a single word.
|
|
||||||
|
|
||||||
In the former case, it must follow the pattern `LANGUAGE SWITCHES ARGUMENTS`,
|
|
||||||
where SWITCHES and ARGUMENTS are optional.
|
|
||||||
|
|
||||||
LANGUAGE cannot contain any whitespace character.
|
|
||||||
|
|
||||||
SWITCHES is made of any number of `SWITCH` patterns, separated by blank lines.
|
|
||||||
|
|
||||||
A SWITCH pattern is either `-l FORMAT`, where FORMAT can contain any character
|
|
||||||
but a double quote and a new line, `-S` or `+S`, where S stands for a single
|
|
||||||
letter.
|
|
||||||
|
|
||||||
ARGUMENTS can contain any character but a new line.
|
|
||||||
|
|
||||||
CONTENTS can contain any character, including new lines. Though it will only
|
|
||||||
contain Org objects if the block is a verse block. Otherwise, CONTENTS will not
|
|
||||||
be parsed.
|
|
||||||
|
|
||||||
<a id="Clock,_Diary_Sexp_and_Planning"></a>
|
|
||||||
|
|
||||||
## Clock, Diary Sexp and Planning
|
|
||||||
|
|
||||||
A clock follows either of the patterns below:
|
|
||||||
|
|
||||||
CLOCK: INACTIVE-TIMESTAMP
|
|
||||||
CLOCK: INACTIVE-TIMESTAMP-RANGE DURATION
|
|
||||||
|
|
||||||
INACTIVE-TIMESTAMP, resp. INACTIVE-TIMESTAMP-RANGE, is an inactive, resp.
|
|
||||||
inactive range, [timestamp](#Timestamp) object.
|
|
||||||
|
|
||||||
DURATION follows the pattern:
|
|
||||||
|
|
||||||
=> HH:MM
|
|
||||||
|
|
||||||
HH is a number containing any number of digits. MM is a two digit numbers.
|
|
||||||
|
|
||||||
A diary sexp is a line starting at column 0 with `%%(` string. It can then
|
|
||||||
contain any character besides a new line.
|
|
||||||
|
|
||||||
A planning is an element with the following pattern:
|
|
||||||
|
|
||||||
HEADLINE
|
|
||||||
PLANNING
|
|
||||||
|
|
||||||
where HEADLINE is a [headline](#Headlines_and_Sections) element and PLANNING is
|
|
||||||
a line filled with INFO parts, where each of them follows the pattern:
|
|
||||||
|
|
||||||
KEYWORD: TIMESTAMP
|
|
||||||
|
|
||||||
KEYWORD is either `DEADLINE`, `SCHEDULED` or `CLOSED`. TIMESTAMP is a
|
|
||||||
[timestamp](#Timestamp) object.
|
|
||||||
|
|
||||||
In particular, no blank line is allowed between PLANNING and HEADLINE.
|
|
||||||
|
|
||||||
<a id="Comments"></a>
|
|
||||||
|
|
||||||
## Comments
|
|
||||||
|
|
||||||
A **comment line** starts with a hash signe and a whitespace character or an end
|
|
||||||
of line.
|
|
||||||
|
|
||||||
Comments can contain any number of consecutive comment lines.
|
|
||||||
|
|
||||||
<a id="Fixed_Width_Areas"></a>
|
|
||||||
|
|
||||||
## Fixed Width Areas
|
|
||||||
|
|
||||||
A **fixed-width line** start with a colon character and a whitespace or an end
|
|
||||||
of line.
|
|
||||||
|
|
||||||
Fixed width areas can contain any number of consecutive fixed-width lines.
|
|
||||||
|
|
||||||
<a id="Horizontal_Rules"></a>
|
|
||||||
|
|
||||||
## Horizontal Rules
|
|
||||||
|
|
||||||
A horizontal rule is a line made of at least 5 consecutive hyphens. It can be
|
|
||||||
indented.
|
|
||||||
|
|
||||||
<a id="Keywords"></a>
|
|
||||||
|
|
||||||
## Keywords
|
|
||||||
|
|
||||||
Keywords follow the syntax:
|
|
||||||
|
|
||||||
#+KEY: VALUE
|
|
||||||
|
|
||||||
KEY can contain any non-whitespace character, but it cannot be equal to `CALL`
|
|
||||||
or any affiliated keyword.
|
|
||||||
|
|
||||||
VALUE can contain any character excepted a new line.
|
|
||||||
|
|
||||||
If KEY belongs to `org-element-document-properties`, VALUE can contain objects.
|
|
||||||
|
|
||||||
<a id="LaTeX_Environments"></a>
|
|
||||||
|
|
||||||
## LaTeX Environments
|
|
||||||
|
|
||||||
Pattern for LaTeX environments is:
|
|
||||||
|
|
||||||
\begin{NAME} CONTENTS \end{NAME}
|
|
||||||
|
|
||||||
NAME is constituted of alpha-numeric or asterisk characters.
|
|
||||||
|
|
||||||
CONTENTS can contain anything but the `\end{NAME}` string.
|
|
||||||
|
|
||||||
<a id="Node_Properties"></a>
|
|
||||||
|
|
||||||
## Node Properties
|
|
||||||
|
|
||||||
Node properties can only exist in [property drawers](#Property_Drawers). Their
|
|
||||||
pattern is any of the following
|
|
||||||
|
|
||||||
:NAME: VALUE
|
|
||||||
|
|
||||||
:NAME+: VALUE
|
|
||||||
|
|
||||||
:NAME:
|
|
||||||
|
|
||||||
:NAME+:
|
|
||||||
|
|
||||||
NAME can contain any non-whitespace character but cannot end with a plus sign.
|
|
||||||
It cannot be the empty string.
|
|
||||||
|
|
||||||
VALUE can contain anything but a newline character.
|
|
||||||
|
|
||||||
<a id="Paragraphs"></a>
|
|
||||||
|
|
||||||
## Paragraphs
|
|
||||||
|
|
||||||
Paragraphs are the default element, which means that any unrecognized context is
|
|
||||||
a paragraph.
|
|
||||||
|
|
||||||
Empty lines and other elements end paragraphs.
|
|
||||||
|
|
||||||
Paragraphs can contain every type of object.
|
|
||||||
|
|
||||||
<a id="Table_Rows"></a>
|
|
||||||
|
|
||||||
## Table Rows
|
|
||||||
|
|
||||||
A table rows is either constituted of a vertical bar and any number of [table
|
|
||||||
cells](#Table_Cells) or a vertical bar followed by a hyphen.
|
|
||||||
|
|
||||||
In the first case the table row has the **standard** type. In the second case,
|
|
||||||
it has the **rule** type.
|
|
||||||
|
|
||||||
Table rows can only exist in [tables](#Tables).
|
|
||||||
|
|
||||||
<a id="Objects"></a>
|
|
||||||
|
|
||||||
# Objects
|
|
||||||
|
|
||||||
Objects can only be found in the following locations:
|
|
||||||
|
|
||||||
- [affiliated keywords](#Affiliated_keywords) defined in
|
|
||||||
`org-element-parsed-keywords`,
|
|
||||||
- [document properties](#Keywords),
|
|
||||||
- [headline](#Headlines_and_Sections) titles,
|
|
||||||
- [inlinetask](#Inlinetasks) titles,
|
|
||||||
- [item](#Plain_Lists_and_Items) tags,
|
|
||||||
- [paragraphs](#Paragraphs),
|
|
||||||
- [table cells](#Table_Cells),
|
|
||||||
- [table rows](#Table_Rows), which can only contain table cell objects,
|
|
||||||
- [verse blocks](#Blocks).
|
|
||||||
|
|
||||||
Most objects cannot contain objects. Those which can will be specified.
|
|
||||||
|
|
||||||
<a id="Entities_and_LaTeX_Fragments"></a>
|
|
||||||
|
|
||||||
## Entities and LaTeX Fragments
|
|
||||||
|
|
||||||
An entity follows the pattern:
|
|
||||||
|
|
||||||
\NAME POST
|
|
||||||
|
|
||||||
where NAME has a valid association in either `org-entities` or
|
|
||||||
`org-entities-user`.
|
|
||||||
|
|
||||||
POST is the end of line, `{}` string, or a non-alphabetical character. It isn't
|
|
||||||
separated from NAME by a whitespace character.
|
|
||||||
|
|
||||||
A LaTeX fragment can follow multiple patterns:
|
|
||||||
|
|
||||||
\NAME BRACKETS
|
|
||||||
\(CONTENTS\)
|
|
||||||
\[CONTENTS\]
|
|
||||||
$$CONTENTS$$
|
|
||||||
PRE$CHAR$POST
|
|
||||||
PRE$BORDER1 BODY BORDER2$POST
|
|
||||||
|
|
||||||
NAME contains alphabetical characters only and must not have an association in
|
|
||||||
either **org-entities** or **org-entities-user**.
|
|
||||||
|
|
||||||
BRACKETS is optional, and is not separated from NAME with white spaces. It may
|
|
||||||
contain any number of the following patterns:
|
|
||||||
|
|
||||||
[CONTENTS1]
|
|
||||||
{CONTENTS2}
|
|
||||||
|
|
||||||
where CONTENTS1 can contain any characters excepted `{` `}`, `[` `]` and newline
|
|
||||||
and CONTENTS2 can contain any character excepted `{`, `}` and newline.
|
|
||||||
|
|
||||||
CONTENTS can contain any character but cannot contain `\\)` in the second
|
|
||||||
template or `\\]` in the third one.
|
|
||||||
|
|
||||||
PRE is either the beginning of line or a character different from `$`.
|
|
||||||
|
|
||||||
CHAR is a non-whitespace character different from `.`, `,`, `?`, `;`, `'` or a
|
|
||||||
double quote.
|
|
||||||
|
|
||||||
POST is any punctuation (including parentheses and quotes) or space character,
|
|
||||||
or the end of line.
|
|
||||||
|
|
||||||
BORDER1 is a non-whitespace character different from `.`, `,`, `;` and `$`.
|
|
||||||
|
|
||||||
BODY can contain any character excepted `$`, and may not span over more than 3
|
|
||||||
lines.
|
|
||||||
|
|
||||||
BORDER2 is any non-whitespace character different from `,`, `.` and `$`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> It would introduce incompatibilities with previous Org versions, but support
|
|
||||||
> for `$...$` (and for symmetry, `$$...$$`) constructs ought to be removed.
|
|
||||||
>
|
|
||||||
> They are slow to parse, fragile, redundant and imply false positives. —
|
|
||||||
> ngz
|
|
||||||
|
|
||||||
<a id="Export_Snippets"></a>
|
|
||||||
|
|
||||||
## Export Snippets
|
|
||||||
|
|
||||||
Patter for export snippets is:
|
|
||||||
|
|
||||||
@@NAME:VALUE@@
|
|
||||||
|
|
||||||
NAME can contain any alpha-numeric character and hyphens.
|
|
||||||
|
|
||||||
VALUE can contain anything but `@@` string.
|
|
||||||
|
|
||||||
<a id="Footnote_References"></a>
|
|
||||||
|
|
||||||
## Footnote References
|
|
||||||
|
|
||||||
There are four patterns for footnote references:
|
|
||||||
|
|
||||||
[fn:LABEL]
|
|
||||||
[fn:LABEL:DEFINITION]
|
|
||||||
[fn::DEFINITION]
|
|
||||||
|
|
||||||
LABEL can contain any word constituent character, hyphens and underscores.
|
|
||||||
|
|
||||||
DEFINITION can contain any character. Though opening and closing square brackets
|
|
||||||
must be balanced in it. It can contain any object encountered in a paragraph,
|
|
||||||
even other footnote references.
|
|
||||||
|
|
||||||
If the reference follows the second pattern, it is called an **inline
|
|
||||||
footnote**. If it follows the third one, i.e. if LABEL is omitted, it is an
|
|
||||||
**anonymous footnote**.
|
|
||||||
|
|
||||||
<a id="Inline_Babel_Calls_and_Source_Blocks"></a>
|
|
||||||
|
|
||||||
## Inline Babel Calls and Source Blocks
|
|
||||||
|
|
||||||
Inline Babel calls follow any of the following patterns:
|
|
||||||
|
|
||||||
call_NAME(ARGUMENTS)
|
|
||||||
call_NAME[HEADER](ARGUMENTS)[HEADER]
|
|
||||||
|
|
||||||
NAME can contain any character besides `(`, `)` and `\n`.
|
|
||||||
|
|
||||||
HEADER can contain any character besides `]` and `\n`.
|
|
||||||
|
|
||||||
ARGUMENTS can contain any character besides `)` and `\n`.
|
|
||||||
|
|
||||||
Inline source blocks follow any of the following patterns:
|
|
||||||
|
|
||||||
src_LANG{BODY}
|
|
||||||
src_LANG[OPTIONS]{BODY}
|
|
||||||
|
|
||||||
LANG can contain any non-whitespace character.
|
|
||||||
|
|
||||||
OPTIONS and BODY can contain any character but `\n`.
|
|
||||||
|
|
||||||
<a id="Line_Breaks"></a>
|
|
||||||
|
|
||||||
## Line Breaks
|
|
||||||
|
|
||||||
A line break consists in `\\\SPACE` pattern at the end of an otherwise non-empty
|
|
||||||
line.
|
|
||||||
|
|
||||||
SPACE can contain any number of tabs and spaces, including 0.
|
|
||||||
|
|
||||||
<a id="Links"></a>
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
There are 4 major types of links:
|
|
||||||
|
|
||||||
PRE1 RADIO POST1 ("radio" link)
|
|
||||||
<PROTOCOL:PATH> ("angle" link)
|
|
||||||
PRE2 PROTOCOL:PATH2 POST2 ("plain" link)
|
|
||||||
[[PATH3]DESCRIPTION] ("regular" link)
|
|
||||||
|
|
||||||
PRE1 and POST1, when they exist, are non alphanumeric characters.
|
|
||||||
|
|
||||||
RADIO is a string matched by some [radio target](#Targets_and_Radio_Targets). It
|
|
||||||
may contain [entities](#Entities_and_LaTeX_Fragments), [latex
|
|
||||||
fragments](#Entities_and_LaTeX_Fragments),
|
|
||||||
[subscript](#Subscript_and_Superscript) and
|
|
||||||
[superscript](#Subscript_and_Superscript).
|
|
||||||
|
|
||||||
PROTOCOL is a string among `org-link-types`.
|
|
||||||
|
|
||||||
PATH can contain any character but `]`, `<`, `>` and `\n`.
|
|
||||||
|
|
||||||
PRE2 and POST2, when they exist, are non word constituent characters.
|
|
||||||
|
|
||||||
PATH2 can contain any non-whitespace character excepted `(`, `)`, `<` and `>`.
|
|
||||||
It must end with a word-constituent character, or any non-whitespace
|
|
||||||
non-punctuation character followed by `/`.
|
|
||||||
|
|
||||||
DESCRIPTION must be enclosed within square brackets. It can contain any
|
|
||||||
character but square brackets. It can contain any object found in a paragraph
|
|
||||||
excepted a [footnote reference](#Footnote_References), a [radio
|
|
||||||
target](#Targets_and_Radio_Targets) and a [line break](#Line_Breaks). It cannot
|
|
||||||
contain another link either, unless it is a plain or angular link.
|
|
||||||
|
|
||||||
DESCRIPTION is optional.
|
|
||||||
|
|
||||||
PATH3 is built according to the following patterns:
|
|
||||||
|
|
||||||
FILENAME ("file" type)
|
|
||||||
PROTOCOL:PATH4 ("PROTOCOL" type)
|
|
||||||
PROTOCOL://PATH4 ("PROTOCOL" type)
|
|
||||||
id:ID ("id" type)
|
|
||||||
#CUSTOM-ID ("custom-id" type)
|
|
||||||
(CODEREF) ("coderef" type)
|
|
||||||
FUZZY ("fuzzy" type)
|
|
||||||
|
|
||||||
FILENAME is a file name, either absolute or relative.
|
|
||||||
|
|
||||||
PATH4 can contain any character besides square brackets.
|
|
||||||
|
|
||||||
ID is constituted of hexadecimal numbers separated with hyphens.
|
|
||||||
|
|
||||||
PATH4, CUSTOM-ID, CODEREF and FUZZY can contain any character besides square
|
|
||||||
brackets.
|
|
||||||
|
|
||||||
<a id="Macros"></a>
|
|
||||||
|
|
||||||
## Macros
|
|
||||||
|
|
||||||
Macros follow the pattern:
|
|
||||||
|
|
||||||
{{{NAME(ARGUMENTS)}}}
|
|
||||||
|
|
||||||
NAME must start with a letter and can be followed by any number of alpha-numeric
|
|
||||||
characters, hyphens and underscores.
|
|
||||||
|
|
||||||
ARGUMENTS can contain anything but `}}}` string. Values within ARGUMENTS are
|
|
||||||
separated by commas. Non-separating commas have to be escaped with a backslash
|
|
||||||
character.
|
|
||||||
|
|
||||||
<a id="Targets_and_Radio_Targets"></a>
|
|
||||||
|
|
||||||
## Targets and Radio Targets
|
|
||||||
|
|
||||||
Radio targets follow the pattern:
|
|
||||||
|
|
||||||
<<<CONTENTS>>>
|
|
||||||
|
|
||||||
CONTENTS can be any character besides `<`, `>` and `\n`. It cannot start or end
|
|
||||||
with a whitespace character. As far as objects go, it can contain [text
|
|
||||||
markup](#Emphasis_Markers), [entities](#Entities_and_LaTeX_Fragments), [latex
|
|
||||||
fragments](#Entities_and_LaTeX_Fragments),
|
|
||||||
[subscript](#Subscript_and_Superscript) and
|
|
||||||
[superscript](#Subscript_and_Superscript) only.
|
|
||||||
|
|
||||||
Targets follow the pattern:
|
|
||||||
|
|
||||||
<<TARGET>>
|
|
||||||
|
|
||||||
TARGET can contain any character besides `<`, `>` and `\n`. It cannot start or
|
|
||||||
end with a whitespace character. It cannot contain any object.
|
|
||||||
|
|
||||||
<a id="Statistics_Cookies"></a>
|
|
||||||
|
|
||||||
## Statistics Cookies
|
|
||||||
|
|
||||||
Statistics cookies follow either pattern:
|
|
||||||
|
|
||||||
[PERCENT%]
|
|
||||||
[NUM1/NUM2]
|
|
||||||
|
|
||||||
PERCENT, NUM1 and NUM2 are numbers or the empty string.
|
|
||||||
|
|
||||||
<a id="Subscript_and_Superscript"></a>
|
|
||||||
|
|
||||||
## Subscript and Superscript
|
|
||||||
|
|
||||||
Pattern for subscript is:
|
|
||||||
|
|
||||||
CHAR_SCRIPT
|
|
||||||
|
|
||||||
Pattern for superscript is:
|
|
||||||
|
|
||||||
CHAR^SCRIPT
|
|
||||||
|
|
||||||
CHAR is any non-whitespace character.
|
|
||||||
|
|
||||||
SCRIPT can be `*` or an expression enclosed in parenthesis (respectively curly
|
|
||||||
brackets), possibly containing balanced parenthesis (respectively curly
|
|
||||||
brackets).
|
|
||||||
|
|
||||||
SCRIPT can also follow the pattern:
|
|
||||||
|
|
||||||
SIGN CHARS FINAL
|
|
||||||
|
|
||||||
SIGN is either a plus sign, a minus sign, or an empty string.
|
|
||||||
|
|
||||||
CHARS is any number of alpha-numeric characters, commas, backslashes and dots,
|
|
||||||
or an empty string.
|
|
||||||
|
|
||||||
FINAL is an alpha-numeric character.
|
|
||||||
|
|
||||||
There is no white space between SIGN, CHARS and FINAL.
|
|
||||||
|
|
||||||
<a id="Table_Cells"></a>
|
|
||||||
|
|
||||||
## Table Cells
|
|
||||||
|
|
||||||
Table cells follow the pattern:
|
|
||||||
|
|
||||||
CONTENTS SPACES|
|
|
||||||
|
|
||||||
CONTENTS can contain any character excepted a vertical bar.
|
|
||||||
|
|
||||||
SPACES contains any number of space characters, including zero. It can be used
|
|
||||||
to align properly the table.
|
|
||||||
|
|
||||||
The final bar may be replaced with a newline character for the last cell in row.
|
|
||||||
|
|
||||||
<a id="Timestamp"></a>
|
|
||||||
|
|
||||||
## Timestamps
|
|
||||||
|
|
||||||
There are seven possible patterns for timestamps:
|
|
||||||
|
|
||||||
<%%(SEXP)> (diary)
|
|
||||||
<DATE TIME REPEATER-OR-DELAY> (active)
|
|
||||||
[DATE TIME REPEATER-OR-DELAY] (inactive)
|
|
||||||
<DATE TIME REPEATER-OR-DELAY>--<DATE TIME REPEATER-OR-DELAY> (active range)
|
|
||||||
<DATE TIME-TIME REPEATER-OR-DELAY> (active range)
|
|
||||||
[DATE TIME REPEATER-OR-DELAY]--[DATE TIME REPEATER-OR-DELAY] (inactive range)
|
|
||||||
[DATE TIME-TIME REPEATER-OR-DELAY] (inactive range)
|
|
||||||
|
|
||||||
SEXP can contain any character excepted `>` and `\n`.
|
|
||||||
|
|
||||||
DATE follows the pattern:
|
|
||||||
|
|
||||||
YYYY-MM-DD DAYNAME
|
|
||||||
|
|
||||||
`Y`, `M` and `D` are digits. DAYNAME can contain any non whitespace-character
|
|
||||||
besides `+`, `-`, `]`, `>`, a digit or `\n`.
|
|
||||||
|
|
||||||
TIME follows the pattern `H:MM`. `H` can be one or two digit long and can start
|
|
||||||
with 0.
|
|
||||||
|
|
||||||
REPEATER-OR-DELAY follows the pattern:
|
|
||||||
|
|
||||||
MARK VALUE UNIT
|
|
||||||
|
|
||||||
MARK is `+` (cumulate type), `++` (catch-up type) or `.+` (restart type) for a
|
|
||||||
repeater, and `-` (all type) or `--` (first type) for warning delays.
|
|
||||||
|
|
||||||
VALUE is a number.
|
|
||||||
|
|
||||||
UNIT is a character among `h` (hour), `d` (day), `w` (week), `m` (month), `y`
|
|
||||||
(year).
|
|
||||||
|
|
||||||
MARK, VALUE and UNIT are not separated by whitespace characters.
|
|
||||||
|
|
||||||
There can be two REPEATER-OR-DELAY in the timestamp: one as a repeater and one
|
|
||||||
as a warning delay.
|
|
||||||
|
|
||||||
<a id="Emphasis_Markers"></a>
|
|
||||||
|
|
||||||
## Text Markup
|
|
||||||
|
|
||||||
Text markup follows the pattern:
|
|
||||||
|
|
||||||
PRE MARKER CONTENTS MARKER POST
|
|
||||||
|
|
||||||
PRE is a whitespace character, `(`, `{` `'` or a double quote. It can also be a
|
|
||||||
beginning of line.
|
|
||||||
|
|
||||||
MARKER is a character among `*` (bold), `=` (verbatim), `/` (italic), `+`
|
|
||||||
(strike-through), `_` (underline), `~` (code).
|
|
||||||
|
|
||||||
CONTENTS is a string following the pattern:
|
|
||||||
|
|
||||||
BORDER BODY BORDER
|
|
||||||
|
|
||||||
BORDER can be any non-whitespace character excepted `,`, `'` or a double quote.
|
|
||||||
|
|
||||||
BODY can contain contain any character but may not span over more than 3 lines.
|
|
||||||
|
|
||||||
BORDER and BODY are not separated by whitespaces.
|
|
||||||
|
|
||||||
CONTENTS can contain any object encountered in a paragraph when markup is
|
|
||||||
**bold**, **italic**, **strike-through** or **underline**.
|
|
||||||
|
|
||||||
POST is a whitespace character, `-`, `.`, `,`, `:`, `!`, `?`, `'`, `)`, `}` or a
|
|
||||||
double quote. It can also be an end of line.
|
|
||||||
|
|
||||||
PRE, MARKER, CONTENTS, MARKER and POST are not separated by whitespace
|
|
||||||
characters.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> All of this is wrong if `org-emphasis-regexp-components` or
|
|
||||||
> `org-emphasis-alist` are modified.
|
|
||||||
>
|
|
||||||
> This should really be simplified.
|
|
||||||
>
|
|
||||||
> Also, CONTENTS should be anything within code and verbatim emphasis, by
|
|
||||||
> definition. — ngz
|
|
||||||
|
|
||||||
# Footnotes
|
|
||||||
|
|
||||||
<sup><a id="fn.1" href="#fnr.1">1</a></sup> In particular, the parser requires
|
|
||||||
stars at column 0 to be quoted by a comma when they do not define a headline.
|
|
||||||
|
|
||||||
<sup><a id="fn.2" href="#fnr.2">2</a></sup> It also means that only headlines
|
|
||||||
and sections can be recognized just by looking at the beginning of the line.
|
|
||||||
Planning lines and property drawers can be recognized by looking at one or two
|
|
||||||
lines above.
|
|
||||||
|
|
||||||
As a consequence, using `org-element-at-point` or `org-element-context` will
|
|
||||||
move up to the parent headline, and parse top-down from there until context
|
|
||||||
around original location is found.
|
|
|
@ -50,7 +50,7 @@ pub use self::{
|
||||||
table::{Table, TableCell, TableRow},
|
table::{Table, TableCell, TableRow},
|
||||||
target::Target,
|
target::Target,
|
||||||
timestamp::{Datetime, Timestamp},
|
timestamp::{Datetime, Timestamp},
|
||||||
title::{PropertiesMap, Title},
|
title::Title,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Headline Title
|
//! Headline Title
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::{borrow::Cow, iter::FromIterator};
|
|
||||||
|
|
||||||
use memchr::memrchr2;
|
use memchr::memrchr2;
|
||||||
use nom::{
|
use nom::{
|
||||||
|
@ -43,11 +43,8 @@ pub struct Title<'a> {
|
||||||
#[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))]
|
#[cfg_attr(feature = "ser", serde(skip_serializing_if = "Option::is_none"))]
|
||||||
pub planning: Option<Box<Planning<'a>>>,
|
pub planning: Option<Box<Planning<'a>>>,
|
||||||
/// Property drawer associated to this headline
|
/// Property drawer associated to this headline
|
||||||
#[cfg_attr(
|
#[cfg_attr(feature = "ser", serde(skip_serializing_if = "HashMap::is_empty"))]
|
||||||
feature = "ser",
|
pub properties: HashMap<Cow<'a, str>, Cow<'a, str>>,
|
||||||
serde(skip_serializing_if = "PropertiesMap::is_empty")
|
|
||||||
)]
|
|
||||||
pub properties: PropertiesMap<'a>,
|
|
||||||
/// Numbers of blank lines between last title's line and next non-blank line
|
/// Numbers of blank lines between last title's line and next non-blank line
|
||||||
/// or buffer's end
|
/// or buffer's end
|
||||||
pub post_blank: usize,
|
pub post_blank: usize,
|
||||||
|
@ -102,7 +99,11 @@ impl Title<'_> {
|
||||||
keyword: self.keyword.map(Into::into).map(Cow::Owned),
|
keyword: self.keyword.map(Into::into).map(Cow::Owned),
|
||||||
raw: self.raw.into_owned().into(),
|
raw: self.raw.into_owned().into(),
|
||||||
planning: self.planning.map(|p| Box::new(p.into_owned())),
|
planning: self.planning.map(|p| Box::new(p.into_owned())),
|
||||||
properties: self.properties.into_owned(),
|
properties: self
|
||||||
|
.properties
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, v)| (k.into_owned().into(), v.into_owned().into()))
|
||||||
|
.collect(),
|
||||||
post_blank: self.post_blank,
|
post_blank: self.post_blank,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,66 +118,12 @@ impl Default for Title<'_> {
|
||||||
keyword: None,
|
keyword: None,
|
||||||
raw: Cow::Borrowed(""),
|
raw: Cow::Borrowed(""),
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Properties
|
|
||||||
#[derive(Default, Debug, Clone)]
|
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
|
||||||
#[cfg_attr(feature = "ser", derive(serde::Serialize))]
|
|
||||||
pub struct PropertiesMap<'a> {
|
|
||||||
pub pairs: Vec<(Cow<'a, str>, Cow<'a, str>)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> PropertiesMap<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
PropertiesMap { pairs: Vec::new() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.pairs.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &(Cow<'a, str>, Cow<'a, str>)> {
|
|
||||||
self.pairs.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut (Cow<'a, str>, Cow<'a, str>)> {
|
|
||||||
self.pairs.iter_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_iter(self) -> impl Iterator<Item = (Cow<'a, str>, Cow<'a, str>)> {
|
|
||||||
self.pairs.into_iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_hash_map(self) -> HashMap<Cow<'a, str>, Cow<'a, str>> {
|
|
||||||
self.pairs.into_iter().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "indexmap")]
|
|
||||||
pub fn into_index_map(self) -> indexmap::IndexMap<Cow<'a, str>, Cow<'a, str>> {
|
|
||||||
self.pairs.into_iter().collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_owned(self) -> PropertiesMap<'static> {
|
|
||||||
self.pairs
|
|
||||||
.into_iter()
|
|
||||||
.map(|(k, v)| (k.into_owned().into(), v.into_owned().into()))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromIterator<(Cow<'a, str>, Cow<'a, str>)> for PropertiesMap<'a> {
|
|
||||||
fn from_iter<T: IntoIterator<Item = (Cow<'a, str>, Cow<'a, str>)>>(iter: T) -> Self {
|
|
||||||
let mut map = PropertiesMap::new();
|
|
||||||
map.pairs.extend(iter);
|
|
||||||
map
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn white_spaces_or_eol(input: &str) -> IResult<&str, &str, ()> {
|
fn white_spaces_or_eol(input: &str) -> IResult<&str, &str, ()> {
|
||||||
alt((space1, line_ending))(input)
|
alt((space1, line_ending))(input)
|
||||||
}
|
}
|
||||||
|
@ -257,16 +204,16 @@ fn is_tag_line(input: &str) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_properties_drawer(input: &str) -> IResult<&str, PropertiesMap<'_>, ()> {
|
fn parse_properties_drawer(input: &str) -> IResult<&str, HashMap<Cow<'_, str>, Cow<'_, str>>, ()> {
|
||||||
let (input, (drawer, content)) = parse_drawer_without_blank(input.trim_start())?;
|
let (input, (drawer, content)) = parse_drawer_without_blank(input.trim_start())?;
|
||||||
if drawer.name != "PROPERTIES" {
|
if drawer.name != "PROPERTIES" {
|
||||||
return Err(Err::Error(make_error(input, ErrorKind::Tag)));
|
return Err(Err::Error(make_error(input, ErrorKind::Tag)));
|
||||||
}
|
}
|
||||||
let (_, map) = fold_many0(
|
let (_, map) = fold_many0(
|
||||||
parse_node_property,
|
parse_node_property,
|
||||||
PropertiesMap::new,
|
HashMap::new(),
|
||||||
|mut acc: PropertiesMap, (name, value)| {
|
|mut acc: HashMap<_, _>, (name, value)| {
|
||||||
acc.pairs.push((name.into(), value.into()));
|
acc.insert(name.into(), value.into());
|
||||||
acc
|
acc
|
||||||
},
|
},
|
||||||
)(content)?;
|
)(content)?;
|
||||||
|
@ -300,7 +247,7 @@ fn parse_title_() {
|
||||||
raw: "COMMENT Title".into(),
|
raw: "COMMENT Title".into(),
|
||||||
tags: vec!["tag".into(), "a2%".into()],
|
tags: vec!["tag".into(), "a2%".into()],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"COMMENT Title"
|
"COMMENT Title"
|
||||||
|
@ -319,7 +266,7 @@ fn parse_title_() {
|
||||||
raw: "ToDO [#A] COMMENT Title".into(),
|
raw: "ToDO [#A] COMMENT Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"ToDO [#A] COMMENT Title"
|
"ToDO [#A] COMMENT Title"
|
||||||
|
@ -338,7 +285,7 @@ fn parse_title_() {
|
||||||
raw: "T0DO [#A] COMMENT Title".into(),
|
raw: "T0DO [#A] COMMENT Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"T0DO [#A] COMMENT Title"
|
"T0DO [#A] COMMENT Title"
|
||||||
|
@ -357,7 +304,7 @@ fn parse_title_() {
|
||||||
raw: "[#1] COMMENT Title".into(),
|
raw: "[#1] COMMENT Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"[#1] COMMENT Title"
|
"[#1] COMMENT Title"
|
||||||
|
@ -376,7 +323,7 @@ fn parse_title_() {
|
||||||
raw: "[#a] COMMENT Title".into(),
|
raw: "[#a] COMMENT Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"[#a] COMMENT Title"
|
"[#a] COMMENT Title"
|
||||||
|
@ -397,7 +344,7 @@ fn parse_title_() {
|
||||||
raw: "[#B]::".into(),
|
raw: "[#B]::".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"[#B]::"
|
"[#B]::"
|
||||||
|
@ -417,7 +364,7 @@ fn parse_title_() {
|
||||||
raw: "Title :tag:a2%".into(),
|
raw: "Title :tag:a2%".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"Title :tag:a2%"
|
"Title :tag:a2%"
|
||||||
|
@ -436,7 +383,7 @@ fn parse_title_() {
|
||||||
raw: "Title tag:a2%:".into(),
|
raw: "Title tag:a2%:".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"Title tag:a2%:"
|
"Title tag:a2%:"
|
||||||
|
@ -462,7 +409,7 @@ fn parse_title_() {
|
||||||
raw: "DONE Title".into(),
|
raw: "DONE Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"DONE Title"
|
"DONE Title"
|
||||||
|
@ -487,7 +434,7 @@ fn parse_title_() {
|
||||||
raw: "Title".into(),
|
raw: "Title".into(),
|
||||||
tags: vec![],
|
tags: vec![],
|
||||||
planning: None,
|
planning: None,
|
||||||
properties: PropertiesMap::new(),
|
properties: HashMap::new(),
|
||||||
post_blank: 0,
|
post_blank: 0,
|
||||||
},
|
},
|
||||||
"Title"
|
"Title"
|
||||||
|
@ -504,48 +451,7 @@ fn parse_properties_drawer_() {
|
||||||
"",
|
"",
|
||||||
vec![("CUSTOM_ID".into(), "id".into())]
|
vec![("CUSTOM_ID".into(), "id".into())]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<PropertiesMap>()
|
.collect::<HashMap<_, _>>()
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[cfg(feature = "indexmap")]
|
|
||||||
fn preserve_properties_drawer_order() {
|
|
||||||
let mut vec = Vec::default();
|
|
||||||
// Use a large number of properties to reduce false pass rate, since HashMap
|
|
||||||
// is non-deterministic. There are roughly 10^18 possible derangements of this sequence.
|
|
||||||
for i in 0..20 {
|
|
||||||
// Avoid alphabetic or numeric order.
|
|
||||||
let j = (i + 7) % 20;
|
|
||||||
vec.push((
|
|
||||||
Cow::Owned(format!(
|
|
||||||
"{}{}",
|
|
||||||
if i % 3 == 0 {
|
|
||||||
"FOO"
|
|
||||||
} else if i % 3 == 1 {
|
|
||||||
"QUX"
|
|
||||||
} else {
|
|
||||||
"BAR"
|
|
||||||
},
|
|
||||||
j
|
|
||||||
)),
|
|
||||||
Cow::Owned(i.to_string()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut s = String::default();
|
|
||||||
|
|
||||||
for (k, v) in &vec {
|
|
||||||
s += &format!(" :{}: {}\n", k, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let drawer = format!(" :PROPERTIES:\n{}:END:\n", &s);
|
|
||||||
|
|
||||||
let map = parse_properties_drawer(&drawer).unwrap().1.into_index_map();
|
|
||||||
|
|
||||||
// indexmap should be in the same order as vector
|
|
||||||
for (left, right) in vec.iter().zip(map) {
|
|
||||||
assert_eq!(left, &right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -269,7 +269,7 @@ impl OrgHandler<Error> for DefaultOrgHandler {
|
||||||
}
|
}
|
||||||
if !title.properties.is_empty() {
|
if !title.properties.is_empty() {
|
||||||
writeln!(&mut w, ":PROPERTIES:")?;
|
writeln!(&mut w, ":PROPERTIES:")?;
|
||||||
for (key, value) in title.properties.iter() {
|
for (key, value) in &title.properties {
|
||||||
writeln!(&mut w, ":{}: {}", key, value)?;
|
writeln!(&mut w, ":{}: {}", key, value)?;
|
||||||
}
|
}
|
||||||
writeln!(&mut w, ":END:")?;
|
writeln!(&mut w, ":END:")?;
|
||||||
|
|
|
@ -178,7 +178,6 @@
|
||||||
//! use serde_json::{json, to_string};
|
//! use serde_json::{json, to_string};
|
||||||
//!
|
//!
|
||||||
//! let org = Org::parse("I 'm *bold*.");
|
//! let org = Org::parse("I 'm *bold*.");
|
||||||
//! #[cfg(feature = "ser")]
|
|
||||||
//! println!("{}", to_string(&org).unwrap());
|
//! println!("{}", to_string(&org).unwrap());
|
||||||
//!
|
//!
|
||||||
//! // {
|
//! // {
|
||||||
|
@ -240,6 +239,3 @@ pub use elements::Element;
|
||||||
pub use headline::{Document, Headline};
|
pub use headline::{Document, Headline};
|
||||||
pub use org::{Event, Org};
|
pub use org::{Event, Org};
|
||||||
pub use validate::ValidationError;
|
pub use validate::ValidationError;
|
||||||
|
|
||||||
#[cfg(feature = "wasm")]
|
|
||||||
mod wasm;
|
|
||||||
|
|
|
@ -83,7 +83,11 @@ impl Org<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for child in children {
|
for child in children {
|
||||||
expect_element!(child, "Headline", Element::Headline { .. });
|
expect_element!(
|
||||||
|
child,
|
||||||
|
"Headline",
|
||||||
|
Element::Headline { .. }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Element::Headline { .. } => {
|
Element::Headline { .. } => {
|
||||||
|
@ -103,7 +107,11 @@ impl Org<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for child in children {
|
for child in children {
|
||||||
expect_element!(child, "Headline", Element::Headline { .. });
|
expect_element!(
|
||||||
|
child,
|
||||||
|
"Headline",
|
||||||
|
Element::Headline { .. }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Element::Title(title) => {
|
Element::Title(title) => {
|
||||||
|
|
189
src/wasm/mod.rs
189
src/wasm/mod.rs
|
@ -1,189 +0,0 @@
|
||||||
#[global_allocator]
|
|
||||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
|
||||||
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde_wasm_bindgen::Serializer;
|
|
||||||
use wasm_bindgen::prelude::*;
|
|
||||||
|
|
||||||
use crate::{Element, Event};
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub struct Org(crate::Org<'static>);
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
impl Org {
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn parse(input: String) -> Self {
|
|
||||||
Org(crate::Org::parse_string(input))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = toJson)]
|
|
||||||
pub fn to_json(&self) -> JsValue {
|
|
||||||
to_value(&self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
extern "C" {
|
|
||||||
#[wasm_bindgen(skip_typescript)]
|
|
||||||
pub type Handler;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn text(this: &Handler, text: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn code(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn cookie(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn rule(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = exampleBlock)]
|
|
||||||
pub fn example_block(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = exportBlock)]
|
|
||||||
pub fn export_block(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = sourceBlock)]
|
|
||||||
pub fn source_block(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = inlineSrc)]
|
|
||||||
pub fn inline_src(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn link(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn snippet(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn timestamp(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn verbatim(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn fixedWidth(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method)]
|
|
||||||
pub fn keyword(this: &Handler, item: JsValue);
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, js_name = listStart)]
|
|
||||||
pub fn list_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = listEnd)]
|
|
||||||
pub fn list_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableStart)]
|
|
||||||
pub fn table_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableEnd)]
|
|
||||||
pub fn table_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableRowStart)]
|
|
||||||
pub fn table_row_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableRowEnd)]
|
|
||||||
pub fn table_row_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableCellStart)]
|
|
||||||
pub fn table_cell_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = tableCellEnd)]
|
|
||||||
pub fn table_cell_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = titleStart)]
|
|
||||||
pub fn title_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = titleEnd)]
|
|
||||||
pub fn title_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = boldStart)]
|
|
||||||
pub fn bold_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = boldEnd)]
|
|
||||||
pub fn bold_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = centerBlockStart)]
|
|
||||||
pub fn center_block_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = centerBlockEnd)]
|
|
||||||
pub fn center_block_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = documentStart)]
|
|
||||||
pub fn document_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = documentEnd)]
|
|
||||||
pub fn document_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = italicStart)]
|
|
||||||
pub fn italic_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = italicEnd)]
|
|
||||||
pub fn italic_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = listItemStart)]
|
|
||||||
pub fn list_item_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = listItemEnd)]
|
|
||||||
pub fn list_item_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = paragraphStart)]
|
|
||||||
pub fn paragraph_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = paragraphEnd)]
|
|
||||||
pub fn paragraph_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = quoteBlockStart)]
|
|
||||||
pub fn quote_block_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = quoteBlockEnd)]
|
|
||||||
pub fn quote_block_end(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = sectionStart)]
|
|
||||||
pub fn section_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = sectionEnd)]
|
|
||||||
pub fn section_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = strikeStart)]
|
|
||||||
pub fn strike_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = strikeEnd)]
|
|
||||||
pub fn strike_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = underlineStart)]
|
|
||||||
pub fn underline_start(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = underlineEnd)]
|
|
||||||
pub fn underline_end(this: &Handler);
|
|
||||||
#[wasm_bindgen(method, js_name = verseBlockStart)]
|
|
||||||
pub fn verse_block_start(this: &Handler, item: JsValue);
|
|
||||||
#[wasm_bindgen(method, js_name = verseBlockEnd)]
|
|
||||||
pub fn verse_block_end(this: &Handler, item: JsValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn handle(org: &Org, handler: Handler) {
|
|
||||||
for event in org.0.iter() {
|
|
||||||
use Element::*;
|
|
||||||
|
|
||||||
match event {
|
|
||||||
Event::Start(Text { value }) => handler.text(JsValue::from_str(value)),
|
|
||||||
Event::Start(ExampleBlock(block)) => handler.example_block(to_value(block)),
|
|
||||||
Event::Start(ExportBlock(block)) => handler.export_block(to_value(block)),
|
|
||||||
Event::Start(SourceBlock(block)) => handler.source_block(to_value(block)),
|
|
||||||
Event::Start(InlineSrc(src)) => handler.inline_src(to_value(src)),
|
|
||||||
Event::Start(Code { value }) => handler.code(JsValue::from_str(value)),
|
|
||||||
Event::Start(Link(link)) => handler.link(to_value(link)),
|
|
||||||
Event::Start(Snippet(snippet)) => handler.snippet(to_value(snippet)),
|
|
||||||
Event::Start(Timestamp(timestamp)) => handler.timestamp(to_value(timestamp)),
|
|
||||||
Event::Start(Verbatim { value }) => handler.verbatim(JsValue::from_str(value)),
|
|
||||||
Event::Start(FixedWidth(fixed_width)) => handler.fixedWidth(to_value(fixed_width)),
|
|
||||||
Event::Start(Rule(_)) => handler.rule(),
|
|
||||||
Event::Start(Cookie(cookie)) => handler.cookie(to_value(cookie)),
|
|
||||||
Event::Start(Keyword(keyword)) => handler.keyword(to_value(keyword)),
|
|
||||||
|
|
||||||
Event::Start(Table(table)) => handler.table_start(to_value(table)),
|
|
||||||
Event::End(Table(table)) => handler.table_start(to_value(table)),
|
|
||||||
Event::Start(TableRow(row)) => handler.table_row_start(to_value(row)),
|
|
||||||
Event::End(TableRow(row)) => handler.table_row_start(to_value(row)),
|
|
||||||
Event::Start(TableCell(cell)) => handler.table_cell_start(to_value(cell)),
|
|
||||||
Event::End(TableCell(cell)) => handler.table_cell_start(to_value(cell)),
|
|
||||||
Event::Start(Title(title)) => handler.title_start(to_value(title)),
|
|
||||||
Event::End(Title(title)) => handler.title_end(to_value(title)),
|
|
||||||
Event::Start(QuoteBlock(block)) => handler.quote_block_start(to_value(block)),
|
|
||||||
Event::End(QuoteBlock(block)) => handler.quote_block_end(to_value(block)),
|
|
||||||
Event::Start(CenterBlock(block)) => handler.center_block_start(to_value(block)),
|
|
||||||
Event::End(CenterBlock(block)) => handler.center_block_end(to_value(block)),
|
|
||||||
Event::Start(VerseBlock(block)) => handler.verse_block_start(to_value(block)),
|
|
||||||
Event::End(VerseBlock(block)) => handler.verse_block_end(to_value(block)),
|
|
||||||
Event::Start(Bold) => handler.bold_start(),
|
|
||||||
Event::End(Bold) => handler.bold_end(),
|
|
||||||
Event::Start(Document { .. }) => handler.document_start(),
|
|
||||||
Event::End(Document { .. }) => handler.document_end(),
|
|
||||||
Event::Start(List(list)) => handler.list_start(to_value(list)),
|
|
||||||
Event::End(List(list)) => handler.list_end(to_value(list)),
|
|
||||||
Event::Start(Italic) => handler.italic_start(),
|
|
||||||
Event::End(Italic) => handler.italic_end(),
|
|
||||||
Event::Start(ListItem(_)) => handler.list_item_start(),
|
|
||||||
Event::End(ListItem(_)) => handler.list_item_end(),
|
|
||||||
Event::Start(Paragraph { .. }) => handler.paragraph_start(),
|
|
||||||
Event::End(Paragraph { .. }) => handler.paragraph_end(),
|
|
||||||
Event::Start(Section) => handler.section_start(),
|
|
||||||
Event::End(Section) => handler.section_end(),
|
|
||||||
Event::Start(Strike) => handler.strike_start(),
|
|
||||||
Event::End(Strike) => handler.strike_end(),
|
|
||||||
Event::Start(Underline) => handler.underline_start(),
|
|
||||||
Event::End(Underline) => handler.underline_end(),
|
|
||||||
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_value<T: Serialize + ?Sized>(value: &T) -> JsValue {
|
|
||||||
value
|
|
||||||
.serialize(&Serializer::new().serialize_maps_as_objects(true))
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
6
wasm/.gitignore
vendored
6
wasm/.gitignore
vendored
|
@ -1,6 +0,0 @@
|
||||||
/lib
|
|
||||||
/node_modules
|
|
||||||
/out-tsc
|
|
||||||
/package
|
|
||||||
/pkg
|
|
||||||
*.tgz
|
|
|
@ -1,41 +0,0 @@
|
||||||
# orgize
|
|
||||||
|
|
||||||
![npm](https://img.shields.io/npm/v/orgize)
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
Install the package:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install orgize
|
|
||||||
yarn add orgize
|
|
||||||
```
|
|
||||||
|
|
||||||
Load the wasm module and init:
|
|
||||||
|
|
||||||
### Browser
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { init, renderHtml } from "orgize";
|
|
||||||
|
|
||||||
init().then(() => {
|
|
||||||
console.log(renderHtml("* Hello, /world/!"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Node.js
|
|
||||||
|
|
||||||
```js
|
|
||||||
const { init, renderHtml } = require("orgize");
|
|
||||||
const { readFile } = require("fs/promises");
|
|
||||||
|
|
||||||
readFile(require.resolve("orgize/lib/orgize_bg.wasm"))
|
|
||||||
.then((bytes) => init(new WebAssembly.Module(bytes)))
|
|
||||||
.then(() => {
|
|
||||||
console.log(renderHtml("* Hello, /world/!"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
|
@ -1,71 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Orgize wasm demo</title>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<script defer src="https://unpkg.com/alpinejs@3/dist/cdn.min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify-html.js"></script>
|
|
||||||
|
|
||||||
<script src="./orgize.umd.js"></script>
|
|
||||||
<style>
|
|
||||||
h3 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body > * {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body
|
|
||||||
x-data="{ loaded: false, org: '* Hello, /world/!', type: 'json' }"
|
|
||||||
x-init="orgize.init('./orgize_bg.wasm').then(() => loaded = true)"
|
|
||||||
>
|
|
||||||
<h2>Orgize wasm demo</h2>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<a href="https://github.com/PoiScript/orgize">GitHub</a>
|
|
||||||
<a href="https://www.npmjs.com/package/orgize">NPM</a>
|
|
||||||
<a href="https://crates.io/crates/orgize">crates.io</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>Input:</div>
|
|
||||||
|
|
||||||
<textarea
|
|
||||||
x-model="org"
|
|
||||||
style="width: 100%; height: 100px; margin-bottom: 16px"
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
<div>Type:</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<button @click="type = 'json'">JSON</button>
|
|
||||||
<button @click="type = 'html'">HTML</button>
|
|
||||||
<button @click="type = 'html-rendered'">HTML (Rendered)</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>Output:</div>
|
|
||||||
|
|
||||||
<noscript>
|
|
||||||
<p style="color: red">JavaScript is required.</p>
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
<pre
|
|
||||||
x-show="type === 'json'"
|
|
||||||
x-transition
|
|
||||||
x-text="loaded ? JSON.stringify(orgize.Org.parse(org).toJson(), null, 2) : 'Loading...'"
|
|
||||||
></pre>
|
|
||||||
<pre
|
|
||||||
x-show="type === 'html'"
|
|
||||||
x-transition
|
|
||||||
x-text="loaded ? html_beautify(orgize.renderHtml(org), { indent_size: 2 }) : 'Loading...'"
|
|
||||||
></pre>
|
|
||||||
<div
|
|
||||||
x-show="type === 'html-rendered'"
|
|
||||||
x-transition
|
|
||||||
x-html="loaded ? orgize.renderHtml(org) : 'Loading...'"
|
|
||||||
></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"name": "orgize",
|
|
||||||
"version": "0.0.3",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "PoiScript <poiscript@gmail.com>",
|
|
||||||
"main": "lib/orgize.umd.js",
|
|
||||||
"module": "lib/orgize.es.js",
|
|
||||||
"typings": "lib/orgize.d.ts",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/PoiScript/orgize"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"prebuild": "rm -rf out-tsc/ lib/",
|
|
||||||
"build": "tsc && rollup -c rollup.js && cp pkg/orgize_bg.wasm lib/"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"rollup": "^2.56.3",
|
|
||||||
"rollup-plugin-copy": "^3.4.0",
|
|
||||||
"rollup-plugin-dts": "^4.0.0",
|
|
||||||
"typescript": "^4.4.2"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"lib",
|
|
||||||
"README.md"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
import dts from "rollup-plugin-dts";
|
|
||||||
import copy from "rollup-plugin-copy";
|
|
||||||
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
input: "./out-tsc/index.d.ts",
|
|
||||||
output: {
|
|
||||||
file: "./lib/orgize.d.ts",
|
|
||||||
},
|
|
||||||
plugins: [dts()],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "./out-tsc/index.js",
|
|
||||||
output: [
|
|
||||||
{
|
|
||||||
file: "./lib/orgize.es.js",
|
|
||||||
format: "es",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "orgize",
|
|
||||||
file: "./lib/orgize.umd.js",
|
|
||||||
format: "umd",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
copy({
|
|
||||||
targets: [{ src: "index.html", dest: "lib" }],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
|
@ -1,102 +0,0 @@
|
||||||
export class Handler {
|
|
||||||
text(_text: string) {}
|
|
||||||
code(_item: string) {}
|
|
||||||
cookie(_item: Cookie) {}
|
|
||||||
rule() {}
|
|
||||||
exampleBlock(_item: Block) {}
|
|
||||||
exportBlock(_item: Block) {}
|
|
||||||
sourceBlock(_item: SourceBlock) {}
|
|
||||||
inlineSrc(_item: InlineSrc) {}
|
|
||||||
link(_item: Link) {}
|
|
||||||
snippet(_item: Snippet) {}
|
|
||||||
timestamp(_item: any) {}
|
|
||||||
verbatim(_item: string) {}
|
|
||||||
fixedWidth(_item: FixedWidth) {}
|
|
||||||
listStart(_item: List) {}
|
|
||||||
listEnd(_item: List) {}
|
|
||||||
tableStart(_item: any) {}
|
|
||||||
tableEnd(_item: any) {}
|
|
||||||
tableRowStart(_item: any) {}
|
|
||||||
tableRowEnd(_item: any) {}
|
|
||||||
tableCellStart(_item: any) {}
|
|
||||||
tableCellEnd(_item: any) {}
|
|
||||||
titleStart(_item: Title) {}
|
|
||||||
titleEnd(_item: Title) {}
|
|
||||||
boldStart() {}
|
|
||||||
boldEnd() {}
|
|
||||||
centerBlockStart(_item: any) {}
|
|
||||||
centerBlockEnd(_item: any) {}
|
|
||||||
documentStart() {}
|
|
||||||
documentEnd() {}
|
|
||||||
italicStart() {}
|
|
||||||
italicEnd() {}
|
|
||||||
listItemStart() {}
|
|
||||||
listItemEnd() {}
|
|
||||||
paragraphStart() {}
|
|
||||||
paragraphEnd() {}
|
|
||||||
quoteBlockStart(_item: any) {}
|
|
||||||
quoteBlockEnd(_item: any) {}
|
|
||||||
sectionStart() {}
|
|
||||||
sectionEnd() {}
|
|
||||||
strikeStart() {}
|
|
||||||
strikeEnd() {}
|
|
||||||
underlineStart() {}
|
|
||||||
underlineEnd() {}
|
|
||||||
verseBlockStart(_item: any) {}
|
|
||||||
verseBlockEnd(_item: any) {}
|
|
||||||
keyword(_item: Keyword) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Title = {
|
|
||||||
level: number;
|
|
||||||
priority?: string;
|
|
||||||
tags?: string[];
|
|
||||||
keyword?: string;
|
|
||||||
raw: string;
|
|
||||||
properties?: { [key: string]: string };
|
|
||||||
post_blank: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type List = {
|
|
||||||
ordered: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Block = {
|
|
||||||
contents: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type InlineSrc = {
|
|
||||||
lang: string;
|
|
||||||
body: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Link = {
|
|
||||||
path: string;
|
|
||||||
desc?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FixedWidth = {
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Cookie = {
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SourceBlock = {
|
|
||||||
contents: string;
|
|
||||||
language: string;
|
|
||||||
arguments: string;
|
|
||||||
post_blank: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Keyword = {
|
|
||||||
key: string;
|
|
||||||
optional?: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Snippet = {
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
160
wasm/src/html.ts
160
wasm/src/html.ts
|
@ -1,160 +0,0 @@
|
||||||
import {
|
|
||||||
Block,
|
|
||||||
Cookie,
|
|
||||||
FixedWidth,
|
|
||||||
Handler,
|
|
||||||
InlineSrc,
|
|
||||||
Link,
|
|
||||||
List,
|
|
||||||
Snippet,
|
|
||||||
Title,
|
|
||||||
} from "./handler";
|
|
||||||
|
|
||||||
const tags: { [tag: string]: string } = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': """,
|
|
||||||
"'": "'",
|
|
||||||
};
|
|
||||||
|
|
||||||
const replaceTags = (tag: string): string => tags[tag];
|
|
||||||
|
|
||||||
export const escapeHtml = (str: string): string =>
|
|
||||||
str.replace(/[&<>"']/g, replaceTags);
|
|
||||||
|
|
||||||
export class HtmlHandler extends Handler {
|
|
||||||
result: string;
|
|
||||||
|
|
||||||
constructor(result: string = "") {
|
|
||||||
super();
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static escape(): string {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
quoteBlockStart() {
|
|
||||||
this.result += "<blockquote>";
|
|
||||||
}
|
|
||||||
quoteBlockEnd() {
|
|
||||||
this.result += "</blockquote>";
|
|
||||||
}
|
|
||||||
centerBlockStart() {
|
|
||||||
this.result += '<div class="center">';
|
|
||||||
}
|
|
||||||
centerBlockEnd() {
|
|
||||||
this.result += "</div>";
|
|
||||||
}
|
|
||||||
verseBlockStart() {
|
|
||||||
this.result += '<p class="verse">';
|
|
||||||
}
|
|
||||||
verseBlockEnd() {
|
|
||||||
this.result += "</p>";
|
|
||||||
}
|
|
||||||
boldStart() {
|
|
||||||
this.result += "<b>";
|
|
||||||
}
|
|
||||||
boldEnd() {
|
|
||||||
this.result += "</b>";
|
|
||||||
}
|
|
||||||
documentStart() {
|
|
||||||
this.result += "<main>";
|
|
||||||
}
|
|
||||||
documentEnd() {
|
|
||||||
this.result += "</main>";
|
|
||||||
}
|
|
||||||
|
|
||||||
listStart(list: List) {
|
|
||||||
this.result += `<${list.ordered ? "o" : "u"}l>`;
|
|
||||||
}
|
|
||||||
listEnd(list: List) {
|
|
||||||
this.result += `</${list.ordered ? "o" : "u"}l>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
italicStart() {
|
|
||||||
this.result += "<i>";
|
|
||||||
}
|
|
||||||
italicEnd() {
|
|
||||||
this.result += "</i>";
|
|
||||||
}
|
|
||||||
listItemStart() {
|
|
||||||
this.result += "<li>";
|
|
||||||
}
|
|
||||||
listItemEnd() {
|
|
||||||
this.result += "</li>";
|
|
||||||
}
|
|
||||||
paragraphStart() {
|
|
||||||
this.result += "<p>";
|
|
||||||
}
|
|
||||||
paragraphEnd() {
|
|
||||||
this.result += "</p>";
|
|
||||||
}
|
|
||||||
sectionStart() {
|
|
||||||
this.result += "<section>";
|
|
||||||
}
|
|
||||||
sectionEnd() {
|
|
||||||
this.result += "</section>";
|
|
||||||
}
|
|
||||||
strikeStart() {
|
|
||||||
this.result += "<s>";
|
|
||||||
}
|
|
||||||
strikeEnd() {
|
|
||||||
this.result += "</s>";
|
|
||||||
}
|
|
||||||
underlineStart() {
|
|
||||||
this.result += "<u>";
|
|
||||||
}
|
|
||||||
underlineEnd() {
|
|
||||||
this.result += "</u>";
|
|
||||||
}
|
|
||||||
|
|
||||||
exampleBlock(block: Block) {
|
|
||||||
this.result += `<pre class="example">${escapeHtml(block.contents)}</pre>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceBlock(block: Block) {
|
|
||||||
this.result += `<pre class="example">${escapeHtml(block.contents)}</pre>`;
|
|
||||||
}
|
|
||||||
inlineSrc(src: InlineSrc) {
|
|
||||||
this.result += `<code class="src src-${src.lang}">${escapeHtml(
|
|
||||||
src.body
|
|
||||||
)}</code>`;
|
|
||||||
}
|
|
||||||
code(value: string) {
|
|
||||||
this.result += `<code>${escapeHtml(value)}</code>`;
|
|
||||||
}
|
|
||||||
link(link: Link) {
|
|
||||||
this.result += `<a href="${link.path}">${escapeHtml(
|
|
||||||
link.desc || link.path
|
|
||||||
)}</a>`;
|
|
||||||
}
|
|
||||||
snippet(snippet: Snippet) {
|
|
||||||
if (snippet.name.toLowerCase() === "html") {
|
|
||||||
this.result += snippet.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text(value: string) {
|
|
||||||
this.result += escapeHtml(value);
|
|
||||||
}
|
|
||||||
verbatim(value: string) {
|
|
||||||
this.result += `<code>${escapeHtml(value)}</code>`;
|
|
||||||
}
|
|
||||||
fixedWidth(item: FixedWidth) {
|
|
||||||
this.result += `<pre class="example">${escapeHtml(item.value)}</pre>`;
|
|
||||||
}
|
|
||||||
rule() {
|
|
||||||
this.result += "<hr>";
|
|
||||||
}
|
|
||||||
cookie(cookie: Cookie) {
|
|
||||||
this.result += `<code>${escapeHtml(cookie.value)}</code>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
titleStart(title: Title) {
|
|
||||||
this.result += `<h${Math.min(title.level, 6)}>`;
|
|
||||||
}
|
|
||||||
titleEnd(title: Title) {
|
|
||||||
this.result += `</h${Math.min(title.level, 6)}>`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
import init, {
|
|
||||||
handle as internalHandle,
|
|
||||||
InitInput,
|
|
||||||
InitOutput,
|
|
||||||
Org,
|
|
||||||
} from "../pkg/orgize";
|
|
||||||
import { Handler } from "./handler";
|
|
||||||
import { HtmlHandler } from "./html";
|
|
||||||
import { CollectKeywords } from "./keyword";
|
|
||||||
|
|
||||||
export const handle = (org: Org | string, handler: Handler) => {
|
|
||||||
if (typeof org === "string") {
|
|
||||||
org = Org.parse(org);
|
|
||||||
}
|
|
||||||
internalHandle(org, handler);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const renderHtml = (
|
|
||||||
org: Org | string,
|
|
||||||
handler: HtmlHandler = new HtmlHandler()
|
|
||||||
): string => {
|
|
||||||
handle(org, handler);
|
|
||||||
return handler.result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const keywords = (org: Org | string): { [key: string]: string[] } => {
|
|
||||||
const handler = new CollectKeywords();
|
|
||||||
handle(org, handler);
|
|
||||||
return handler.keywords;
|
|
||||||
};
|
|
||||||
|
|
||||||
export * from "./handler";
|
|
||||||
export * from "./html";
|
|
||||||
export { Org, init, InitInput, InitOutput };
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { Handler, Keyword } from "./handler";
|
|
||||||
|
|
||||||
export class CollectKeywords extends Handler {
|
|
||||||
keywords: { [key: string]: string[] } = {};
|
|
||||||
|
|
||||||
keyword(keyword: Keyword) {
|
|
||||||
this.keywords[keyword.key] = this.keywords[keyword.key] || [];
|
|
||||||
this.keywords[keyword.key].push(keyword.value);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
const { readFile } = require("fs/promises");
|
|
||||||
const { resolve } = require("path");
|
|
||||||
const { strictEqual } = require("assert");
|
|
||||||
|
|
||||||
const { init, renderHtml } = require("../lib/orgize.umd");
|
|
||||||
|
|
||||||
const assert = (org, html) => strictEqual(renderHtml(org), html);
|
|
||||||
|
|
||||||
readFile(resolve(__dirname, "../lib/orgize_bg.wasm"))
|
|
||||||
.then((bytes) => new WebAssembly.Module(bytes))
|
|
||||||
.then((module) => init(module))
|
|
||||||
.then(() => {
|
|
||||||
assert(
|
|
||||||
"*bold*, /italic/,\n_underlined_, =verbatim= and ~code~",
|
|
||||||
"<main><section><p><b>bold</b>, <i>italic</i>,\n<u>underlined</u>, " +
|
|
||||||
"<code>verbatim</code> and <code>code</code></p></section></main>"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
"Visit[[http://example.com][link1]]or[[http://example.com][link1]].",
|
|
||||||
`<main><section><p>Visit<a href="http://example.com">link1</a>or<a href="http://example.com">link1</a>.</p></section></main>`
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
`
|
|
||||||
* title 1
|
|
||||||
section 1
|
|
||||||
** title 2
|
|
||||||
section 2
|
|
||||||
* title 3
|
|
||||||
section 3
|
|
||||||
* title 4
|
|
||||||
section 4
|
|
||||||
`,
|
|
||||||
"<main><h1>title 1</h1><section><p>section 1</p></section>" +
|
|
||||||
"<h2>title 2</h2><section><p>section 2</p></section>" +
|
|
||||||
"<h1>title 3</h1><section><p>section 3</p></section>" +
|
|
||||||
"<h1>title 4</h1><section><p>section 4</p></section></main>"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
`
|
|
||||||
+ 1
|
|
||||||
|
|
||||||
+ 2
|
|
||||||
|
|
||||||
- 3
|
|
||||||
|
|
||||||
- 4
|
|
||||||
|
|
||||||
+ 5
|
|
||||||
`,
|
|
||||||
"<main><section><ul>" +
|
|
||||||
"<li><p>1</p></li>" +
|
|
||||||
"<li><p>2</p><ul><li><p>3</p></li><li><p>4</p></li></ul></li>" +
|
|
||||||
"<li><p>5</p></li>" +
|
|
||||||
"</ul></section></main>"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
"@@html:<del>@@delete this@@html:</del>@@",
|
|
||||||
"<main><section><p><del>delete this</del></p></section></main>"
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(
|
|
||||||
`
|
|
||||||
* title
|
|
||||||
|
|
||||||
paragraph 1
|
|
||||||
|
|
||||||
paragraph 2
|
|
||||||
|
|
||||||
paragraph 3
|
|
||||||
|
|
||||||
paragraph 4
|
|
||||||
`,
|
|
||||||
"<main><h1>title</h1><section>" +
|
|
||||||
"<p>paragraph 1</p><p>paragraph 2</p>" +
|
|
||||||
"<p>paragraph 3</p><p>paragraph 4</p>" +
|
|
||||||
"</section></main>"
|
|
||||||
);
|
|
||||||
});
|
|
|
@ -1,17 +0,0 @@
|
||||||
const { readFile } = require("fs/promises");
|
|
||||||
const { resolve } = require("path");
|
|
||||||
const { deepStrictEqual } = require("assert");
|
|
||||||
|
|
||||||
const { init, keywords } = require("../lib/orgize.umd");
|
|
||||||
|
|
||||||
const assert = (org, kw) => deepStrictEqual(keywords(org), kw);
|
|
||||||
|
|
||||||
readFile(resolve(__dirname, "../lib/orgize_bg.wasm"))
|
|
||||||
.then((bytes) => new WebAssembly.Module(bytes))
|
|
||||||
.then((module) => init(module))
|
|
||||||
.then(() => {
|
|
||||||
assert("#+TITLE: orgize test cases\n#+FOO: bar", {
|
|
||||||
TITLE: ["orgize test cases"],
|
|
||||||
FOO: ["bar"],
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ESNext",
|
|
||||||
"module": "ESNext",
|
|
||||||
"lib": ["ESNext", "WebWorker"],
|
|
||||||
"strict": true,
|
|
||||||
"outDir": "out-tsc",
|
|
||||||
"rootDir": "./src",
|
|
||||||
"declaration": true
|
|
||||||
},
|
|
||||||
"include": ["./src"]
|
|
||||||
}
|
|
416
wasm/yarn.lock
416
wasm/yarn.lock
|
@ -1,416 +0,0 @@
|
||||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
||||||
# yarn lockfile v1
|
|
||||||
|
|
||||||
|
|
||||||
"@babel/code-frame@^7.14.5":
|
|
||||||
version "7.14.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
|
|
||||||
integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
|
|
||||||
dependencies:
|
|
||||||
"@babel/highlight" "^7.14.5"
|
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@^7.14.5":
|
|
||||||
version "7.14.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
|
|
||||||
integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
|
|
||||||
|
|
||||||
"@babel/highlight@^7.14.5":
|
|
||||||
version "7.14.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
|
|
||||||
integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
|
|
||||||
dependencies:
|
|
||||||
"@babel/helper-validator-identifier" "^7.14.5"
|
|
||||||
chalk "^2.0.0"
|
|
||||||
js-tokens "^4.0.0"
|
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
|
||||||
version "2.1.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
|
||||||
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
|
|
||||||
dependencies:
|
|
||||||
"@nodelib/fs.stat" "2.0.5"
|
|
||||||
run-parallel "^1.1.9"
|
|
||||||
|
|
||||||
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
|
||||||
version "2.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
|
|
||||||
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
|
||||||
|
|
||||||
"@nodelib/fs.walk@^1.2.3":
|
|
||||||
version "1.2.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
|
|
||||||
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
|
|
||||||
dependencies:
|
|
||||||
"@nodelib/fs.scandir" "2.1.5"
|
|
||||||
fastq "^1.6.0"
|
|
||||||
|
|
||||||
"@types/fs-extra@^8.0.1":
|
|
||||||
version "8.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.2.tgz#7125cc2e4bdd9bd2fc83005ffdb1d0ba00cca61f"
|
|
||||||
integrity sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/glob@^7.1.1":
|
|
||||||
version "7.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
|
||||||
integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
|
|
||||||
dependencies:
|
|
||||||
"@types/minimatch" "*"
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/minimatch@*":
|
|
||||||
version "3.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
|
|
||||||
integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
|
|
||||||
|
|
||||||
"@types/node@*":
|
|
||||||
version "16.11.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
|
|
||||||
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
|
|
||||||
|
|
||||||
ansi-styles@^3.2.1:
|
|
||||||
version "3.2.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
|
||||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
|
||||||
dependencies:
|
|
||||||
color-convert "^1.9.0"
|
|
||||||
|
|
||||||
array-union@^2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
|
|
||||||
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
|
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
|
||||||
version "1.1.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
|
||||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
|
||||||
dependencies:
|
|
||||||
balanced-match "^1.0.0"
|
|
||||||
concat-map "0.0.1"
|
|
||||||
|
|
||||||
braces@^3.0.1:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
|
||||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
|
||||||
dependencies:
|
|
||||||
fill-range "^7.0.1"
|
|
||||||
|
|
||||||
chalk@^2.0.0:
|
|
||||||
version "2.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
|
||||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^3.2.1"
|
|
||||||
escape-string-regexp "^1.0.5"
|
|
||||||
supports-color "^5.3.0"
|
|
||||||
|
|
||||||
color-convert@^1.9.0:
|
|
||||||
version "1.9.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
|
||||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
|
||||||
dependencies:
|
|
||||||
color-name "1.1.3"
|
|
||||||
|
|
||||||
color-name@1.1.3:
|
|
||||||
version "1.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
|
||||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
|
||||||
|
|
||||||
colorette@^1.1.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
|
|
||||||
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
|
|
||||||
|
|
||||||
concat-map@0.0.1:
|
|
||||||
version "0.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
|
||||||
|
|
||||||
dir-glob@^3.0.1:
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
|
||||||
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
|
|
||||||
dependencies:
|
|
||||||
path-type "^4.0.0"
|
|
||||||
|
|
||||||
escape-string-regexp@^1.0.5:
|
|
||||||
version "1.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
|
||||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
|
||||||
|
|
||||||
fast-glob@^3.0.3:
|
|
||||||
version "3.2.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
|
|
||||||
integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
|
|
||||||
dependencies:
|
|
||||||
"@nodelib/fs.stat" "^2.0.2"
|
|
||||||
"@nodelib/fs.walk" "^1.2.3"
|
|
||||||
glob-parent "^5.1.2"
|
|
||||||
merge2 "^1.3.0"
|
|
||||||
micromatch "^4.0.4"
|
|
||||||
|
|
||||||
fastq@^1.6.0:
|
|
||||||
version "1.13.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
|
|
||||||
integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
|
|
||||||
dependencies:
|
|
||||||
reusify "^1.0.4"
|
|
||||||
|
|
||||||
fill-range@^7.0.1:
|
|
||||||
version "7.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
|
||||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
|
||||||
dependencies:
|
|
||||||
to-regex-range "^5.0.1"
|
|
||||||
|
|
||||||
fs-extra@^8.1.0:
|
|
||||||
version "8.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
|
||||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
|
||||||
dependencies:
|
|
||||||
graceful-fs "^4.2.0"
|
|
||||||
jsonfile "^4.0.0"
|
|
||||||
universalify "^0.1.0"
|
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
|
||||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
|
||||||
|
|
||||||
fsevents@~2.3.2:
|
|
||||||
version "2.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
|
||||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
|
||||||
|
|
||||||
glob-parent@^5.1.2:
|
|
||||||
version "5.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
|
||||||
dependencies:
|
|
||||||
is-glob "^4.0.1"
|
|
||||||
|
|
||||||
glob@^7.1.3:
|
|
||||||
version "7.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
|
||||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
|
||||||
dependencies:
|
|
||||||
fs.realpath "^1.0.0"
|
|
||||||
inflight "^1.0.4"
|
|
||||||
inherits "2"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
once "^1.3.0"
|
|
||||||
path-is-absolute "^1.0.0"
|
|
||||||
|
|
||||||
globby@10.0.1:
|
|
||||||
version "10.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.1.tgz#4782c34cb75dd683351335c5829cc3420e606b22"
|
|
||||||
integrity sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==
|
|
||||||
dependencies:
|
|
||||||
"@types/glob" "^7.1.1"
|
|
||||||
array-union "^2.1.0"
|
|
||||||
dir-glob "^3.0.1"
|
|
||||||
fast-glob "^3.0.3"
|
|
||||||
glob "^7.1.3"
|
|
||||||
ignore "^5.1.1"
|
|
||||||
merge2 "^1.2.3"
|
|
||||||
slash "^3.0.0"
|
|
||||||
|
|
||||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
|
||||||
version "4.2.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
|
||||||
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
|
||||||
|
|
||||||
has-flag@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
|
||||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
|
||||||
|
|
||||||
ignore@^5.1.1:
|
|
||||||
version "5.1.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb"
|
|
||||||
integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==
|
|
||||||
|
|
||||||
inflight@^1.0.4:
|
|
||||||
version "1.0.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
|
||||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
|
||||||
dependencies:
|
|
||||||
once "^1.3.0"
|
|
||||||
wrappy "1"
|
|
||||||
|
|
||||||
inherits@2:
|
|
||||||
version "2.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
|
||||||
|
|
||||||
is-extglob@^2.1.1:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
|
||||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
|
||||||
|
|
||||||
is-glob@^4.0.1:
|
|
||||||
version "4.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
|
||||||
dependencies:
|
|
||||||
is-extglob "^2.1.1"
|
|
||||||
|
|
||||||
is-number@^7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
|
||||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
|
||||||
|
|
||||||
is-plain-object@^3.0.0:
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.1.tgz#662d92d24c0aa4302407b0d45d21f2251c85f85b"
|
|
||||||
integrity sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==
|
|
||||||
|
|
||||||
js-tokens@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
|
||||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
|
||||||
|
|
||||||
jsonfile@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
|
||||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
|
|
||||||
optionalDependencies:
|
|
||||||
graceful-fs "^4.1.6"
|
|
||||||
|
|
||||||
magic-string@^0.25.7:
|
|
||||||
version "0.25.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
|
||||||
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
|
|
||||||
dependencies:
|
|
||||||
sourcemap-codec "^1.4.4"
|
|
||||||
|
|
||||||
merge2@^1.2.3, merge2@^1.3.0:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
|
||||||
|
|
||||||
micromatch@^4.0.4:
|
|
||||||
version "4.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
|
|
||||||
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
|
|
||||||
dependencies:
|
|
||||||
braces "^3.0.1"
|
|
||||||
picomatch "^2.2.3"
|
|
||||||
|
|
||||||
minimatch@^3.0.4:
|
|
||||||
version "3.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
|
||||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
|
||||||
dependencies:
|
|
||||||
brace-expansion "^1.1.7"
|
|
||||||
|
|
||||||
once@^1.3.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
|
||||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
|
||||||
dependencies:
|
|
||||||
wrappy "1"
|
|
||||||
|
|
||||||
path-is-absolute@^1.0.0:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
|
||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
|
||||||
|
|
||||||
path-type@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
|
||||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
|
||||||
|
|
||||||
picomatch@^2.2.3:
|
|
||||||
version "2.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
|
||||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
|
||||||
|
|
||||||
queue-microtask@^1.2.2:
|
|
||||||
version "1.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
|
||||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
|
||||||
|
|
||||||
reusify@^1.0.4:
|
|
||||||
version "1.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
|
||||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
|
||||||
|
|
||||||
rollup-plugin-copy@^3.4.0:
|
|
||||||
version "3.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-3.4.0.tgz#f1228a3ffb66ffad8606e2f3fb7ff23141ed3286"
|
|
||||||
integrity sha512-rGUmYYsYsceRJRqLVlE9FivJMxJ7X6jDlP79fmFkL8sJs7VVMSVyA2yfyL+PGyO/vJs4A87hwhgVfz61njI+uQ==
|
|
||||||
dependencies:
|
|
||||||
"@types/fs-extra" "^8.0.1"
|
|
||||||
colorette "^1.1.0"
|
|
||||||
fs-extra "^8.1.0"
|
|
||||||
globby "10.0.1"
|
|
||||||
is-plain-object "^3.0.0"
|
|
||||||
|
|
||||||
rollup-plugin-dts@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-4.0.0.tgz#7645280183b7624e77375a548a11297f9916f6d8"
|
|
||||||
integrity sha512-tgUC8CxVgtlLDVloUEA9uACVaxjJHuYxlDSTp1LdCexA0bJx+RuMi45RjdLG9RTCgZlV5YBh3O7P2u6dS1KlnA==
|
|
||||||
dependencies:
|
|
||||||
magic-string "^0.25.7"
|
|
||||||
optionalDependencies:
|
|
||||||
"@babel/code-frame" "^7.14.5"
|
|
||||||
|
|
||||||
rollup@^2.56.3:
|
|
||||||
version "2.56.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.56.3.tgz#b63edadd9851b0d618a6d0e6af8201955a77aeff"
|
|
||||||
integrity sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents "~2.3.2"
|
|
||||||
|
|
||||||
run-parallel@^1.1.9:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
|
||||||
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
|
|
||||||
dependencies:
|
|
||||||
queue-microtask "^1.2.2"
|
|
||||||
|
|
||||||
slash@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
|
||||||
|
|
||||||
sourcemap-codec@^1.4.4:
|
|
||||||
version "1.4.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
|
||||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
|
||||||
version "5.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
|
||||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
|
||||||
dependencies:
|
|
||||||
has-flag "^3.0.0"
|
|
||||||
|
|
||||||
to-regex-range@^5.0.1:
|
|
||||||
version "5.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
|
||||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
|
||||||
dependencies:
|
|
||||||
is-number "^7.0.0"
|
|
||||||
|
|
||||||
typescript@^4.4.2:
|
|
||||||
version "4.4.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86"
|
|
||||||
integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==
|
|
||||||
|
|
||||||
universalify@^0.1.0:
|
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
|
||||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
|
||||||
|
|
||||||
wrappy@1:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
|
||||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
|
Loading…
Reference in a new issue