Compare commits
197 Commits
3f707149e3
...
v0.1.10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b54f95087 | ||
|
|
17c2e9fefe | ||
|
|
d2d8c1ffcf | ||
|
|
b9c638c280 | ||
|
|
8ac8f9fe6e | ||
|
|
ddb3144e66 | ||
|
|
ad5efc4b0f | ||
|
|
2de33b8150 | ||
|
|
e1fde88a60 | ||
|
|
123da9cca3 | ||
|
|
c20e7b5f2f | ||
|
|
74a3512038 | ||
|
|
ff04c4a131 | ||
|
|
00611e05c2 | ||
|
|
3e7e54a1bd | ||
|
|
aa35d1dc03 | ||
|
|
92afdc0ea6 | ||
|
|
f43920fc7c | ||
|
|
dde4bc7920 | ||
|
|
3d68e1fd00 | ||
|
|
8271f6b44a | ||
|
|
8a26965e14 | ||
|
|
3927889e66 | ||
|
|
5ecd7b8bef | ||
|
|
b0b795d13b | ||
|
|
182c2737cd | ||
|
|
5f93cabff5 | ||
|
|
a1f8cbe079 | ||
|
|
d7e870cba1 | ||
|
|
591b5ed382 | ||
|
|
fd141762f0 | ||
|
|
d59bbfa7d2 | ||
|
|
1d9f91cdd2 | ||
|
|
68f8e04ee8 | ||
|
|
c039e0d62c | ||
|
|
e6e3783ec6 | ||
|
|
5ae19e455d | ||
|
|
f475754a71 | ||
|
|
767f44f94d | ||
|
|
1411aca7b5 | ||
|
|
9ccdcaac24 | ||
|
|
d1223dcdb7 | ||
|
|
59448a4f2c | ||
|
|
5136880532 | ||
|
|
8654cf5507 | ||
|
|
6ca4dc8ffc | ||
|
|
a6f36ba679 | ||
|
|
176e37874e | ||
|
|
3208a04f7a | ||
|
|
0d579263cb | ||
|
|
c022b30110 | ||
|
|
7da4e4a29b | ||
|
|
8bc942a26f | ||
|
|
dff7550038 | ||
|
|
c4edcb8c24 | ||
|
|
4a44d88461 | ||
|
|
efc6bd11d9 | ||
|
|
51429e3155 | ||
|
|
b1a0fa4acf | ||
|
|
aeb2b6fe68 | ||
|
|
6679db98a8 | ||
|
|
5363324bbf | ||
|
|
dc9188dffc | ||
|
|
bd620ccd0d | ||
|
|
1947ae9f22 | ||
|
|
3fcf1b3864 | ||
|
|
d965dd6fd1 | ||
|
|
42dcd41e48 | ||
|
|
68fac7cfe8 | ||
|
|
a9f067e25a | ||
|
|
41b4b1015e | ||
|
|
9523365090 | ||
|
|
aa33fe42a8 | ||
|
|
78a9b93f22 | ||
|
|
a89339e472 | ||
|
|
f3307a8159 | ||
|
|
4bfa25dcb3 | ||
|
|
441a240c33 | ||
|
|
e767892dd5 | ||
|
|
8e0a7dea0f | ||
|
|
c4cc40f5e1 | ||
|
|
a5129199c7 | ||
|
|
c0e462944d | ||
|
|
63614841e8 | ||
|
|
bc4c09c546 | ||
|
|
0d1ab0e75a | ||
|
|
6e39029f91 | ||
|
|
d550966516 | ||
|
|
32d6b3d1ee | ||
|
|
7cb71a5a0a | ||
|
|
6b90a9bfa8 | ||
|
|
83d939bdc0 | ||
|
|
0e1ace78f4 | ||
|
|
6d4db60688 | ||
|
|
3aca01891d | ||
|
|
275ed87c3f | ||
|
|
b385270d7b | ||
|
|
fb412bc2cd | ||
|
|
585b1d2b74 | ||
|
|
c578bb45af | ||
|
|
b7f7876706 | ||
|
|
ee5ed17c20 | ||
|
|
a873794068 | ||
|
|
360b2d963d | ||
|
|
534c5ded3c | ||
|
|
bdaf90af03 | ||
|
|
1a67aac502 | ||
|
|
9f166278f4 | ||
|
|
c2222c9102 | ||
|
|
fc104680eb | ||
|
|
e40e3ff553 | ||
|
|
0b465fe290 | ||
|
|
d5396e311b | ||
|
|
384242af87 | ||
|
|
ec755bae8b | ||
|
|
0b1e06f0d5 | ||
|
|
bdfa050ee3 | ||
|
|
ec98e1c3c5 | ||
|
|
0d0b1b2051 | ||
|
|
2215c32e57 | ||
|
|
cf257443b0 | ||
|
|
62815621e4 | ||
|
|
7af5359e00 | ||
|
|
d1184fa1d0 | ||
|
|
5b146d7c07 | ||
|
|
926682d513 | ||
|
|
4c89d6c813 | ||
|
|
62926bb91d | ||
|
|
9ab649ebd4 | ||
|
|
ca1b633a9f | ||
|
|
f543caee00 | ||
|
|
409a92333e | ||
|
|
7a38d1ead3 | ||
|
|
33c53a14ab | ||
|
|
65615c64d2 | ||
|
|
166e59b922 | ||
|
|
8e357ed3b6 | ||
|
|
45074e3be3 | ||
|
|
ee1d8ca321 | ||
|
|
25531cc443 | ||
|
|
47a440147f | ||
|
|
8a91b9a074 | ||
|
|
d1ef83afca | ||
|
|
86dd526dde | ||
|
|
4d88256394 | ||
|
|
c49455e9ce | ||
|
|
a588da2c4a | ||
|
|
869c98d8b2 | ||
|
|
0374743cad | ||
|
|
4bc2f48738 | ||
|
|
69500837f2 | ||
|
|
0d0b9863c3 | ||
|
|
6bc6fdc87b | ||
|
|
53b9deff10 | ||
|
|
627f16e3a0 | ||
|
|
bf1a281c29 | ||
|
|
df4daa0e16 | ||
|
|
5cd34ba3a2 | ||
|
|
13b95cd0a1 | ||
|
|
876d042c37 | ||
|
|
81c0b7079f | ||
|
|
4a367dd7e0 | ||
|
|
8a0f9d4540 | ||
|
|
f6155ecf93 | ||
|
|
c077d34933 | ||
|
|
1ecc3ecf9d | ||
|
|
ced35e1694 | ||
|
|
840dc0a750 | ||
|
|
adc5a383c3 | ||
|
|
5ac12229f4 | ||
|
|
9565435526 | ||
|
|
e39562c85d | ||
|
|
c49556bd5d | ||
|
|
84ec2f2023 | ||
|
|
00ed63dcaa | ||
|
|
8dde8ce4e1 | ||
|
|
4e551e6d7e | ||
|
|
ea29ad8667 | ||
|
|
085e728c34 | ||
|
|
99318f39e3 | ||
|
|
c679a85e77 | ||
|
|
fc17fc224c | ||
|
|
7fe7e7a6ea | ||
|
|
ef591556fe | ||
|
|
c150aa4dea | ||
|
|
1df6777b0b | ||
|
|
8a109276df | ||
|
|
f07d041eb9 | ||
|
|
9bdec391f1 | ||
|
|
b9ead09dde | ||
|
|
dd009498dd | ||
|
|
17c745ee71 | ||
|
|
41aa0349a0 | ||
|
|
a6adeee40b | ||
|
|
a32cea8139 | ||
|
|
37bc5ef712 | ||
|
|
1a2f0856da |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
TODO.org
|
||||
|
||||
@@ -137,7 +137,7 @@ spec:
|
||||
value: []
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: run-image-all
|
||||
- name: run-image-tracing-compare
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
@@ -152,6 +152,46 @@ spec:
|
||||
value: ["--no-default-features", "--features", "tracing,compare"]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: run-image-compare-foreign
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: git-source
|
||||
- name: cargo-cache
|
||||
workspace: cargo-cache
|
||||
runAfter:
|
||||
- run-image-tracing-compare
|
||||
params:
|
||||
- name: args
|
||||
value:
|
||||
[
|
||||
"--no-default-features",
|
||||
"--features",
|
||||
"compare,foreign_document_test",
|
||||
]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
- name: run-image-all
|
||||
taskRef:
|
||||
name: run-docker-image
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: git-source
|
||||
- name: cargo-cache
|
||||
workspace: cargo-cache
|
||||
runAfter:
|
||||
- run-image-compare-foreign
|
||||
params:
|
||||
- name: args
|
||||
value:
|
||||
[
|
||||
"--no-default-features",
|
||||
"--features",
|
||||
"tracing,compare,foreign_document_test",
|
||||
]
|
||||
- name: docker-image
|
||||
value: "$(params.image-name):$(tasks.fetch-repository.results.commit)"
|
||||
finally:
|
||||
- name: report-success
|
||||
when:
|
||||
|
||||
13
Cargo.toml
13
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "organic"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
authors = ["Tom Alexander <tom@fizz.buzz>"]
|
||||
description = "An org-mode parser."
|
||||
edition = "2021"
|
||||
@@ -31,7 +31,14 @@ path = "src/lib.rs"
|
||||
path = "src/bin_compare.rs"
|
||||
required-features = ["compare"]
|
||||
|
||||
[[bin]]
|
||||
# This bin exists for development purposes only. The real target of this crate is the library.
|
||||
name = "foreign_document_test"
|
||||
path = "src/bin_foreign_document_test.rs"
|
||||
required-features = ["foreign_document_test"]
|
||||
|
||||
[dependencies]
|
||||
futures = { version = "0.3.28", optional = true }
|
||||
nom = "7.1.1"
|
||||
opentelemetry = { version = "0.20.0", optional = true, default-features = false, features = ["trace", "rt-tokio"] }
|
||||
opentelemetry-otlp = { version = "0.13.0", optional = true }
|
||||
@@ -40,13 +47,15 @@ tokio = { version = "1.30.0", optional = true, default-features = false, feature
|
||||
tracing = { version = "0.1.37", optional = true }
|
||||
tracing-opentelemetry = { version = "0.20.0", optional = true }
|
||||
tracing-subscriber = { version = "0.3.17", optional = true, features = ["env-filter"] }
|
||||
walkdir = { version = "2.3.3", optional = true }
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "2.3.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
compare = []
|
||||
compare = ["tokio/process", "tokio/macros"]
|
||||
foreign_document_test = ["compare", "dep:futures", "tokio/sync", "dep:walkdir", "tokio/process"]
|
||||
tracing = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry-semantic-conventions", "dep:tokio", "dep:tracing", "dep:tracing-opentelemetry", "dep:tracing-subscriber"]
|
||||
|
||||
# Optimized build for any sort of release.
|
||||
|
||||
2
Makefile
2
Makefile
@@ -52,6 +52,8 @@ buildtest:
|
||||
> cargo build --no-default-features --features compare
|
||||
> cargo build --no-default-features --features tracing
|
||||
> cargo build --no-default-features --features compare,tracing
|
||||
> cargo build --no-default-features --features compare,foreign_document_test
|
||||
> cargo build --no-default-features --features compare,tracing,foreign_document_test
|
||||
|
||||
.PHONY: foreign_document_test
|
||||
foreign_document_test:
|
||||
|
||||
@@ -6,14 +6,13 @@ Organic is an emacs-less implementation of an [org-mode](https://orgmode.org/) p
|
||||
|
||||
This project is still under HEAVY development. While the version remains v0.1.x the API will be changing often. Once we hit v0.2.x we will start following semver.
|
||||
|
||||
Currently, the parser is able to correctly identify the start/end bounds of all the org-mode objects and elements (except table.el tables, org-mode tables are supported) but many of the interior properties are not yet populated.
|
||||
Currently, Organic parses most documents the same as the official org-mode parser. Most of the development right now is finding documents where the parsers differ and fixing those issues.
|
||||
|
||||
### Project Goals
|
||||
- We aim to provide perfect parity with the emacs org-mode parser. In that regard, any document that parses differently between Emacs and Organic is considered a bug.
|
||||
- The parser should be fast. We're not doing anything special, but since this is written in Rust and natively compiled we should be able to beat the existing parsers.
|
||||
- The parser should have minimal dependencies. This should reduce effort w.r.t.: security audits, legal compliance, portability.
|
||||
- The parser should be usable everywhere. In the interest of getting org-mode used in as many places as possible, this parser should be usable by everyone everywhere. This means:
|
||||
- It must have a permissive license for use in proprietary code bases.
|
||||
- It must have a permissive license.
|
||||
- We will investigate compiling to WASM. This is an important goal of the project and will definitely happen, but only after the parser has a more stable API.
|
||||
- We will investigate compiling to a C library for native linking to other code. This is more of a maybe-goal for the project.
|
||||
### Project Non-Goals
|
||||
|
||||
@@ -14,7 +14,7 @@ RUN make DESTDIR="/root/dist" install
|
||||
|
||||
|
||||
FROM build AS build-org-mode
|
||||
ARG ORG_VERSION=c703541ffcc14965e3567f928de1683a1c1e33f6
|
||||
ARG ORG_VERSION=abf5156096c06ee5aa05795c3dc5a065f76ada97
|
||||
COPY --from=build-emacs /root/dist/ /
|
||||
RUN mkdir /root/dist
|
||||
# Savannah does not allow fetching specific revisions, so we're going to have to put unnecessary load on their server by cloning main and then checking out the revision we want.
|
||||
@@ -102,6 +102,4 @@ COPY --from=foreign-document-gather /foreign_documents/doomemacs /foreign_docume
|
||||
COPY --from=foreign-document-gather /foreign_documents/worg /foreign_documents/worg
|
||||
COPY --from=build-org-mode /root/org-mode /foreign_documents/org-mode
|
||||
COPY --from=build-emacs /root/emacs /foreign_documents/emacs
|
||||
COPY foreign_document_test_entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
ENTRYPOINT ["cargo", "run", "--bin", "foreign_document_test", "--features", "compare,foreign_document_test", "--profile", "release-lto"]
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Run the Organic compare script against a series of documents sourced from exterior places.
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
REALPATH=$(command -v uu-realpath || command -v realpath)
|
||||
|
||||
function log {
|
||||
(>&2 echo "${@}")
|
||||
}
|
||||
|
||||
function die {
|
||||
local status_code="$1"
|
||||
shift
|
||||
(>&2 echo "${@}")
|
||||
exit "$status_code"
|
||||
}
|
||||
|
||||
function main {
|
||||
cargo build --no-default-features --features compare --profile release-lto
|
||||
if [ "${CARGO_TARGET_DIR:-}" = "" ]; then
|
||||
CARGO_TARGET_DIR=$(realpath target/)
|
||||
fi
|
||||
PARSE="${CARGO_TARGET_DIR}/release-lto/compare"
|
||||
|
||||
local all_status=0
|
||||
set +e
|
||||
|
||||
(run_compare_function "org-mode" compare_all_org_document "/foreign_documents/org-mode")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "emacs" compare_all_org_document "/foreign_documents/emacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "worg" compare_all_org_document "/foreign_documents/worg")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "howard_abrams" compare_howard_abrams)
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "doomemacs" compare_all_org_document "/foreign_documents/doomemacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
|
||||
set -e
|
||||
if [ "$all_status" -ne 0 ]; then
|
||||
red_text "Some tests failed."
|
||||
else
|
||||
green_text "All tests passed."
|
||||
fi
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
function green_text {
|
||||
(IFS=' '; printf '\x1b[38;2;0;255;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function red_text {
|
||||
(IFS=' '; printf '\x1b[38;2;255;0;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function yellow_text {
|
||||
(IFS=' '; printf '\x1b[38;2;255;255;0m%s\x1b[0m' "${*}")
|
||||
}
|
||||
|
||||
function indent {
|
||||
local depth="$1"
|
||||
local scaled_depth=$((depth * 2))
|
||||
shift 1
|
||||
local prefix
|
||||
prefix=$(printf -- "%${scaled_depth}s")
|
||||
while read -r l; do
|
||||
(IFS=' '; printf -- '%s%s\n' "$prefix" "$l")
|
||||
done
|
||||
}
|
||||
|
||||
function run_compare_function {
|
||||
local name="$1"
|
||||
local stdoutput
|
||||
shift 1
|
||||
set +e
|
||||
stdoutput=$("${@}")
|
||||
local status=$?
|
||||
set -e
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo "$(green_text "GOOD") $name"
|
||||
indent 1 <<<"$stdoutput"
|
||||
else
|
||||
echo "$(red_text "FAIL") $name"
|
||||
indent 1 <<<"$stdoutput"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function compare_all_org_document {
|
||||
local root_dir="$1"
|
||||
local target_document
|
||||
local all_status=0
|
||||
while read target_document; do
|
||||
local relative_path
|
||||
relative_path=$($REALPATH --relative-to "$root_dir" "$target_document")
|
||||
set +e
|
||||
(run_compare "$relative_path" "$target_document")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
set -e
|
||||
done<<<"$(find "$root_dir" -type f -iname '*.org' | sort)"
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
function run_compare {
|
||||
local name="$1"
|
||||
local target_document="$2"
|
||||
set +e
|
||||
($PARSE "$target_document" &> /dev/null)
|
||||
local status=$?
|
||||
set -e
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo "$(green_text "GOOD") $name"
|
||||
else
|
||||
echo "$(red_text "FAIL") $name"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function compare_howard_abrams {
|
||||
local all_status=0
|
||||
set +e
|
||||
|
||||
(run_compare_function "dot-files" compare_all_org_document "/foreign_documents/howardabrams/dot-files")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "hamacs" compare_all_org_document "/foreign_documents/howardabrams/hamacs")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "demo-it" compare_all_org_document "/foreign_documents/howardabrams/demo-it")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "magit-demo" compare_all_org_document "/foreign_documents/howardabrams/magit-demo")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "pdx-emacs-hackers" compare_all_org_document "/foreign_documents/howardabrams/pdx-emacs-hackers")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "flora-simulator" compare_all_org_document "/foreign_documents/howardabrams/flora-simulator")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "literate-devops-demo" compare_all_org_document "/foreign_documents/howardabrams/literate-devops-demo")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "clojure-yesql-xp" compare_all_org_document "/foreign_documents/howardabrams/clojure-yesql-xp")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
(run_compare_function "veep" compare_all_org_document "/foreign_documents/howardabrams/veep")
|
||||
if [ "$?" -ne 0 ]; then all_status=1; fi
|
||||
|
||||
set -e
|
||||
return "$all_status"
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
@@ -1,5 +1,11 @@
|
||||
(dolist (var org-entities)
|
||||
(when (listp var)
|
||||
(message "\"%s\"," (nth 0 var))
|
||||
(dolist (var (sort (seq-filter 'listp org-entities)
|
||||
(lambda (x y) (> (length (nth 0 x)) (length (nth 0 y))))))
|
||||
(message "EntityDefinition {name: %s, latex_math_mode: %s, latex: %s, html: %s, ascii: %s, utf8: %s},"
|
||||
(prin1-to-string (nth 0 var))
|
||||
(if (nth 2 var) "true" "false")
|
||||
(prin1-to-string (nth 1 var))
|
||||
(prin1-to-string (nth 3 var))
|
||||
(prin1-to-string (nth 4 var))
|
||||
(prin1-to-string (nth 6 var))
|
||||
)
|
||||
)
|
||||
|
||||
8
org_mode_samples/affiliated_keyword/optional_value.org
Normal file
8
org_mode_samples/affiliated_keyword/optional_value.org
Normal file
@@ -0,0 +1,8 @@
|
||||
#+CAPTION[foo]: *bar*
|
||||
#+CAPTION[*lorem* ipsum]: dolar
|
||||
1. baz
|
||||
|
||||
|
||||
#+CAPTION[foo]: *bar*
|
||||
#+CAPTION[*lorem* ipsum]: dolar
|
||||
# Comments cannot have affiliated keywords so those become regular keywords.
|
||||
@@ -0,0 +1,74 @@
|
||||
* Headline
|
||||
before
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
after
|
||||
@@ -1,10 +0,0 @@
|
||||
* Headline
|
||||
before
|
||||
#+NAME: foo
|
||||
:candle:
|
||||
inside
|
||||
|
||||
the drawer
|
||||
:end:
|
||||
|
||||
after
|
||||
@@ -0,0 +1,72 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
@@ -1,7 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+BEGIN: clocktable :scope file :maxlevel 2
|
||||
#+CAPTION: Clock summary at [2023-08-25 Fri 05:34]
|
||||
| Headline | Time |
|
||||
|--------------+--------|
|
||||
| *Total time* | *0:00* |
|
||||
#+END:
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
[fn:1] A footnote.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
[fn:1] A footnote.
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_center
|
||||
|
||||
#+end_center
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_quote
|
||||
|
||||
#+end_quote
|
||||
@@ -0,0 +1,71 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
@@ -1,6 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_defun
|
||||
foo
|
||||
|
||||
{{{bar(baz)}}}
|
||||
#+end_defun
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
1. bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
1. BAR
|
||||
3
org_mode_samples/greater_element/plain_list/checkbox.org
Normal file
3
org_mode_samples/greater_element/plain_list/checkbox.org
Normal file
@@ -0,0 +1,3 @@
|
||||
- [ ] Foo
|
||||
- [-] Bar
|
||||
- [X] Baz
|
||||
@@ -0,0 +1,3 @@
|
||||
1. foo
|
||||
#+NAME: bar
|
||||
2. baz
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
1. bar
|
||||
@@ -0,0 +1,2 @@
|
||||
# This test causes problems with regular links if we do not create a new ContextTree when calling into confine_context.
|
||||
- foo [[info:bar][baz]] lorem
|
||||
@@ -0,0 +1,5 @@
|
||||
* baz
|
||||
# lorem
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,6 @@
|
||||
* baz
|
||||
# lorem
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
* baz
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
* baz
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,13 @@
|
||||
* baz
|
||||
|
||||
|
||||
|
||||
|
||||
# lorem
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,19 @@
|
||||
:PROPERTIES:
|
||||
:foo: bar
|
||||
:foo+: baz
|
||||
:cat: dog
|
||||
:END:
|
||||
|
||||
# Even though these are inheriting the properties and overwriting and/or appending to them, this is not represented in the parser AST so Organic does not do any special handling of this.
|
||||
|
||||
* Overwrite
|
||||
:PROPERTIES:
|
||||
:foo: lorem
|
||||
:bat: car
|
||||
:END:
|
||||
|
||||
* Append
|
||||
:PROPERTIES:
|
||||
:foo+: ipsum
|
||||
:cake: lie
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
* Overwrite
|
||||
#+NAME: foo
|
||||
:PROPERTIES:
|
||||
:header-args: :var foo="lorem"
|
||||
:END:
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# Blank lines and comments can come before property drawers in the zeroth section
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
|
||||
|
||||
|
||||
* Spaces turn property drawers into regular drawers
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
* Comments turn property drawers into regular drawers
|
||||
# Comment
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
* Baseline
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
# lorem
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,5 @@
|
||||
# lorem
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,3 @@
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# lorem
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
# Blank lines and comments can come before property drawers in the zeroth section
|
||||
|
||||
|
||||
|
||||
|
||||
:PROPERTIES:
|
||||
:FOO: bar
|
||||
:END:
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
| foo | bar |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
| foo | bar |
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
| foo | bar |
|
||||
3
org_mode_samples/greater_element/table/row/name.org
Normal file
3
org_mode_samples/greater_element/table/row/name.org
Normal file
@@ -0,0 +1,3 @@
|
||||
|foo|
|
||||
#+NAME: bar
|
||||
|baz |
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+call: foo(bar="baz")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+call: foo(bar="baz")
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+call: foo(bar="baz")
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
%%(foo)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
%%(foo)
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
%%(foo)
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
: bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
: bar
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
: bar
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
-----
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
-----
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
-----
|
||||
@@ -1,8 +1,63 @@
|
||||
#+name: foo
|
||||
#+caption: bar
|
||||
#+caption: baz
|
||||
[[file:lorem/ipsum.png]]
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+foo: bar
|
||||
|
||||
#+name: cat
|
||||
#+caption: dog
|
||||
[[file:lorem/ipsum.png]]
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+foo: bar
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# This test is to prove that the parser works with affiliated keywords that have both a shorter and longer version.
|
||||
|
||||
#+results:
|
||||
#+result:
|
||||
#+begin_latex
|
||||
\foo
|
||||
#+end_latex
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+FOO: BAR
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
\begin{foo}
|
||||
bar
|
||||
\end{foo}
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_comment text
|
||||
bar
|
||||
#+end_comment
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_example text
|
||||
bar
|
||||
#+end_example
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_export text
|
||||
bar
|
||||
#+end_export
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_src text
|
||||
bar
|
||||
#+end_src
|
||||
@@ -0,0 +1,67 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
@@ -1,4 +0,0 @@
|
||||
#+NAME: foo
|
||||
#+begin_verse text
|
||||
bar
|
||||
#+end_verse
|
||||
@@ -0,0 +1,63 @@
|
||||
#+NAME: a
|
||||
#+caption: b *lorem* ipsum
|
||||
#+results: c
|
||||
#+headers: d
|
||||
#+header: e
|
||||
#+label: f
|
||||
#+plot: g
|
||||
#+resname: h
|
||||
#+result: i
|
||||
#+source: j
|
||||
#+srcname: k
|
||||
#+tblname: l
|
||||
#+attr_latex: m
|
||||
#+attr_html: n
|
||||
#+NAME: aa
|
||||
#+caption: bb *lorem* ipsum
|
||||
#+results: cc
|
||||
#+headers: dd
|
||||
#+header: ee
|
||||
#+label: ff
|
||||
#+plot: gg
|
||||
#+resname: hh
|
||||
#+result: ii
|
||||
#+source: jj
|
||||
#+srcname: kk
|
||||
#+tblname: ll
|
||||
#+attr_latex: mm
|
||||
#+attr_html: nn
|
||||
bar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#+NAME: A
|
||||
#+CAPTION: B *LOREM* IPSUM
|
||||
#+RESULTS: C
|
||||
#+HEADERS: D
|
||||
#+HEADER: E
|
||||
#+LABEL: F
|
||||
#+PLOT: G
|
||||
#+RESNAME: H
|
||||
#+RESULT: I
|
||||
#+SOURCE: J
|
||||
#+SRCNAME: K
|
||||
#+TBLNAME: L
|
||||
#+ATTR_LATEX: M
|
||||
#+ATTR_HTML: N
|
||||
#+NAME: AA
|
||||
#+CAPTION: BB *LOREM* IPSUM
|
||||
#+RESULTS: CC
|
||||
#+HEADERS: DD
|
||||
#+HEADER: EE
|
||||
#+LABEL: FF
|
||||
#+PLOT: GG
|
||||
#+RESNAME: HH
|
||||
#+RESULT: II
|
||||
#+SOURCE: JJ
|
||||
#+SRCNAME: KK
|
||||
#+TBLNAME: LL
|
||||
#+ATTR_LATEX: MM
|
||||
#+ATTR_HTML: NN
|
||||
bar
|
||||
@@ -1,2 +0,0 @@
|
||||
#+NAME: foo
|
||||
bar
|
||||
414
org_mode_samples/object/entity/all_entities.org
Normal file
414
org_mode_samples/object/entity/all_entities.org
Normal file
@@ -0,0 +1,414 @@
|
||||
\Agrave{}
|
||||
\agrave{}
|
||||
\Aacute{}
|
||||
\aacute{}
|
||||
\Acirc{}
|
||||
\acirc{}
|
||||
\Amacr{}
|
||||
\amacr{}
|
||||
\Atilde{}
|
||||
\atilde{}
|
||||
\Auml{}
|
||||
\auml{}
|
||||
\Aring{}
|
||||
\AA{}
|
||||
\aring{}
|
||||
\AElig{}
|
||||
\aelig{}
|
||||
\Ccedil{}
|
||||
\ccedil{}
|
||||
\Egrave{}
|
||||
\egrave{}
|
||||
\Eacute{}
|
||||
\eacute{}
|
||||
\Ecirc{}
|
||||
\ecirc{}
|
||||
\Euml{}
|
||||
\euml{}
|
||||
\Igrave{}
|
||||
\igrave{}
|
||||
\Iacute{}
|
||||
\iacute{}
|
||||
\Idot{}
|
||||
\inodot{}
|
||||
\Icirc{}
|
||||
\icirc{}
|
||||
\Iuml{}
|
||||
\iuml{}
|
||||
\Ntilde{}
|
||||
\ntilde{}
|
||||
\Ograve{}
|
||||
\ograve{}
|
||||
\Oacute{}
|
||||
\oacute{}
|
||||
\Ocirc{}
|
||||
\ocirc{}
|
||||
\Otilde{}
|
||||
\otilde{}
|
||||
\Ouml{}
|
||||
\ouml{}
|
||||
\Oslash{}
|
||||
\oslash{}
|
||||
\OElig{}
|
||||
\oelig{}
|
||||
\Scaron{}
|
||||
\scaron{}
|
||||
\szlig{}
|
||||
\Ugrave{}
|
||||
\ugrave{}
|
||||
\Uacute{}
|
||||
\uacute{}
|
||||
\Ucirc{}
|
||||
\ucirc{}
|
||||
\Uuml{}
|
||||
\uuml{}
|
||||
\Yacute{}
|
||||
\yacute{}
|
||||
\Yuml{}
|
||||
\yuml{}
|
||||
\fnof{}
|
||||
\real{}
|
||||
\image{}
|
||||
\weierp{}
|
||||
\ell{}
|
||||
\imath{}
|
||||
\jmath{}
|
||||
\Alpha{}
|
||||
\alpha{}
|
||||
\Beta{}
|
||||
\beta{}
|
||||
\Gamma{}
|
||||
\gamma{}
|
||||
\Delta{}
|
||||
\delta{}
|
||||
\Epsilon{}
|
||||
\epsilon{}
|
||||
\varepsilon{}
|
||||
\Zeta{}
|
||||
\zeta{}
|
||||
\Eta{}
|
||||
\eta{}
|
||||
\Theta{}
|
||||
\theta{}
|
||||
\thetasym{}
|
||||
\vartheta{}
|
||||
\Iota{}
|
||||
\iota{}
|
||||
\Kappa{}
|
||||
\kappa{}
|
||||
\Lambda{}
|
||||
\lambda{}
|
||||
\Mu{}
|
||||
\mu{}
|
||||
\nu{}
|
||||
\Nu{}
|
||||
\Xi{}
|
||||
\xi{}
|
||||
\Omicron{}
|
||||
\omicron{}
|
||||
\Pi{}
|
||||
\pi{}
|
||||
\Rho{}
|
||||
\rho{}
|
||||
\Sigma{}
|
||||
\sigma{}
|
||||
\sigmaf{}
|
||||
\varsigma{}
|
||||
\Tau{}
|
||||
\Upsilon{}
|
||||
\upsih{}
|
||||
\upsilon{}
|
||||
\Phi{}
|
||||
\phi{}
|
||||
\varphi{}
|
||||
\Chi{}
|
||||
\chi{}
|
||||
\acutex{}
|
||||
\Psi{}
|
||||
\psi{}
|
||||
\tau{}
|
||||
\Omega{}
|
||||
\omega{}
|
||||
\piv{}
|
||||
\varpi{}
|
||||
\partial{}
|
||||
\alefsym{}
|
||||
\aleph{}
|
||||
\gimel{}
|
||||
\beth{}
|
||||
\dalet{}
|
||||
\ETH{}
|
||||
\eth{}
|
||||
\THORN{}
|
||||
\thorn{}
|
||||
\dots{}
|
||||
\cdots{}
|
||||
\hellip{}
|
||||
\middot{}
|
||||
\iexcl{}
|
||||
\iquest{}
|
||||
\shy{}
|
||||
\ndash{}
|
||||
\mdash{}
|
||||
\quot{}
|
||||
\acute{}
|
||||
\ldquo{}
|
||||
\rdquo{}
|
||||
\bdquo{}
|
||||
\lsquo{}
|
||||
\rsquo{}
|
||||
\sbquo{}
|
||||
\laquo{}
|
||||
\raquo{}
|
||||
\lsaquo{}
|
||||
\rsaquo{}
|
||||
\circ{}
|
||||
\vert{}
|
||||
\vbar{}
|
||||
\brvbar{}
|
||||
\S{}
|
||||
\sect{}
|
||||
\P{}
|
||||
\para{}
|
||||
\amp{}
|
||||
\lt{}
|
||||
\gt{}
|
||||
\tilde{}
|
||||
\slash{}
|
||||
\plus{}
|
||||
\under{}
|
||||
\equal{}
|
||||
\asciicirc{}
|
||||
\dagger{}
|
||||
\dag{}
|
||||
\Dagger{}
|
||||
\ddag{}
|
||||
\nbsp{}
|
||||
\ensp{}
|
||||
\emsp{}
|
||||
\thinsp{}
|
||||
\curren{}
|
||||
\cent{}
|
||||
\pound{}
|
||||
\yen{}
|
||||
\euro{}
|
||||
\EUR{}
|
||||
\dollar{}
|
||||
\USD{}
|
||||
\copy{}
|
||||
\reg{}
|
||||
\trade{}
|
||||
\minus{}
|
||||
\pm{}
|
||||
\plusmn{}
|
||||
\times{}
|
||||
\frasl{}
|
||||
\colon{}
|
||||
\div{}
|
||||
\frac12{}
|
||||
\frac14{}
|
||||
\frac34{}
|
||||
\permil{}
|
||||
\sup1{}
|
||||
\sup2{}
|
||||
\sup3{}
|
||||
\radic{}
|
||||
\sum{}
|
||||
\prod{}
|
||||
\micro{}
|
||||
\macr{}
|
||||
\deg{}
|
||||
\prime{}
|
||||
\Prime{}
|
||||
\infin{}
|
||||
\infty{}
|
||||
\prop{}
|
||||
\propto{}
|
||||
\not{}
|
||||
\neg{}
|
||||
\land{}
|
||||
\wedge{}
|
||||
\lor{}
|
||||
\vee{}
|
||||
\cap{}
|
||||
\cup{}
|
||||
\smile{}
|
||||
\frown{}
|
||||
\int{}
|
||||
\therefore{}
|
||||
\there4{}
|
||||
\because{}
|
||||
\sim{}
|
||||
\cong{}
|
||||
\simeq{}
|
||||
\asymp{}
|
||||
\approx{}
|
||||
\ne{}
|
||||
\neq{}
|
||||
\equiv{}
|
||||
\triangleq{}
|
||||
\le{}
|
||||
\leq{}
|
||||
\ge{}
|
||||
\geq{}
|
||||
\lessgtr{}
|
||||
\lesseqgtr{}
|
||||
\ll{}
|
||||
\Ll{}
|
||||
\lll{}
|
||||
\gg{}
|
||||
\Gg{}
|
||||
\ggg{}
|
||||
\prec{}
|
||||
\preceq{}
|
||||
\preccurlyeq{}
|
||||
\succ{}
|
||||
\succeq{}
|
||||
\succcurlyeq{}
|
||||
\sub{}
|
||||
\subset{}
|
||||
\sup{}
|
||||
\supset{}
|
||||
\nsub{}
|
||||
\sube{}
|
||||
\nsup{}
|
||||
\supe{}
|
||||
\setminus{}
|
||||
\forall{}
|
||||
\exist{}
|
||||
\exists{}
|
||||
\nexist{}
|
||||
\nexists{}
|
||||
\empty{}
|
||||
\emptyset{}
|
||||
\isin{}
|
||||
\in{}
|
||||
\notin{}
|
||||
\ni{}
|
||||
\nabla{}
|
||||
\ang{}
|
||||
\angle{}
|
||||
\perp{}
|
||||
\parallel{}
|
||||
\sdot{}
|
||||
\cdot{}
|
||||
\lceil{}
|
||||
\rceil{}
|
||||
\lfloor{}
|
||||
\rfloor{}
|
||||
\lang{}
|
||||
\rang{}
|
||||
\langle{}
|
||||
\rangle{}
|
||||
\hbar{}
|
||||
\mho{}
|
||||
\larr{}
|
||||
\leftarrow{}
|
||||
\gets{}
|
||||
\lArr{}
|
||||
\Leftarrow{}
|
||||
\uarr{}
|
||||
\uparrow{}
|
||||
\uArr{}
|
||||
\Uparrow{}
|
||||
\rarr{}
|
||||
\to{}
|
||||
\rightarrow{}
|
||||
\rArr{}
|
||||
\Rightarrow{}
|
||||
\darr{}
|
||||
\downarrow{}
|
||||
\dArr{}
|
||||
\Downarrow{}
|
||||
\harr{}
|
||||
\leftrightarrow{}
|
||||
\hArr{}
|
||||
\Leftrightarrow{}
|
||||
\crarr{}
|
||||
\hookleftarrow{}
|
||||
\arccos{}
|
||||
\arcsin{}
|
||||
\arctan{}
|
||||
\arg{}
|
||||
\cos{}
|
||||
\cosh{}
|
||||
\cot{}
|
||||
\coth{}
|
||||
\csc{}
|
||||
\deg{}
|
||||
\det{}
|
||||
\dim{}
|
||||
\exp{}
|
||||
\gcd{}
|
||||
\hom{}
|
||||
\inf{}
|
||||
\ker{}
|
||||
\lg{}
|
||||
\lim{}
|
||||
\liminf{}
|
||||
\limsup{}
|
||||
\ln{}
|
||||
\log{}
|
||||
\max{}
|
||||
\min{}
|
||||
\Pr{}
|
||||
\sec{}
|
||||
\sin{}
|
||||
\sinh{}
|
||||
\sup{}
|
||||
\tan{}
|
||||
\tanh{}
|
||||
\bull{}
|
||||
\bullet{}
|
||||
\star{}
|
||||
\lowast{}
|
||||
\ast{}
|
||||
\odot{}
|
||||
\oplus{}
|
||||
\otimes{}
|
||||
\check{}
|
||||
\checkmark{}
|
||||
\ordf{}
|
||||
\ordm{}
|
||||
\cedil{}
|
||||
\oline{}
|
||||
\uml{}
|
||||
\zwnj{}
|
||||
\zwj{}
|
||||
\lrm{}
|
||||
\rlm{}
|
||||
\smiley{}
|
||||
\blacksmile{}
|
||||
\sad{}
|
||||
\frowny{}
|
||||
\clubs{}
|
||||
\clubsuit{}
|
||||
\spades{}
|
||||
\spadesuit{}
|
||||
\hearts{}
|
||||
\heartsuit{}
|
||||
\diams{}
|
||||
\diamondsuit{}
|
||||
\diamond{}
|
||||
\Diamond{}
|
||||
\loz{}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
\_ {}
|
||||
414
org_mode_samples/object/entity/all_entities_without_braces.org
Normal file
414
org_mode_samples/object/entity/all_entities_without_braces.org
Normal file
@@ -0,0 +1,414 @@
|
||||
\Agrave
|
||||
\agrave
|
||||
\Aacute
|
||||
\aacute
|
||||
\Acirc
|
||||
\acirc
|
||||
\Amacr
|
||||
\amacr
|
||||
\Atilde
|
||||
\atilde
|
||||
\Auml
|
||||
\auml
|
||||
\Aring
|
||||
\AA
|
||||
\aring
|
||||
\AElig
|
||||
\aelig
|
||||
\Ccedil
|
||||
\ccedil
|
||||
\Egrave
|
||||
\egrave
|
||||
\Eacute
|
||||
\eacute
|
||||
\Ecirc
|
||||
\ecirc
|
||||
\Euml
|
||||
\euml
|
||||
\Igrave
|
||||
\igrave
|
||||
\Iacute
|
||||
\iacute
|
||||
\Idot
|
||||
\inodot
|
||||
\Icirc
|
||||
\icirc
|
||||
\Iuml
|
||||
\iuml
|
||||
\Ntilde
|
||||
\ntilde
|
||||
\Ograve
|
||||
\ograve
|
||||
\Oacute
|
||||
\oacute
|
||||
\Ocirc
|
||||
\ocirc
|
||||
\Otilde
|
||||
\otilde
|
||||
\Ouml
|
||||
\ouml
|
||||
\Oslash
|
||||
\oslash
|
||||
\OElig
|
||||
\oelig
|
||||
\Scaron
|
||||
\scaron
|
||||
\szlig
|
||||
\Ugrave
|
||||
\ugrave
|
||||
\Uacute
|
||||
\uacute
|
||||
\Ucirc
|
||||
\ucirc
|
||||
\Uuml
|
||||
\uuml
|
||||
\Yacute
|
||||
\yacute
|
||||
\Yuml
|
||||
\yuml
|
||||
\fnof
|
||||
\real
|
||||
\image
|
||||
\weierp
|
||||
\ell
|
||||
\imath
|
||||
\jmath
|
||||
\Alpha
|
||||
\alpha
|
||||
\Beta
|
||||
\beta
|
||||
\Gamma
|
||||
\gamma
|
||||
\Delta
|
||||
\delta
|
||||
\Epsilon
|
||||
\epsilon
|
||||
\varepsilon
|
||||
\Zeta
|
||||
\zeta
|
||||
\Eta
|
||||
\eta
|
||||
\Theta
|
||||
\theta
|
||||
\thetasym
|
||||
\vartheta
|
||||
\Iota
|
||||
\iota
|
||||
\Kappa
|
||||
\kappa
|
||||
\Lambda
|
||||
\lambda
|
||||
\Mu
|
||||
\mu
|
||||
\nu
|
||||
\Nu
|
||||
\Xi
|
||||
\xi
|
||||
\Omicron
|
||||
\omicron
|
||||
\Pi
|
||||
\pi
|
||||
\Rho
|
||||
\rho
|
||||
\Sigma
|
||||
\sigma
|
||||
\sigmaf
|
||||
\varsigma
|
||||
\Tau
|
||||
\Upsilon
|
||||
\upsih
|
||||
\upsilon
|
||||
\Phi
|
||||
\phi
|
||||
\varphi
|
||||
\Chi
|
||||
\chi
|
||||
\acutex
|
||||
\Psi
|
||||
\psi
|
||||
\tau
|
||||
\Omega
|
||||
\omega
|
||||
\piv
|
||||
\varpi
|
||||
\partial
|
||||
\alefsym
|
||||
\aleph
|
||||
\gimel
|
||||
\beth
|
||||
\dalet
|
||||
\ETH
|
||||
\eth
|
||||
\THORN
|
||||
\thorn
|
||||
\dots
|
||||
\cdots
|
||||
\hellip
|
||||
\middot
|
||||
\iexcl
|
||||
\iquest
|
||||
\shy
|
||||
\ndash
|
||||
\mdash
|
||||
\quot
|
||||
\acute
|
||||
\ldquo
|
||||
\rdquo
|
||||
\bdquo
|
||||
\lsquo
|
||||
\rsquo
|
||||
\sbquo
|
||||
\laquo
|
||||
\raquo
|
||||
\lsaquo
|
||||
\rsaquo
|
||||
\circ
|
||||
\vert
|
||||
\vbar
|
||||
\brvbar
|
||||
\S
|
||||
\sect
|
||||
\P
|
||||
\para
|
||||
\amp
|
||||
\lt
|
||||
\gt
|
||||
\tilde
|
||||
\slash
|
||||
\plus
|
||||
\under
|
||||
\equal
|
||||
\asciicirc
|
||||
\dagger
|
||||
\dag
|
||||
\Dagger
|
||||
\ddag
|
||||
\nbsp
|
||||
\ensp
|
||||
\emsp
|
||||
\thinsp
|
||||
\curren
|
||||
\cent
|
||||
\pound
|
||||
\yen
|
||||
\euro
|
||||
\EUR
|
||||
\dollar
|
||||
\USD
|
||||
\copy
|
||||
\reg
|
||||
\trade
|
||||
\minus
|
||||
\pm
|
||||
\plusmn
|
||||
\times
|
||||
\frasl
|
||||
\colon
|
||||
\div
|
||||
\frac12
|
||||
\frac14
|
||||
\frac34
|
||||
\permil
|
||||
\sup1
|
||||
\sup2
|
||||
\sup3
|
||||
\radic
|
||||
\sum
|
||||
\prod
|
||||
\micro
|
||||
\macr
|
||||
\deg
|
||||
\prime
|
||||
\Prime
|
||||
\infin
|
||||
\infty
|
||||
\prop
|
||||
\propto
|
||||
\not
|
||||
\neg
|
||||
\land
|
||||
\wedge
|
||||
\lor
|
||||
\vee
|
||||
\cap
|
||||
\cup
|
||||
\smile
|
||||
\frown
|
||||
\int
|
||||
\therefore
|
||||
\there4
|
||||
\because
|
||||
\sim
|
||||
\cong
|
||||
\simeq
|
||||
\asymp
|
||||
\approx
|
||||
\ne
|
||||
\neq
|
||||
\equiv
|
||||
\triangleq
|
||||
\le
|
||||
\leq
|
||||
\ge
|
||||
\geq
|
||||
\lessgtr
|
||||
\lesseqgtr
|
||||
\ll
|
||||
\Ll
|
||||
\lll
|
||||
\gg
|
||||
\Gg
|
||||
\ggg
|
||||
\prec
|
||||
\preceq
|
||||
\preccurlyeq
|
||||
\succ
|
||||
\succeq
|
||||
\succcurlyeq
|
||||
\sub
|
||||
\subset
|
||||
\sup
|
||||
\supset
|
||||
\nsub
|
||||
\sube
|
||||
\nsup
|
||||
\supe
|
||||
\setminus
|
||||
\forall
|
||||
\exist
|
||||
\exists
|
||||
\nexist
|
||||
\nexists
|
||||
\empty
|
||||
\emptyset
|
||||
\isin
|
||||
\in
|
||||
\notin
|
||||
\ni
|
||||
\nabla
|
||||
\ang
|
||||
\angle
|
||||
\perp
|
||||
\parallel
|
||||
\sdot
|
||||
\cdot
|
||||
\lceil
|
||||
\rceil
|
||||
\lfloor
|
||||
\rfloor
|
||||
\lang
|
||||
\rang
|
||||
\langle
|
||||
\rangle
|
||||
\hbar
|
||||
\mho
|
||||
\larr
|
||||
\leftarrow
|
||||
\gets
|
||||
\lArr
|
||||
\Leftarrow
|
||||
\uarr
|
||||
\uparrow
|
||||
\uArr
|
||||
\Uparrow
|
||||
\rarr
|
||||
\to
|
||||
\rightarrow
|
||||
\rArr
|
||||
\Rightarrow
|
||||
\darr
|
||||
\downarrow
|
||||
\dArr
|
||||
\Downarrow
|
||||
\harr
|
||||
\leftrightarrow
|
||||
\hArr
|
||||
\Leftrightarrow
|
||||
\crarr
|
||||
\hookleftarrow
|
||||
\arccos
|
||||
\arcsin
|
||||
\arctan
|
||||
\arg
|
||||
\cos
|
||||
\cosh
|
||||
\cot
|
||||
\coth
|
||||
\csc
|
||||
\deg
|
||||
\det
|
||||
\dim
|
||||
\exp
|
||||
\gcd
|
||||
\hom
|
||||
\inf
|
||||
\ker
|
||||
\lg
|
||||
\lim
|
||||
\liminf
|
||||
\limsup
|
||||
\ln
|
||||
\log
|
||||
\max
|
||||
\min
|
||||
\Pr
|
||||
\sec
|
||||
\sin
|
||||
\sinh
|
||||
\sup
|
||||
\tan
|
||||
\tanh
|
||||
\bull
|
||||
\bullet
|
||||
\star
|
||||
\lowast
|
||||
\ast
|
||||
\odot
|
||||
\oplus
|
||||
\otimes
|
||||
\check
|
||||
\checkmark
|
||||
\ordf
|
||||
\ordm
|
||||
\cedil
|
||||
\oline
|
||||
\uml
|
||||
\zwnj
|
||||
\zwj
|
||||
\lrm
|
||||
\rlm
|
||||
\smiley
|
||||
\blacksmile
|
||||
\sad
|
||||
\frowny
|
||||
\clubs
|
||||
\clubsuit
|
||||
\spades
|
||||
\spadesuit
|
||||
\hearts
|
||||
\heartsuit
|
||||
\diams
|
||||
\diamondsuit
|
||||
\diamond
|
||||
\Diamond
|
||||
\loz
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
\_
|
||||
@@ -1,3 +1,4 @@
|
||||
call_foo()
|
||||
call_foo(arguments)
|
||||
call_bar[header](arguments)
|
||||
call_baz(arguments)[header]
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
before src_foo{ipsum} after
|
||||
src_bar[lorem]{ipsum}
|
||||
src_foo{}
|
||||
before src_bar{lorem} after
|
||||
src_baz[ipsum]{dolar}
|
||||
|
||||
1
org_mode_samples/object/macro/capitalize.org
Normal file
1
org_mode_samples/object/macro/capitalize.org
Normal file
@@ -0,0 +1 @@
|
||||
{{{Foo(Bar,Baz)}}}
|
||||
7
org_mode_samples/object/macro/escape.org
Normal file
7
org_mode_samples/object/macro/escape.org
Normal file
@@ -0,0 +1,7 @@
|
||||
{{{foo}}}
|
||||
|
||||
{{{fo\o}}}
|
||||
|
||||
{{{foo(b\ar)}}}
|
||||
|
||||
{{{foo(b\,r)}}}
|
||||
10
org_mode_samples/object/macro/whitespace_in_args.org
Normal file
10
org_mode_samples/object/macro/whitespace_in_args.org
Normal file
@@ -0,0 +1,10 @@
|
||||
{{{foo(bar baz)}}}
|
||||
|
||||
{{{foo(bar
|
||||
baz)}}}
|
||||
|
||||
{{{foo(foo )}}}
|
||||
|
||||
{{{foo(foo , bar )}}}
|
||||
|
||||
{{{foo(foo , bar , baz )}}}
|
||||
@@ -1 +1,3 @@
|
||||
**foo**
|
||||
|
||||
foo ** bar ** baz
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__foo_bar_baz__
|
||||
1
org_mode_samples/object/text_markup/italic_bold.org
Normal file
1
org_mode_samples/object/text_markup/italic_bold.org
Normal file
@@ -0,0 +1 @@
|
||||
/*foo*/
|
||||
3
org_mode_samples/sections_and_headings/name.org
Normal file
3
org_mode_samples/sections_and_headings/name.org
Normal file
@@ -0,0 +1,3 @@
|
||||
#+NAME: foo
|
||||
* bar
|
||||
#+NAME: baz
|
||||
@@ -14,7 +14,12 @@ mod init_tracing;
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main_body()
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
let result = rt.block_on(async {
|
||||
let main_body_result = main_body().await;
|
||||
main_body_result
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
@@ -22,7 +27,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
let result = rt.block_on(async {
|
||||
init_telemetry()?;
|
||||
let main_body_result = main_body();
|
||||
let main_body_result = main_body().await;
|
||||
shutdown_telemetry()?;
|
||||
main_body_result
|
||||
});
|
||||
@@ -30,14 +35,21 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
async fn main_body() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args = std::env::args().skip(1);
|
||||
if args.is_empty() {
|
||||
let org_contents = read_stdin_to_string()?;
|
||||
run_anonymous_compare(org_contents)
|
||||
if run_anonymous_compare(org_contents).await? {
|
||||
} else {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
for arg in args {
|
||||
run_compare_on_file(arg)?
|
||||
if run_compare_on_file(arg).await? {
|
||||
} else {
|
||||
Err("Diff results do not match.")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
399
src/bin_foreign_document_test.rs
Normal file
399
src/bin_foreign_document_test.rs
Normal file
@@ -0,0 +1,399 @@
|
||||
#![feature(round_char_boundary)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::ExitCode;
|
||||
|
||||
use futures::future::BoxFuture;
|
||||
use futures::future::FutureExt;
|
||||
use organic::compare::silent_compare_on_file;
|
||||
use tokio::sync::Semaphore;
|
||||
use tokio::task::JoinError;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
use crate::init_tracing::init_telemetry;
|
||||
#[cfg(feature = "tracing")]
|
||||
use crate::init_tracing::shutdown_telemetry;
|
||||
#[cfg(feature = "tracing")]
|
||||
mod init_tracing;
|
||||
|
||||
#[cfg(not(feature = "tracing"))]
|
||||
fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
let result = rt.block_on(async {
|
||||
let main_body_result = main_body().await;
|
||||
main_body_result
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg(feature = "tracing")]
|
||||
fn main() -> Result<ExitCode, Box<dyn std::error::Error>> {
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
let result = rt.block_on(async {
|
||||
init_telemetry()?;
|
||||
let main_body_result = main_body().await;
|
||||
shutdown_telemetry()?;
|
||||
main_body_result
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
async fn main_body() -> Result<ExitCode, Box<dyn std::error::Error>> {
|
||||
let layer = compare_group("org-mode", || {
|
||||
compare_all_org_document("/foreign_documents/org-mode")
|
||||
});
|
||||
let layer = layer.chain(compare_group("emacs", || {
|
||||
compare_all_org_document("/foreign_documents/emacs")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("worg", || {
|
||||
compare_all_org_document("/foreign_documents/worg")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("howard_abrams", compare_howard_abrams));
|
||||
let layer = layer.chain(compare_group("doomemacs", || {
|
||||
compare_all_org_document("/foreign_documents/doomemacs")
|
||||
}));
|
||||
|
||||
let running_tests: Vec<_> = layer.map(|c| tokio::spawn(c.run_test())).collect();
|
||||
let mut any_failed = false;
|
||||
for test in running_tests.into_iter() {
|
||||
let test_result = test.await??;
|
||||
if test_result.is_immediately_bad() || test_result.has_bad_children() {
|
||||
any_failed = true;
|
||||
}
|
||||
test_result.print();
|
||||
}
|
||||
|
||||
if any_failed {
|
||||
println!(
|
||||
"{color}Some tests failed.{reset}",
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
);
|
||||
Ok(ExitCode::FAILURE)
|
||||
} else {
|
||||
println!(
|
||||
"{color}All tests passed.{reset}",
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
);
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
}
|
||||
|
||||
fn compare_howard_abrams() -> impl Iterator<Item = TestConfig> {
|
||||
let layer = compare_group("dot-files", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/dot-files")
|
||||
});
|
||||
let layer = layer.chain(compare_group("hamacs", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/hamacs")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("demo-it", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/demo-it")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("magit-demo", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/magit-demo")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("pdx-emacs-hackers", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/pdx-emacs-hackers")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("flora-simulator", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/flora-simulator")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("literate-devops-demo", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/literate-devops-demo")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("clojure-yesql-xp", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/clojure-yesql-xp")
|
||||
}));
|
||||
let layer = layer.chain(compare_group("veep", || {
|
||||
compare_all_org_document("/foreign_documents/howardabrams/veep")
|
||||
}));
|
||||
layer
|
||||
}
|
||||
|
||||
fn compare_group<N: Into<String>, F: Fn() -> I, I: Iterator<Item = TestConfig>>(
|
||||
name: N,
|
||||
inner: F,
|
||||
) -> impl Iterator<Item = TestConfig> {
|
||||
std::iter::once(TestConfig::TestLayer(TestLayer {
|
||||
name: name.into(),
|
||||
children: inner().collect(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn compare_all_org_document<P: AsRef<Path>>(root_dir: P) -> impl Iterator<Item = TestConfig> {
|
||||
let root_dir = root_dir.as_ref();
|
||||
let mut test_files = WalkDir::new(root_dir)
|
||||
.into_iter()
|
||||
.filter(|e| match e {
|
||||
Ok(dir_entry) => {
|
||||
dir_entry.file_type().is_file()
|
||||
&& Path::new(dir_entry.file_name())
|
||||
.extension()
|
||||
.map(|ext| ext.to_ascii_lowercase() == "org")
|
||||
.unwrap_or(false)
|
||||
}
|
||||
Err(_) => true,
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.unwrap();
|
||||
test_files.sort_by_cached_key(|test_file| PathBuf::from(test_file.path()));
|
||||
let test_configs: Vec<_> = test_files
|
||||
.into_iter()
|
||||
.map(|test_file| {
|
||||
let name = test_file
|
||||
.path()
|
||||
.strip_prefix(root_dir)
|
||||
.expect("Result is from walkdir so it must be below the root directory.")
|
||||
.as_os_str()
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
TestConfig::SingleFile(SingleFile {
|
||||
name,
|
||||
file_path: test_file.into_path(),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
test_configs.into_iter()
|
||||
}
|
||||
|
||||
static TEST_PERMITS: Semaphore = Semaphore::const_new(8);
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestConfig {
|
||||
TestLayer(TestLayer),
|
||||
SingleFile(SingleFile),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TestLayer {
|
||||
name: String,
|
||||
children: Vec<TestConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SingleFile {
|
||||
name: String,
|
||||
file_path: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestResult {
|
||||
ResultLayer(ResultLayer),
|
||||
SingleFileResult(SingleFileResult),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ResultLayer {
|
||||
name: String,
|
||||
children: Vec<TestResult>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SingleFileResult {
|
||||
name: String,
|
||||
file_path: PathBuf,
|
||||
status: TestStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum TestStatus {
|
||||
Pass,
|
||||
Fail,
|
||||
}
|
||||
|
||||
impl TestConfig {
|
||||
fn run_test(self) -> BoxFuture<'static, Result<TestResult, JoinError>> {
|
||||
async move {
|
||||
match self {
|
||||
TestConfig::TestLayer(test) => Ok(TestResult::ResultLayer(test.run_test().await?)),
|
||||
TestConfig::SingleFile(test) => {
|
||||
Ok(TestResult::SingleFileResult(test.run_test().await?))
|
||||
}
|
||||
}
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl SingleFile {
|
||||
async fn run_test(self) -> Result<SingleFileResult, JoinError> {
|
||||
let _permit = TEST_PERMITS.acquire().await.unwrap();
|
||||
let result = silent_compare_on_file(&self.file_path).await;
|
||||
Ok(SingleFileResult {
|
||||
name: self.name,
|
||||
file_path: self.file_path,
|
||||
status: if let Ok(true) = result {
|
||||
TestStatus::Pass
|
||||
} else {
|
||||
TestStatus::Fail
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TestLayer {
|
||||
async fn run_test(self) -> Result<ResultLayer, JoinError> {
|
||||
let running_children: Vec<_> = self
|
||||
.children
|
||||
.into_iter()
|
||||
.map(|c| tokio::spawn(c.run_test()))
|
||||
.collect();
|
||||
let mut children = Vec::with_capacity(running_children.len());
|
||||
for c in running_children {
|
||||
children.push(c.await??);
|
||||
}
|
||||
Ok(ResultLayer {
|
||||
name: self.name,
|
||||
children,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TestResult {
|
||||
pub fn print(&self) {
|
||||
self.print_indented(0);
|
||||
}
|
||||
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.print_indented(indentation),
|
||||
TestResult::SingleFileResult(result) => result.print_indented(indentation),
|
||||
}
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.has_bad_children(),
|
||||
TestResult::SingleFileResult(result) => result.has_bad_children(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
match self {
|
||||
TestResult::ResultLayer(result) => result.is_immediately_bad(),
|
||||
TestResult::SingleFileResult(result) => result.is_immediately_bad(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_color(red: u8, green: u8, blue: u8) -> String {
|
||||
if TestResult::should_use_color() {
|
||||
format!(
|
||||
"\x1b[38;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn background_color(red: u8, green: u8, blue: u8) -> String {
|
||||
if TestResult::should_use_color() {
|
||||
format!(
|
||||
"\x1b[48;2;{red};{green};{blue}m",
|
||||
red = red,
|
||||
green = green,
|
||||
blue = blue
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn reset_color() -> &'static str {
|
||||
if TestResult::should_use_color() {
|
||||
"\x1b[0m"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
fn should_use_color() -> bool {
|
||||
!std::env::var("NO_COLOR").is_ok_and(|val| !val.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl SingleFileResult {
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
match self.status {
|
||||
TestStatus::Pass => {
|
||||
println!(
|
||||
"{indentation}{color}PASS{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
TestStatus::Fail => {
|
||||
println!(
|
||||
"{indentation}{color}FAIL{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
match self.status {
|
||||
TestStatus::Pass => false,
|
||||
TestStatus::Fail => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResultLayer {
|
||||
fn print_indented(&self, indentation: usize) {
|
||||
if self.is_immediately_bad() {
|
||||
println!(
|
||||
"{indentation}{color}FAIL{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 0, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
} else if self.has_bad_children() {
|
||||
println!(
|
||||
"{indentation}{color}BADCHILD{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(255, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"{indentation}{color}PASS{reset} {name}",
|
||||
indentation = " ".repeat(indentation),
|
||||
color = TestResult::foreground_color(0, 255, 0),
|
||||
reset = TestResult::reset_color(),
|
||||
name = self.name
|
||||
);
|
||||
}
|
||||
self.children
|
||||
.iter()
|
||||
.for_each(|result| result.print_indented(indentation + 1));
|
||||
}
|
||||
|
||||
fn has_bad_children(&self) -> bool {
|
||||
self.children
|
||||
.iter()
|
||||
.any(|result| result.is_immediately_bad() || result.has_bad_children())
|
||||
}
|
||||
|
||||
fn is_immediately_bad(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -12,39 +12,60 @@ use crate::context::LocalFileAccessInterface;
|
||||
use crate::parser::parse_file_with_settings;
|
||||
use crate::parser::parse_with_settings;
|
||||
|
||||
pub fn run_anonymous_compare<P: AsRef<str>>(
|
||||
pub async fn run_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default())
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), false).await
|
||||
}
|
||||
|
||||
pub fn run_compare_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default())
|
||||
pub async fn run_compare_on_file<P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), false).await
|
||||
}
|
||||
|
||||
pub fn run_anonymous_compare_with_settings<P: AsRef<str>>(
|
||||
pub async fn silent_anonymous_compare<P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
global_settings: &GlobalSettings,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_anonymous_compare_with_settings(org_contents, &GlobalSettings::default(), true).await
|
||||
}
|
||||
|
||||
pub async fn silent_compare_on_file<P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
run_compare_on_file_with_settings(org_path, &GlobalSettings::default(), true).await
|
||||
}
|
||||
|
||||
pub async fn run_anonymous_compare_with_settings<'g, 's, P: AsRef<str>>(
|
||||
org_contents: P,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
silent: bool,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
// TODO: This is a work-around to pretend that dos line endings do not exist. It would be better to handle the difference in line endings.
|
||||
let org_contents = org_contents.as_ref().replace("\r\n", "\n");
|
||||
let org_contents = org_contents.as_str();
|
||||
print_versions()?;
|
||||
if !silent {
|
||||
print_versions().await?;
|
||||
}
|
||||
let rust_parsed = parse_with_settings(org_contents, global_settings)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings)?;
|
||||
let org_sexp = emacs_parse_anonymous_org_document(org_contents, global_settings).await?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
if !silent {
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
}
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
if !silent {
|
||||
diff_result.print(org_contents)?;
|
||||
}
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
} else {
|
||||
return Ok(false);
|
||||
} else if !silent {
|
||||
println!(
|
||||
"{color}Entire document passes.{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
@@ -52,15 +73,18 @@ pub fn run_anonymous_compare_with_settings<P: AsRef<str>>(
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
|
||||
pub async fn run_compare_on_file_with_settings<'g, 's, P: AsRef<Path>>(
|
||||
org_path: P,
|
||||
global_settings: &GlobalSettings,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
silent: bool,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let org_path = org_path.as_ref();
|
||||
print_versions()?;
|
||||
if !silent {
|
||||
print_versions().await?;
|
||||
}
|
||||
let parent_directory = org_path
|
||||
.parent()
|
||||
.ok_or("Should be contained inside a directory.")?;
|
||||
@@ -77,20 +101,24 @@ pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
|
||||
global_settings
|
||||
};
|
||||
let rust_parsed = parse_file_with_settings(org_contents, &global_settings, Some(org_path))?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path, &global_settings)?;
|
||||
let org_sexp = emacs_parse_file_org_document(org_path, &global_settings).await?;
|
||||
let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
|
||||
|
||||
if !silent {
|
||||
println!("{}\n\n\n", org_contents);
|
||||
println!("{}", org_sexp);
|
||||
println!("{:#?}", rust_parsed);
|
||||
}
|
||||
|
||||
// We do the diffing after printing out both parsed forms in case the diffing panics
|
||||
let diff_result = compare_document(&parsed_sexp, &rust_parsed)?;
|
||||
if !silent {
|
||||
diff_result.print(org_contents)?;
|
||||
}
|
||||
|
||||
if diff_result.is_bad() {
|
||||
Err("Diff results do not match.")?;
|
||||
} else {
|
||||
return Ok(false);
|
||||
} else if !silent {
|
||||
println!(
|
||||
"{color}Entire document passes.{reset}",
|
||||
color = DiffResult::foreground_color(0, 255, 0),
|
||||
@@ -98,11 +126,14 @@ pub fn run_compare_on_file_with_settings<P: AsRef<Path>>(
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
eprintln!("Using emacs version: {}", get_emacs_version()?.trim());
|
||||
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
|
||||
async fn print_versions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
eprintln!("Using emacs version: {}", get_emacs_version().await?.trim());
|
||||
eprintln!(
|
||||
"Using org-mode version: {}",
|
||||
get_org_mode_version().await?.trim()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,35 +1,75 @@
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::diff::artificial_diff_scope;
|
||||
use super::diff::artificial_owned_diff_scope;
|
||||
use super::diff::compare_ast_node;
|
||||
use super::diff::DiffEntry;
|
||||
use super::diff::DiffStatus;
|
||||
use super::sexp::unquote;
|
||||
use super::sexp::Token;
|
||||
use super::util::get_property;
|
||||
use super::util::get_property_numeric;
|
||||
use super::util::get_property_quoted_string;
|
||||
use super::util::get_property_unquoted_atom;
|
||||
use crate::types::AstNode;
|
||||
use crate::types::CharOffsetInLine;
|
||||
use crate::types::LineNumber;
|
||||
use crate::types::Object;
|
||||
use crate::types::RetainLabels;
|
||||
use crate::types::SwitchNumberLines;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum EmacsField<'s> {
|
||||
Required(&'s str),
|
||||
#[allow(dead_code)]
|
||||
Optional(&'s str),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ComparePropertiesResult<'b, 's> {
|
||||
NoChange,
|
||||
/// Return when you want the status for "this" node to change (as opposed to collecting child status).
|
||||
SelfChange(DiffStatus, Option<String>),
|
||||
DiffEntry(DiffEntry<'b, 's>),
|
||||
}
|
||||
|
||||
impl<'b, 's> ComparePropertiesResult<'b, 's> {
|
||||
pub(crate) fn apply(
|
||||
self,
|
||||
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
||||
this_status: &mut DiffStatus,
|
||||
message: &mut Option<String>,
|
||||
) {
|
||||
match self {
|
||||
ComparePropertiesResult::NoChange => {}
|
||||
ComparePropertiesResult::SelfChange(new_status, new_message) => {
|
||||
*this_status = new_status;
|
||||
*message = new_message
|
||||
}
|
||||
ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry),
|
||||
}
|
||||
|
||||
// foo
|
||||
}
|
||||
}
|
||||
|
||||
/// Do no comparison.
|
||||
///
|
||||
/// This is for when you want to acknowledge that a field exists in the emacs token, but you do not have any validation for it when using the compare_properties!() macro. Ideally, this should be kept to a minimum since this represents untested values.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn compare_noop<'b, 's, 'x, R, RG>(
|
||||
_source: &'s str,
|
||||
_emacs: &'b Token<'s>,
|
||||
_rust_node: R,
|
||||
_emacs_field: &'x str,
|
||||
_rust_value_getter: RG,
|
||||
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
|
||||
Ok(None)
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
/// Do no comparison.
|
||||
///
|
||||
/// This is for when you want to acknowledge that a field exists in the emacs token, but you do not have any validation for it when using the compare_properties!() macro. Ideally, this should be kept to a minimum since this represents untested values.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn compare_identity() -> () {
|
||||
()
|
||||
}
|
||||
@@ -38,11 +78,12 @@ pub(crate) fn compare_identity() -> () {
|
||||
///
|
||||
/// This is usually used for fields which, in my testing, are always nil. Using this compare function instead of simply doing a compare_noop will enable us to be alerted when we finally come across an org-mode document that has a value other than nil for the property.
|
||||
pub(crate) fn compare_property_always_nil<'b, 's, 'x, R, RG>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
_rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
_rust_value_getter: RG,
|
||||
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?;
|
||||
if value.is_some() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
@@ -50,9 +91,9 @@ pub(crate) fn compare_property_always_nil<'b, 's, 'x, R, RG>(
|
||||
"{} was expected to always be nil: {:?}",
|
||||
emacs_field, value
|
||||
));
|
||||
Ok(Some((this_status, message)))
|
||||
Ok(ComparePropertiesResult::SelfChange(this_status, message))
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +105,12 @@ pub(crate) fn compare_property_quoted_string<
|
||||
RV: AsRef<str> + std::fmt::Debug,
|
||||
RG: Fn(R) -> Option<RV>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property_quoted_string(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
if rust_value.as_ref().map(|s| s.as_ref()) != value.as_ref().map(String::as_str) {
|
||||
@@ -77,18 +119,19 @@ pub(crate) fn compare_property_quoted_string<
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
Ok(Some((this_status, message)))
|
||||
Ok(ComparePropertiesResult::SelfChange(this_status, message))
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_unquoted_atom<'b, 's, 'x, R, RG: Fn(R) -> Option<&'s str>>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property_unquoted_atom(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
if rust_value != value {
|
||||
@@ -97,8 +140,506 @@ pub(crate) fn compare_property_unquoted_atom<'b, 's, 'x, R, RG: Fn(R) -> Option<
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
Ok(Some((this_status, message)))
|
||||
Ok(ComparePropertiesResult::SelfChange(this_status, message))
|
||||
} else {
|
||||
Ok(None)
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_numeric<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: FromStr + PartialEq + Debug,
|
||||
RG: Fn(R) -> Option<RV>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error + 's>>
|
||||
where
|
||||
<RV as FromStr>::Err: std::error::Error,
|
||||
<RV as FromStr>::Err: 's,
|
||||
{
|
||||
let value = get_property_numeric::<RV>(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
if rust_value != value {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
Ok(ComparePropertiesResult::SelfChange(this_status, message))
|
||||
} else {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_list_of_quoted_string<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: AsRef<str> + std::fmt::Debug,
|
||||
RI: Iterator<Item = RV>,
|
||||
RG: Fn(R) -> Option<RI>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
// TODO: Seems we are needlessly coverting to a vec here.
|
||||
let rust_value: Option<Vec<RV>> = rust_value.map(|it| it.collect());
|
||||
match (value, &rust_value) {
|
||||
(None, None) => {}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) if el.len() != rl.len() => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) => {
|
||||
for (e, r) in el.iter().zip(rl) {
|
||||
let e = unquote(e.as_atom()?)?;
|
||||
let r = r.as_ref();
|
||||
if e != r {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}",
|
||||
emacs_field, e, r, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_set_of_quoted_string<
|
||||
'a,
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RV: AsRef<str> + std::fmt::Debug + Ord + 'a + ?Sized,
|
||||
RI: Iterator<Item = &'a RV>,
|
||||
RG: Fn(R) -> Option<RI>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let empty = Vec::new();
|
||||
let value = value.unwrap_or(&empty);
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
let rust_value = if let Some(rust_value) = rust_value {
|
||||
let slices: BTreeSet<&str> = rust_value.map(|rv| rv.as_ref()).collect();
|
||||
slices
|
||||
} else {
|
||||
BTreeSet::new()
|
||||
};
|
||||
let value: Vec<&str> = value
|
||||
.iter()
|
||||
.map(|e| e.as_atom())
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let value: Vec<String> = value
|
||||
.into_iter()
|
||||
.map(unquote)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let value: BTreeSet<&str> = value.iter().map(|e| e.as_str()).collect();
|
||||
let mismatched: Vec<_> = value
|
||||
.symmetric_difference(&rust_value)
|
||||
.map(|val| *val)
|
||||
.collect();
|
||||
if !mismatched.is_empty() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch. Mismatched values: {}",
|
||||
emacs_field,
|
||||
mismatched.join(", ")
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_boolean<'b, 's, 'x, R, RG: Fn(R) -> bool>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
// get_property already converts nil to None.
|
||||
let value = get_property(emacs, emacs_field)?.is_some();
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
if rust_value != value {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
Ok(ComparePropertiesResult::SelfChange(this_status, message))
|
||||
} else {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_single_ast_node<
|
||||
'b,
|
||||
's,
|
||||
'x: 'b + 's,
|
||||
R,
|
||||
RV: std::fmt::Debug,
|
||||
RG: Fn(R) -> Option<RV>,
|
||||
>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>>
|
||||
where
|
||||
AstNode<'b, 's>: From<RV>,
|
||||
{
|
||||
let value = get_property(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
match (value, rust_value) {
|
||||
(None, None) => {}
|
||||
(None, rv @ Some(_)) | (Some(_), rv @ None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rv
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(ev), Some(rv)) => {
|
||||
let child_status: Vec<DiffEntry<'b, 's>> =
|
||||
vec![compare_ast_node(source, ev, rv.into())?];
|
||||
let diff_scope = artificial_diff_scope(emacs_field, child_status)?;
|
||||
return Ok(ComparePropertiesResult::DiffEntry(diff_scope));
|
||||
}
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_list_of_ast_nodes<
|
||||
'b,
|
||||
's,
|
||||
'x: 'b + 's,
|
||||
R,
|
||||
RV: std::fmt::Debug,
|
||||
RI: Iterator<Item = RV>,
|
||||
RG: Fn(R) -> Option<RI>,
|
||||
>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>>
|
||||
where
|
||||
AstNode<'b, 's>: From<RV>,
|
||||
{
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
// TODO: Seems we are needlessly coverting to a vec here.
|
||||
let rust_value: Option<Vec<RV>> = rust_value.map(|it| it.collect());
|
||||
match (value, rust_value) {
|
||||
(None, None) => {}
|
||||
(Some(el), None)
|
||||
if el.len() == 1
|
||||
&& el.into_iter().all(|t| {
|
||||
if let Ok(r#""""#) = t.as_atom() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) => {}
|
||||
(None, rv @ Some(_)) | (Some(_), rv @ None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rv
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) if el.len() != rl.len() => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, el, rl
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(el), Some(rl)) => {
|
||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rl.len());
|
||||
for (e, r) in el.iter().zip(rl) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
let diff_scope = artificial_diff_scope(emacs_field, child_status)?;
|
||||
return Ok(ComparePropertiesResult::DiffEntry(diff_scope));
|
||||
}
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
/// Special compare used for affiliate keywords that are parsed as objects.
|
||||
///
|
||||
/// Org-mode seems to store these as a 3-deep list:
|
||||
/// - Outer list with 1 element per #+caption keyword (or other parsed keyword).
|
||||
/// - Middle list which has:
|
||||
/// - first element is a list of objects representing the value after the colon.
|
||||
/// - every additional element is a list of objects from inside the square brackets (the optional value).
|
||||
pub(crate) fn compare_property_list_of_list_of_list_of_ast_nodes<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
R,
|
||||
RG: Fn(R) -> Option<&'b Vec<(Option<Vec<Object<'s>>>, Vec<Object<'s>>)>>,
|
||||
>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
// TODO: Replace Object<'s> with generics. I hard-coded Object in to make lifetimes easier.
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
let value = get_property(emacs, emacs_field)?
|
||||
.map(Token::as_list)
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
let (value, rust_value) = match (value, rust_value) {
|
||||
(None, None) => {
|
||||
return Ok(ComparePropertiesResult::NoChange);
|
||||
}
|
||||
(None, Some(_)) | (Some(_), None) => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(value), Some(rust_value)) if value.len() != rust_value.len() => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
(Some(value), Some(rust_value)) => (value, rust_value),
|
||||
};
|
||||
|
||||
let mut full_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
||||
|
||||
// Iterate the outer lists
|
||||
for (value, (rust_optional, rust_value)) in value.iter().zip(rust_value.iter()) {
|
||||
let mut middle_value = value.as_list()?.iter();
|
||||
// First element of middle list is the mandatory value (the value past the colon).
|
||||
let mandatory_value = middle_value.next();
|
||||
let mandatory_value = match mandatory_value {
|
||||
Some(mandatory_value) => mandatory_value,
|
||||
None => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
};
|
||||
|
||||
// Compare optional value
|
||||
if let Some(rust_optional) = rust_optional {
|
||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
||||
if rust_optional.len() != middle_value.len() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} optional value length mismatch (emacs != rust) {} != {} | {:?}",
|
||||
emacs_field,
|
||||
middle_value.len(),
|
||||
rust_optional.len(),
|
||||
rust_optional
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
for (e, r) in middle_value.zip(rust_optional) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
if !child_status.is_empty() {
|
||||
let diff_scope = artificial_diff_scope("optional value", child_status)?;
|
||||
full_status.push(diff_scope);
|
||||
}
|
||||
}
|
||||
|
||||
// Compare mandatory value
|
||||
let mut child_status: Vec<DiffEntry<'b, 's>> = Vec::with_capacity(rust_value.len());
|
||||
let mandatory_value = mandatory_value.as_list()?;
|
||||
if rust_value.len() != mandatory_value.len() {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mandatory value length mismatch (emacs != rust) {} != {} | {:?}",
|
||||
emacs_field,
|
||||
mandatory_value.len(),
|
||||
rust_value.len(),
|
||||
rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
for (e, r) in mandatory_value.iter().zip(rust_value) {
|
||||
child_status.push(compare_ast_node(source, e, r.into())?);
|
||||
}
|
||||
if !child_status.is_empty() {
|
||||
let diff_scope = artificial_diff_scope("mandatory value", child_status)?;
|
||||
full_status.push(diff_scope);
|
||||
}
|
||||
}
|
||||
if full_status.is_empty() {
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
} else {
|
||||
let diff_scope = artificial_owned_diff_scope(emacs_field, full_status)?;
|
||||
Ok(ComparePropertiesResult::DiffEntry(diff_scope))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_number_lines<
|
||||
'b,
|
||||
's,
|
||||
'x,
|
||||
'y,
|
||||
R,
|
||||
RG: Fn(R) -> Option<&'y SwitchNumberLines>,
|
||||
>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>> {
|
||||
let number_lines = get_property(emacs, emacs_field)?;
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
match (number_lines, &rust_value) {
|
||||
(None, None) => {}
|
||||
(Some(number_lines), Some(rust_number_lines)) => {
|
||||
let token_list = number_lines.as_list()?;
|
||||
let number_type = token_list
|
||||
.get(0)
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.ok_or(":number-lines should have a type.")?;
|
||||
let number_value = token_list
|
||||
.get(2)
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.map(|val| val.parse::<LineNumber>())
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.ok_or(":number-lines should have a value.")?;
|
||||
match (number_type, number_value, rust_number_lines) {
|
||||
("new", emacs_val, SwitchNumberLines::New(rust_val)) if emacs_val == *rust_val => {}
|
||||
("continued", emacs_val, SwitchNumberLines::Continued(rust_val))
|
||||
if emacs_val == *rust_val => {}
|
||||
_ => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, number_lines, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, number_lines, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_property_retain_labels<'b, 's, 'x, 'y, R, RG: Fn(R) -> &'y RetainLabels>(
|
||||
_source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_node: R,
|
||||
emacs_field: &'x str,
|
||||
rust_value_getter: RG,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error + 's>> {
|
||||
let rust_value = rust_value_getter(rust_node);
|
||||
let retain_labels = get_property_unquoted_atom(emacs, ":retain-labels")?;
|
||||
if let Some(retain_labels) = retain_labels {
|
||||
if retain_labels == "t" {
|
||||
match rust_value {
|
||||
RetainLabels::Yes => {}
|
||||
_ => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, retain_labels, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let retain_labels: CharOffsetInLine = get_property_numeric(emacs, ":retain-labels")?.expect("Cannot be None or else the earlier get_property_unquoted_atom would have been None.");
|
||||
match (retain_labels, rust_value) {
|
||||
(e, RetainLabels::Keep(r)) if e == *r => {}
|
||||
_ => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, retain_labels, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match rust_value {
|
||||
RetainLabels::No => {}
|
||||
_ => {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_field, retain_labels, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
3717
src/compare/diff.rs
3717
src/compare/diff.rs
File diff suppressed because it is too large
Load Diff
@@ -30,10 +30,9 @@
|
||||
/// }
|
||||
/// ```
|
||||
macro_rules! compare_properties {
|
||||
($emacs:expr, $rust:expr, $(($emacs_field:expr, $rust_value_getter:expr, $compare_fn: expr)),+) => {
|
||||
($source:expr, $emacs:expr, $rust:expr, $(($emacs_field:expr, $rust_value_getter:expr, $compare_fn: expr)),*) => {
|
||||
{
|
||||
let mut this_status = DiffStatus::Good;
|
||||
let mut message: Option<String> = None;
|
||||
let mut new_status = Vec::new();
|
||||
let children = $emacs.as_list()?;
|
||||
let attributes_child = children
|
||||
.iter()
|
||||
@@ -44,10 +43,9 @@ macro_rules! compare_properties {
|
||||
if emacs_keys.contains(":standard-properties") {
|
||||
emacs_keys.remove(":standard-properties");
|
||||
} else {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks :standard-properties field.",
|
||||
));
|
||||
))));
|
||||
}
|
||||
$(
|
||||
match $emacs_field {
|
||||
@@ -58,24 +56,22 @@ macro_rules! compare_properties {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Required(name) => {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks required field: {}",
|
||||
name
|
||||
));
|
||||
))));
|
||||
},
|
||||
EmacsField::Optional(_name) => {},
|
||||
}
|
||||
)+
|
||||
)*
|
||||
|
||||
if !emacs_keys.is_empty() {
|
||||
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
|
||||
let unexpected_keys = unexpected_keys.join(", ");
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token had extra field(s): {}",
|
||||
unexpected_keys
|
||||
));
|
||||
))));
|
||||
}
|
||||
|
||||
$(
|
||||
@@ -87,33 +83,23 @@ macro_rules! compare_properties {
|
||||
name
|
||||
},
|
||||
};
|
||||
let result = $compare_fn($emacs, $rust, emacs_name, $rust_value_getter)?;
|
||||
let result = $compare_fn($source, $emacs, $rust, emacs_name, $rust_value_getter)?;
|
||||
match result {
|
||||
Some((DiffStatus::Good, _)) => unreachable!("No comparison functions should return Some() when DiffStatus is good."),
|
||||
Some((status, msg)) => {
|
||||
this_status = status;
|
||||
message = msg;
|
||||
},
|
||||
_ => {}
|
||||
ComparePropertiesResult::SelfChange(DiffStatus::Good, _) => unreachable!("No comparison functions should return SelfChange() when DiffStatus is good."),
|
||||
ComparePropertiesResult::NoChange => {},
|
||||
result => {
|
||||
new_status.push(result);
|
||||
}
|
||||
)+
|
||||
}
|
||||
)*
|
||||
|
||||
match this_status {
|
||||
DiffStatus::Good => {
|
||||
let result: Result<_, Box<dyn std::error::Error>> = Ok(None);
|
||||
result
|
||||
},
|
||||
_ => {
|
||||
Ok(Some((this_status, message)))
|
||||
}
|
||||
}
|
||||
new_status
|
||||
}
|
||||
};
|
||||
// Default case for when there are no expected properties except for :standard-properties
|
||||
($emacs:expr) => {
|
||||
// For elements with affiliated keywords
|
||||
($source:expr, $emacs:expr, $rust:expr, [], $(($emacs_field:expr, $rust_value_getter:expr, $compare_fn: expr)),*) => {
|
||||
{
|
||||
let mut this_status = DiffStatus::Good;
|
||||
let mut message: Option<String> = None;
|
||||
let mut new_status = Vec::new();
|
||||
let children = $emacs.as_list()?;
|
||||
let attributes_child = children
|
||||
.iter()
|
||||
@@ -124,30 +110,193 @@ macro_rules! compare_properties {
|
||||
if emacs_keys.contains(":standard-properties") {
|
||||
emacs_keys.remove(":standard-properties");
|
||||
} else {
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks :standard-properties field.",
|
||||
));
|
||||
))));
|
||||
}
|
||||
let affiliated_keywords_names: Vec<String> = affiliated_keywords_names($rust).collect();
|
||||
for additional_field in affiliated_keywords_names.iter().map(String::as_str).map(EmacsField::Required) {
|
||||
match additional_field {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Required(name) => {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks required field: {}",
|
||||
name
|
||||
))));
|
||||
},
|
||||
EmacsField::Optional(_name) => {},
|
||||
}
|
||||
}
|
||||
$(
|
||||
match $emacs_field {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Required(name) => {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks required field: {}",
|
||||
name
|
||||
))));
|
||||
},
|
||||
EmacsField::Optional(_name) => {},
|
||||
}
|
||||
)*
|
||||
|
||||
if !emacs_keys.is_empty() {
|
||||
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
|
||||
let unexpected_keys = unexpected_keys.join(", ");
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token had extra field(s): {}",
|
||||
unexpected_keys
|
||||
))));
|
||||
}
|
||||
|
||||
for diff in compare_affiliated_keywords($source, $emacs, $rust)? {
|
||||
new_status.push(diff);
|
||||
}
|
||||
|
||||
$(
|
||||
let emacs_name = match $emacs_field {
|
||||
EmacsField::Required(name) => {
|
||||
name
|
||||
},
|
||||
EmacsField::Optional(name) => {
|
||||
name
|
||||
},
|
||||
};
|
||||
let result = $compare_fn($source, $emacs, $rust, emacs_name, $rust_value_getter)?;
|
||||
match result {
|
||||
ComparePropertiesResult::SelfChange(DiffStatus::Good, _) => unreachable!("No comparison functions should return SelfChange() when DiffStatus is good."),
|
||||
ComparePropertiesResult::NoChange => {},
|
||||
result => {
|
||||
new_status.push(result);
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
new_status
|
||||
}
|
||||
};
|
||||
// Specifies additional properties
|
||||
($source:expr, $emacs:expr, $rust:expr, $additionalproperties: expr, $(($emacs_field:expr, $rust_value_getter:expr, $compare_fn: expr)),*) => {
|
||||
{
|
||||
let mut new_status = Vec::new();
|
||||
let children = $emacs.as_list()?;
|
||||
let attributes_child = children
|
||||
.iter()
|
||||
.nth(1)
|
||||
.ok_or("Should have an attributes child.")?;
|
||||
let attributes_map = attributes_child.as_map()?;
|
||||
let mut emacs_keys: BTreeSet<&str> = attributes_map.keys().map(|s| *s).collect();
|
||||
if emacs_keys.contains(":standard-properties") {
|
||||
emacs_keys.remove(":standard-properties");
|
||||
} else {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks :standard-properties field.",
|
||||
))));
|
||||
}
|
||||
for additional_field in $additionalproperties {
|
||||
match additional_field {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Required(name) => {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks required field: {}",
|
||||
name
|
||||
))));
|
||||
},
|
||||
EmacsField::Optional(_name) => {},
|
||||
}
|
||||
}
|
||||
$(
|
||||
match $emacs_field {
|
||||
EmacsField::Required(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Optional(name) if emacs_keys.contains(name) => {
|
||||
emacs_keys.remove(name);
|
||||
},
|
||||
EmacsField::Required(name) => {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks required field: {}",
|
||||
name
|
||||
))));
|
||||
},
|
||||
EmacsField::Optional(_name) => {},
|
||||
}
|
||||
)*
|
||||
|
||||
if !emacs_keys.is_empty() {
|
||||
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
|
||||
let unexpected_keys = unexpected_keys.join(", ");
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token had extra field(s): {}",
|
||||
unexpected_keys
|
||||
))));
|
||||
}
|
||||
|
||||
$(
|
||||
let emacs_name = match $emacs_field {
|
||||
EmacsField::Required(name) => {
|
||||
name
|
||||
},
|
||||
EmacsField::Optional(name) => {
|
||||
name
|
||||
},
|
||||
};
|
||||
let result = $compare_fn($source, $emacs, $rust, emacs_name, $rust_value_getter)?;
|
||||
match result {
|
||||
ComparePropertiesResult::SelfChange(DiffStatus::Good, _) => unreachable!("No comparison functions should return SelfChange() when DiffStatus is good."),
|
||||
ComparePropertiesResult::NoChange => {},
|
||||
result => {
|
||||
new_status.push(result);
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
new_status
|
||||
}
|
||||
};
|
||||
// Default case for when there are no expected properties except for :standard-properties
|
||||
($emacs:expr) => {
|
||||
{
|
||||
let mut new_status = Vec::new();
|
||||
let children = $emacs.as_list()?;
|
||||
let attributes_child = children
|
||||
.iter()
|
||||
.nth(1)
|
||||
.ok_or("Should have an attributes child.")?;
|
||||
let attributes_map = attributes_child.as_map()?;
|
||||
let mut emacs_keys: BTreeSet<&str> = attributes_map.keys().map(|s| *s).collect();
|
||||
if emacs_keys.contains(":standard-properties") {
|
||||
emacs_keys.remove(":standard-properties");
|
||||
} else {
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token lacks :standard-properties field.",
|
||||
))));
|
||||
}
|
||||
|
||||
if !emacs_keys.is_empty() {
|
||||
let unexpected_keys: Vec<&str> = emacs_keys.into_iter().collect();
|
||||
let unexpected_keys = unexpected_keys.join(", ");
|
||||
this_status = DiffStatus::Bad;
|
||||
message = Some(format!(
|
||||
new_status.push(ComparePropertiesResult::SelfChange(DiffStatus::Bad, Some(format!(
|
||||
"Emacs token had extra field(s): {}",
|
||||
unexpected_keys
|
||||
));
|
||||
}
|
||||
match this_status {
|
||||
DiffStatus::Good => {
|
||||
let result: Result<_, Box<dyn std::error::Error>> = Ok(None);
|
||||
result
|
||||
},
|
||||
_ => {
|
||||
Ok(Some((this_status, message)))
|
||||
}
|
||||
))));
|
||||
}
|
||||
new_status
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,3 +10,5 @@ pub use compare::run_anonymous_compare;
|
||||
pub use compare::run_anonymous_compare_with_settings;
|
||||
pub use compare::run_compare_on_file;
|
||||
pub use compare::run_compare_on_file_with_settings;
|
||||
pub use compare::silent_anonymous_compare;
|
||||
pub use compare::silent_compare_on_file;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::context::HeadlineLevelFilter;
|
||||
use crate::settings::GlobalSettings;
|
||||
@@ -25,9 +26,9 @@ fn global_settings_elisp(global_settings: &GlobalSettings) -> String {
|
||||
ret
|
||||
}
|
||||
|
||||
pub(crate) fn emacs_parse_anonymous_org_document<C>(
|
||||
pub(crate) async fn emacs_parse_anonymous_org_document<'g, 's, C>(
|
||||
file_contents: C,
|
||||
global_settings: &GlobalSettings,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
C: AsRef<str>,
|
||||
@@ -54,15 +55,24 @@ where
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output()?;
|
||||
out.status.exit_ok()?;
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
|
||||
pub(crate) fn emacs_parse_file_org_document<P>(
|
||||
pub(crate) async fn emacs_parse_file_org_document<'g, 's, P>(
|
||||
file_path: P,
|
||||
global_settings: &GlobalSettings,
|
||||
global_settings: &GlobalSettings<'g, 's>,
|
||||
) -> Result<String, Box<dyn std::error::Error>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
@@ -97,8 +107,17 @@ where
|
||||
.arg("--batch")
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
let out = cmd.output()?;
|
||||
out.status.exit_ok()?;
|
||||
let out = cmd.output().await?;
|
||||
let status = out.status.exit_ok();
|
||||
if status.is_err() {
|
||||
eprintln!(
|
||||
"Emacs errored out: {}\n{}",
|
||||
String::from_utf8(out.stdout)?,
|
||||
String::from_utf8(out.stderr)?
|
||||
);
|
||||
status?;
|
||||
unreachable!();
|
||||
}
|
||||
let org_sexp = out.stderr;
|
||||
Ok(String::from_utf8(org_sexp)?)
|
||||
}
|
||||
@@ -125,7 +144,7 @@ where
|
||||
output
|
||||
}
|
||||
|
||||
pub fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
pub async fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let elisp_script = r#"(progn
|
||||
(message "%s" (version))
|
||||
)"#;
|
||||
@@ -138,12 +157,12 @@ pub fn get_emacs_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output()?;
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
pub fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
pub async fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let elisp_script = r#"(progn
|
||||
(org-mode)
|
||||
(message "%s" (org-version nil t nil))
|
||||
@@ -157,7 +176,7 @@ pub fn get_org_mode_version() -> Result<String, Box<dyn std::error::Error>> {
|
||||
.arg("--eval")
|
||||
.arg(elisp_script);
|
||||
|
||||
let out = cmd.output()?;
|
||||
let out = cmd.output().await?;
|
||||
out.status.exit_ok()?;
|
||||
Ok(String::from_utf8(out.stderr)?)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::compare_field::compare_property_list_of_list_of_list_of_ast_nodes;
|
||||
use super::compare_field::compare_property_list_of_quoted_string;
|
||||
use super::compare_field::compare_property_quoted_string;
|
||||
use super::compare_field::ComparePropertiesResult;
|
||||
use super::diff::DiffEntry;
|
||||
use super::diff::DiffStatus;
|
||||
use super::elisp_fact::GetElispFact;
|
||||
use super::sexp::Token;
|
||||
use crate::compare::diff::compare_ast_node;
|
||||
use crate::compare::sexp::unquote;
|
||||
use crate::types::AffiliatedKeywordValue;
|
||||
use crate::types::AstNode;
|
||||
use crate::types::GetAffiliatedKeywords;
|
||||
use crate::types::GetStandardProperties;
|
||||
use crate::types::StandardProperties;
|
||||
|
||||
@@ -217,22 +227,6 @@ pub(crate) fn get_property_quoted_string<'b, 's, 'x>(
|
||||
.map_or(Ok(None), |r| r.map(Some))?)
|
||||
}
|
||||
|
||||
/// Get a named property containing a boolean value.
|
||||
///
|
||||
/// This uses the elisp convention of nil == false, non-nil == true.
|
||||
///
|
||||
/// Returns false if key is not found.
|
||||
pub(crate) fn get_property_boolean<'b, 's, 'x>(
|
||||
emacs: &'b Token<'s>,
|
||||
key: &'x str,
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
Ok(get_property(emacs, key)?
|
||||
.map(Token::as_atom)
|
||||
.map_or(Ok(None), |r| r.map(Some))?
|
||||
.unwrap_or("nil")
|
||||
!= "nil")
|
||||
}
|
||||
|
||||
/// Get a named property containing an unquoted numeric value.
|
||||
///
|
||||
/// Returns None if key is not found.
|
||||
@@ -252,3 +246,157 @@ where
|
||||
.map_or(Ok(None), |r| r.map(Some))?;
|
||||
Ok(parsed_number)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_children<'b, 's, 'x, RC>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_children: &'x Vec<RC>,
|
||||
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
||||
this_status: &mut DiffStatus,
|
||||
message: &mut Option<String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>>
|
||||
where
|
||||
AstNode<'b, 's>: From<&'x RC>,
|
||||
{
|
||||
let emacs_children = emacs.as_list()?;
|
||||
let emacs_children_length = emacs_children.len() - 2;
|
||||
if emacs_children_length != rust_children.len() {
|
||||
*this_status = DiffStatus::Bad;
|
||||
*message = Some(format!(
|
||||
"Child length mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_children_length,
|
||||
rust_children.len()
|
||||
));
|
||||
}
|
||||
for (emacs_child, rust_child) in emacs_children.iter().skip(2).zip(rust_children.iter()) {
|
||||
child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn compare_children_iter<'b, 's, RC, RI: Iterator<Item = RC> + ExactSizeIterator>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust_children: RI,
|
||||
child_status: &mut Vec<DiffEntry<'b, 's>>,
|
||||
this_status: &mut DiffStatus,
|
||||
message: &mut Option<String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>>
|
||||
where
|
||||
AstNode<'b, 's>: From<RC>,
|
||||
{
|
||||
let emacs_children = emacs.as_list()?;
|
||||
let emacs_children_length = emacs_children.len() - 2;
|
||||
if emacs_children_length != rust_children.len() {
|
||||
*this_status = DiffStatus::Bad;
|
||||
*message = Some(format!(
|
||||
"Child length mismatch (emacs != rust) {:?} != {:?}",
|
||||
emacs_children_length,
|
||||
rust_children.len()
|
||||
));
|
||||
}
|
||||
for (emacs_child, rust_child) in emacs_children.iter().skip(2).zip(rust_children) {
|
||||
child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn assert_no_children<'b, 's>(
|
||||
emacs: &'b Token<'s>,
|
||||
this_status: &mut DiffStatus,
|
||||
message: &mut Option<String>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let emacs_children_length = emacs.as_list()?.len();
|
||||
// 2, one for the name of the node and one for the properties. Children would come after that.
|
||||
if emacs_children_length != 2 {
|
||||
*this_status = DiffStatus::Bad;
|
||||
*message = Some(format!(
|
||||
"Should have no children but emacs has {:?} children.",
|
||||
emacs_children_length - 2,
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn compare_additional_properties<'b, 's, RK, RV, RI>(
|
||||
emacs: &'b Token<'s>,
|
||||
rust_children: RI,
|
||||
) -> Result<ComparePropertiesResult<'b, 's>, Box<dyn std::error::Error>>
|
||||
where
|
||||
RK: AsRef<str>,
|
||||
RV: AsRef<str>,
|
||||
RI: Iterator<Item = (RK, RV)> + ExactSizeIterator,
|
||||
{
|
||||
for (rust_key, rust_value) in rust_children {
|
||||
let rust_key = rust_key.as_ref();
|
||||
let rust_value = rust_value.as_ref();
|
||||
let emacs_value = get_property_quoted_string(emacs, rust_key)?;
|
||||
if Some(rust_value) != emacs_value.as_ref().map(String::as_str) {
|
||||
let this_status = DiffStatus::Bad;
|
||||
let message = Some(format!(
|
||||
"{} mismatch (emacs != rust) {:?} != {:?}",
|
||||
rust_key, emacs_value, rust_value
|
||||
));
|
||||
return Ok(ComparePropertiesResult::SelfChange(this_status, message));
|
||||
}
|
||||
}
|
||||
Ok(ComparePropertiesResult::NoChange)
|
||||
}
|
||||
|
||||
pub(crate) fn compare_affiliated_keywords<'b, 's, GAK>(
|
||||
source: &'s str,
|
||||
emacs: &'b Token<'s>,
|
||||
rust: &'b GAK,
|
||||
) -> Result<Vec<ComparePropertiesResult<'b, 's>>, Box<dyn std::error::Error>>
|
||||
where
|
||||
GAK: GetAffiliatedKeywords<'s>,
|
||||
{
|
||||
let mut ret = Vec::new();
|
||||
let affiliated_keywords = rust.get_affiliated_keywords();
|
||||
for (rust_name, rust_value) in affiliated_keywords.keywords.iter() {
|
||||
let emacs_property_name = format!(":{}", rust_name);
|
||||
match rust_value {
|
||||
AffiliatedKeywordValue::SingleString(rust_value) => {
|
||||
let diff = compare_property_quoted_string(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
emacs_property_name.as_str(),
|
||||
|_| Some(*rust_value),
|
||||
)?;
|
||||
ret.push(diff);
|
||||
}
|
||||
AffiliatedKeywordValue::ListOfStrings(rust_value) => {
|
||||
let diff = compare_property_list_of_quoted_string(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
emacs_property_name.as_str(),
|
||||
|_| Some(rust_value.iter()),
|
||||
)?;
|
||||
ret.push(diff);
|
||||
}
|
||||
AffiliatedKeywordValue::ListOfListsOfObjects(rust_value) => {
|
||||
let diff = compare_property_list_of_list_of_list_of_ast_nodes(
|
||||
source,
|
||||
emacs,
|
||||
rust,
|
||||
emacs_property_name.as_str(),
|
||||
|_| Some(rust_value),
|
||||
)?;
|
||||
ret.push(diff);
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub(crate) fn affiliated_keywords_names<'s, GAK>(rust: &'s GAK) -> impl Iterator<Item = String> + 's
|
||||
where
|
||||
GAK: GetAffiliatedKeywords<'s>,
|
||||
{
|
||||
rust.get_affiliated_keywords()
|
||||
.keywords
|
||||
.keys()
|
||||
.map(|k| format!(":{}", k))
|
||||
}
|
||||
|
||||
464
src/context/constants.rs
Normal file
464
src/context/constants.rs
Normal file
@@ -0,0 +1,464 @@
|
||||
use super::global_settings::EntityDefinition;
|
||||
|
||||
pub(crate) const DEFAULT_ORG_ELEMENT_PARSED_KEYWORDS: [&'static str; 1] = ["CAPTION"];
|
||||
|
||||
pub(crate) const DEFAULT_ORG_ELEMENT_DUAL_KEYWORDS: [&'static str; 2] = ["CAPTION", "RESULTS"];
|
||||
|
||||
pub(crate) const DEFAULT_ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [
|
||||
"CAPTION", "DATA", "HEADER", "HEADERS", "LABEL", "NAME", "PLOT", "RESNAME", "RESULT",
|
||||
"RESULTS", "SOURCE", "SRCNAME", "TBLNAME",
|
||||
];
|
||||
|
||||
pub(crate) const DEFAULT_ORG_ELEMENT_KEYWORD_TRANSLATION_ALIST: [(&'static str, &'static str); 8] = [
|
||||
("DATA", "NAME"),
|
||||
("LABEL", "NAME"),
|
||||
("RESNAME", "NAME"),
|
||||
("SOURCE", "NAME"),
|
||||
("SRCNAME", "NAME"),
|
||||
("TBLNAME", "NAME"),
|
||||
("RESULT", "RESULTS"),
|
||||
("HEADERS", "HEADER"),
|
||||
];
|
||||
|
||||
pub(crate) const DEFAULT_ORG_LINK_PARAMETERS: [&'static str; 23] = [
|
||||
"id",
|
||||
"eww",
|
||||
"rmail",
|
||||
"mhe",
|
||||
"irc",
|
||||
"info",
|
||||
"gnus",
|
||||
"docview",
|
||||
"bibtex",
|
||||
"bbdb",
|
||||
"w3m",
|
||||
"doi",
|
||||
"file+sys",
|
||||
"file+emacs",
|
||||
"shell",
|
||||
"news",
|
||||
"mailto",
|
||||
"https",
|
||||
"http",
|
||||
"ftp",
|
||||
"help",
|
||||
"file",
|
||||
"elisp",
|
||||
];
|
||||
|
||||
pub(crate) const DEFAULT_ORG_ENTITIES: [EntityDefinition<'static>; 414] = [
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{10.0em}", html: "                    ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{9.5em}", html: "                   ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{9.0em}", html: "                  ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{8.5em}", html: "                 ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{8.0em}", html: "                ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{7.5em}", html: "               ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{7.0em}", html: "              ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "leftrightarrow", latex_math_mode: true, latex: "\\leftrightarrow", html: "↔", ascii: "<->", utf8: "↔"},
|
||||
EntityDefinition {name: "Leftrightarrow", latex_math_mode: true, latex: "\\Leftrightarrow", html: "⇔", ascii: "<=>", utf8: "⇔"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{6.5em}", html: "             ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "hookleftarrow", latex_math_mode: true, latex: "\\hookleftarrow", html: "↵", ascii: "<-'", utf8: "↵"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{6.0em}", html: "            ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{5.5em}", html: "           ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "preccurlyeq", latex_math_mode: true, latex: "\\preccurlyeq", html: "≼", ascii: "[precedes or equal]", utf8: "≼"},
|
||||
EntityDefinition {name: "succcurlyeq", latex_math_mode: true, latex: "\\succcurlyeq", html: "≽", ascii: "[succeeds or equal]", utf8: "≽"},
|
||||
EntityDefinition {name: "diamondsuit", latex_math_mode: true, latex: "\\diamondsuit", html: "♦", ascii: "[diamonds]", utf8: "◆"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{5.0em}", html: "          ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "varepsilon", latex_math_mode: true, latex: "\\varepsilon", html: "ε", ascii: "varepsilon", utf8: "ε"},
|
||||
EntityDefinition {name: "rightarrow", latex_math_mode: true, latex: "\\rightarrow", html: "→", ascii: "->", utf8: "→"},
|
||||
EntityDefinition {name: "Rightarrow", latex_math_mode: true, latex: "\\Rightarrow", html: "⇒", ascii: "=>", utf8: "⇒"},
|
||||
EntityDefinition {name: "blacksmile", latex_math_mode: true, latex: "\\ddot\\smile", html: "☻", ascii: ":-)", utf8: "☻"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{4.5em}", html: "         ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "asciicirc", latex_math_mode: false, latex: "\\textasciicircum{}", html: "^", ascii: "^", utf8: "^"},
|
||||
EntityDefinition {name: "therefore", latex_math_mode: true, latex: "\\therefore", html: "∴", ascii: "[therefore]", utf8: "∴"},
|
||||
EntityDefinition {name: "triangleq", latex_math_mode: true, latex: "\\triangleq", html: "≜", ascii: "[defined to]", utf8: "≜"},
|
||||
EntityDefinition {name: "lesseqgtr", latex_math_mode: true, latex: "\\lesseqgtr", html: "⋚", ascii: "[less than or equal or greater than or equal]", utf8: "⋚"},
|
||||
EntityDefinition {name: "leftarrow", latex_math_mode: true, latex: "\\leftarrow", html: "←", ascii: "<-", utf8: "←"},
|
||||
EntityDefinition {name: "Leftarrow", latex_math_mode: true, latex: "\\Leftarrow", html: "⇐", ascii: "<=", utf8: "⇐"},
|
||||
EntityDefinition {name: "downarrow", latex_math_mode: true, latex: "\\downarrow", html: "↓", ascii: "[downarrow]", utf8: "↓"},
|
||||
EntityDefinition {name: "Downarrow", latex_math_mode: true, latex: "\\Downarrow", html: "⇓", ascii: "[dbldownarrow]", utf8: "⇓"},
|
||||
EntityDefinition {name: "checkmark", latex_math_mode: true, latex: "\\checkmark", html: "✓", ascii: "[checkmark]", utf8: "✓"},
|
||||
EntityDefinition {name: "spadesuit", latex_math_mode: true, latex: "\\spadesuit", html: "♠", ascii: "[spades]", utf8: "♠"},
|
||||
EntityDefinition {name: "heartsuit", latex_math_mode: true, latex: "\\heartsuit", html: "♥", ascii: "[hearts]", utf8: "♥"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{4.0em}", html: "        ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "thetasym", latex_math_mode: true, latex: "\\vartheta", html: "ϑ", ascii: "theta", utf8: "ϑ"},
|
||||
EntityDefinition {name: "vartheta", latex_math_mode: true, latex: "\\vartheta", html: "ϑ", ascii: "theta", utf8: "ϑ"},
|
||||
EntityDefinition {name: "varsigma", latex_math_mode: true, latex: "\\varsigma", html: "ς", ascii: "varsigma", utf8: "ς"},
|
||||
EntityDefinition {name: "setminus", latex_math_mode: true, latex: "\\setminus", html: "∖", ascii: "\" ", utf8: "⧵"},
|
||||
EntityDefinition {name: "emptyset", latex_math_mode: true, latex: "\\emptyset", html: "∅", ascii: "[empty set]", utf8: "∅"},
|
||||
EntityDefinition {name: "parallel", latex_math_mode: true, latex: "\\parallel", html: "∥", ascii: "||", utf8: "∥"},
|
||||
EntityDefinition {name: "clubsuit", latex_math_mode: true, latex: "\\clubsuit", html: "♣", ascii: "[clubs]", utf8: "♣"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{3.5em}", html: "       ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "Epsilon", latex_math_mode: false, latex: "E", html: "Ε", ascii: "Epsilon", utf8: "Ε"},
|
||||
EntityDefinition {name: "epsilon", latex_math_mode: true, latex: "\\epsilon", html: "ε", ascii: "epsilon", utf8: "ε"},
|
||||
EntityDefinition {name: "Omicron", latex_math_mode: false, latex: "O", html: "Ο", ascii: "Omicron", utf8: "Ο"},
|
||||
EntityDefinition {name: "omicron", latex_math_mode: false, latex: "\\textit{o}", html: "ο", ascii: "omicron", utf8: "ο"},
|
||||
EntityDefinition {name: "Upsilon", latex_math_mode: true, latex: "\\Upsilon", html: "Υ", ascii: "Upsilon", utf8: "Υ"},
|
||||
EntityDefinition {name: "upsilon", latex_math_mode: true, latex: "\\upsilon", html: "υ", ascii: "upsilon", utf8: "υ"},
|
||||
EntityDefinition {name: "partial", latex_math_mode: true, latex: "\\partial", html: "∂", ascii: "[partial differential]", utf8: "∂"},
|
||||
EntityDefinition {name: "alefsym", latex_math_mode: true, latex: "\\aleph", html: "ℵ", ascii: "aleph", utf8: "ℵ"},
|
||||
EntityDefinition {name: "because", latex_math_mode: true, latex: "\\because", html: "∵", ascii: "[because]", utf8: "∵"},
|
||||
EntityDefinition {name: "lessgtr", latex_math_mode: true, latex: "\\lessgtr", html: "≶", ascii: "[less than or greater than]", utf8: "≶"},
|
||||
EntityDefinition {name: "nexists", latex_math_mode: true, latex: "\\nexists", html: "∃", ascii: "[there does not exists]", utf8: "∄"},
|
||||
EntityDefinition {name: "uparrow", latex_math_mode: true, latex: "\\uparrow", html: "↑", ascii: "[uparrow]", utf8: "↑"},
|
||||
EntityDefinition {name: "Uparrow", latex_math_mode: true, latex: "\\Uparrow", html: "⇑", ascii: "[dbluparrow]", utf8: "⇑"},
|
||||
EntityDefinition {name: "diamond", latex_math_mode: true, latex: "\\diamondsuit", html: "⋄", ascii: "[diamond]", utf8: "◆"},
|
||||
EntityDefinition {name: "Diamond", latex_math_mode: true, latex: "\\diamondsuit", html: "⋄", ascii: "[diamond]", utf8: "◆"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{3.0em}", html: "      ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "Agrave", latex_math_mode: false, latex: "\\`{A}", html: "À", ascii: "A", utf8: "À"},
|
||||
EntityDefinition {name: "agrave", latex_math_mode: false, latex: "\\`{a}", html: "à", ascii: "a", utf8: "à"},
|
||||
EntityDefinition {name: "Aacute", latex_math_mode: false, latex: "\\'{A}", html: "Á", ascii: "A", utf8: "Á"},
|
||||
EntityDefinition {name: "aacute", latex_math_mode: false, latex: "\\'{a}", html: "á", ascii: "a", utf8: "á"},
|
||||
EntityDefinition {name: "Atilde", latex_math_mode: false, latex: "\\~{A}", html: "Ã", ascii: "A", utf8: "Ã"},
|
||||
EntityDefinition {name: "atilde", latex_math_mode: false, latex: "\\~{a}", html: "ã", ascii: "a", utf8: "ã"},
|
||||
EntityDefinition {name: "Ccedil", latex_math_mode: false, latex: "\\c{C}", html: "Ç", ascii: "C", utf8: "Ç"},
|
||||
EntityDefinition {name: "ccedil", latex_math_mode: false, latex: "\\c{c}", html: "ç", ascii: "c", utf8: "ç"},
|
||||
EntityDefinition {name: "Egrave", latex_math_mode: false, latex: "\\`{E}", html: "È", ascii: "E", utf8: "È"},
|
||||
EntityDefinition {name: "egrave", latex_math_mode: false, latex: "\\`{e}", html: "è", ascii: "e", utf8: "è"},
|
||||
EntityDefinition {name: "Eacute", latex_math_mode: false, latex: "\\'{E}", html: "É", ascii: "E", utf8: "É"},
|
||||
EntityDefinition {name: "eacute", latex_math_mode: false, latex: "\\'{e}", html: "é", ascii: "e", utf8: "é"},
|
||||
EntityDefinition {name: "Igrave", latex_math_mode: false, latex: "\\`{I}", html: "Ì", ascii: "I", utf8: "Ì"},
|
||||
EntityDefinition {name: "igrave", latex_math_mode: false, latex: "\\`{i}", html: "ì", ascii: "i", utf8: "ì"},
|
||||
EntityDefinition {name: "Iacute", latex_math_mode: false, latex: "\\'{I}", html: "Í", ascii: "I", utf8: "Í"},
|
||||
EntityDefinition {name: "iacute", latex_math_mode: false, latex: "\\'{i}", html: "í", ascii: "i", utf8: "í"},
|
||||
EntityDefinition {name: "inodot", latex_math_mode: false, latex: "\\i", html: "ı", ascii: "i", utf8: "ı"},
|
||||
EntityDefinition {name: "Ntilde", latex_math_mode: false, latex: "\\~{N}", html: "Ñ", ascii: "N", utf8: "Ñ"},
|
||||
EntityDefinition {name: "ntilde", latex_math_mode: false, latex: "\\~{n}", html: "ñ", ascii: "n", utf8: "ñ"},
|
||||
EntityDefinition {name: "Ograve", latex_math_mode: false, latex: "\\`{O}", html: "Ò", ascii: "O", utf8: "Ò"},
|
||||
EntityDefinition {name: "ograve", latex_math_mode: false, latex: "\\`{o}", html: "ò", ascii: "o", utf8: "ò"},
|
||||
EntityDefinition {name: "Oacute", latex_math_mode: false, latex: "\\'{O}", html: "Ó", ascii: "O", utf8: "Ó"},
|
||||
EntityDefinition {name: "oacute", latex_math_mode: false, latex: "\\'{o}", html: "ó", ascii: "o", utf8: "ó"},
|
||||
EntityDefinition {name: "Otilde", latex_math_mode: false, latex: "\\~{O}", html: "Õ", ascii: "O", utf8: "Õ"},
|
||||
EntityDefinition {name: "otilde", latex_math_mode: false, latex: "\\~{o}", html: "õ", ascii: "o", utf8: "õ"},
|
||||
EntityDefinition {name: "Oslash", latex_math_mode: false, latex: "\\O", html: "Ø", ascii: "O", utf8: "Ø"},
|
||||
EntityDefinition {name: "oslash", latex_math_mode: false, latex: "\\o{}", html: "ø", ascii: "o", utf8: "ø"},
|
||||
EntityDefinition {name: "Scaron", latex_math_mode: false, latex: "\\v{S}", html: "Š", ascii: "S", utf8: "Š"},
|
||||
EntityDefinition {name: "scaron", latex_math_mode: false, latex: "\\v{s}", html: "š", ascii: "s", utf8: "š"},
|
||||
EntityDefinition {name: "Ugrave", latex_math_mode: false, latex: "\\`{U}", html: "Ù", ascii: "U", utf8: "Ù"},
|
||||
EntityDefinition {name: "ugrave", latex_math_mode: false, latex: "\\`{u}", html: "ù", ascii: "u", utf8: "ù"},
|
||||
EntityDefinition {name: "Uacute", latex_math_mode: false, latex: "\\'{U}", html: "Ú", ascii: "U", utf8: "Ú"},
|
||||
EntityDefinition {name: "uacute", latex_math_mode: false, latex: "\\'{u}", html: "ú", ascii: "u", utf8: "ú"},
|
||||
EntityDefinition {name: "Yacute", latex_math_mode: false, latex: "\\'{Y}", html: "Ý", ascii: "Y", utf8: "Ý"},
|
||||
EntityDefinition {name: "yacute", latex_math_mode: false, latex: "\\'{y}", html: "ý", ascii: "y", utf8: "ý"},
|
||||
EntityDefinition {name: "weierp", latex_math_mode: true, latex: "\\wp", html: "℘", ascii: "P", utf8: "℘"},
|
||||
EntityDefinition {name: "Lambda", latex_math_mode: true, latex: "\\Lambda", html: "Λ", ascii: "Lambda", utf8: "Λ"},
|
||||
EntityDefinition {name: "lambda", latex_math_mode: true, latex: "\\lambda", html: "λ", ascii: "lambda", utf8: "λ"},
|
||||
EntityDefinition {name: "sigmaf", latex_math_mode: true, latex: "\\varsigma", html: "ς", ascii: "sigmaf", utf8: "ς"},
|
||||
EntityDefinition {name: "varphi", latex_math_mode: true, latex: "\\varphi", html: "ϕ", ascii: "varphi", utf8: "φ"},
|
||||
EntityDefinition {name: "acutex", latex_math_mode: true, latex: "\\acute x", html: "´x", ascii: "'x", utf8: "𝑥́"},
|
||||
EntityDefinition {name: "hellip", latex_math_mode: false, latex: "\\dots{}", html: "…", ascii: "...", utf8: "…"},
|
||||
EntityDefinition {name: "middot", latex_math_mode: false, latex: "\\textperiodcentered{}", html: "·", ascii: ".", utf8: "·"},
|
||||
EntityDefinition {name: "iquest", latex_math_mode: false, latex: "?`", html: "¿", ascii: "?", utf8: "¿"},
|
||||
EntityDefinition {name: "lsaquo", latex_math_mode: false, latex: "\\guilsinglleft{}", html: "‹", ascii: "<", utf8: "‹"},
|
||||
EntityDefinition {name: "rsaquo", latex_math_mode: false, latex: "\\guilsinglright{}", html: "›", ascii: ">", utf8: "›"},
|
||||
EntityDefinition {name: "brvbar", latex_math_mode: false, latex: "\\textbrokenbar{}", html: "¦", ascii: "|", utf8: "¦"},
|
||||
EntityDefinition {name: "dagger", latex_math_mode: false, latex: "\\textdagger{}", html: "†", ascii: "[dagger]", utf8: "†"},
|
||||
EntityDefinition {name: "Dagger", latex_math_mode: false, latex: "\\textdaggerdbl{}", html: "‡", ascii: "[doubledagger]", utf8: "‡"},
|
||||
EntityDefinition {name: "thinsp", latex_math_mode: false, latex: "\\hspace*{.2em}", html: " ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "curren", latex_math_mode: false, latex: "\\textcurrency{}", html: "¤", ascii: "curr.", utf8: "¤"},
|
||||
EntityDefinition {name: "dollar", latex_math_mode: false, latex: "\\$", html: "$", ascii: "$", utf8: "$"},
|
||||
EntityDefinition {name: "plusmn", latex_math_mode: false, latex: "\\textpm{}", html: "±", ascii: "+-", utf8: "±"},
|
||||
EntityDefinition {name: "frac12", latex_math_mode: false, latex: "\\textonehalf{}", html: "½", ascii: "1/2", utf8: "½"},
|
||||
EntityDefinition {name: "frac14", latex_math_mode: false, latex: "\\textonequarter{}", html: "¼", ascii: "1/4", utf8: "¼"},
|
||||
EntityDefinition {name: "frac34", latex_math_mode: false, latex: "\\textthreequarters{}", html: "¾", ascii: "3/4", utf8: "¾"},
|
||||
EntityDefinition {name: "permil", latex_math_mode: false, latex: "\\textperthousand{}", html: "‰", ascii: "per thousand", utf8: "‰"},
|
||||
EntityDefinition {name: "propto", latex_math_mode: true, latex: "\\propto", html: "∝", ascii: "[proportional to]", utf8: "∝"},
|
||||
EntityDefinition {name: "there4", latex_math_mode: true, latex: "\\therefore", html: "∴", ascii: "[therefore]", utf8: "∴"},
|
||||
EntityDefinition {name: "approx", latex_math_mode: true, latex: "\\approx", html: "≈", ascii: "[almost equal to]", utf8: "≈"},
|
||||
EntityDefinition {name: "preceq", latex_math_mode: true, latex: "\\preceq", html: "≼", ascii: "[precedes or equal]", utf8: "≼"},
|
||||
EntityDefinition {name: "succeq", latex_math_mode: true, latex: "\\succeq", html: "≽", ascii: "[succeeds or equal]", utf8: "≽"},
|
||||
EntityDefinition {name: "subset", latex_math_mode: true, latex: "\\subset", html: "⊂", ascii: "[subset of]", utf8: "⊂"},
|
||||
EntityDefinition {name: "supset", latex_math_mode: true, latex: "\\supset", html: "⊃", ascii: "[superset of]", utf8: "⊃"},
|
||||
EntityDefinition {name: "forall", latex_math_mode: true, latex: "\\forall", html: "∀", ascii: "[for all]", utf8: "∀"},
|
||||
EntityDefinition {name: "exists", latex_math_mode: true, latex: "\\exists", html: "∃", ascii: "[there exists]", utf8: "∃"},
|
||||
EntityDefinition {name: "nexist", latex_math_mode: true, latex: "\\nexists", html: "∃", ascii: "[there does not exists]", utf8: "∄"},
|
||||
EntityDefinition {name: "lfloor", latex_math_mode: true, latex: "\\lfloor", html: "⌊", ascii: "[left floor]", utf8: "⌊"},
|
||||
EntityDefinition {name: "rfloor", latex_math_mode: true, latex: "\\rfloor", html: "⌋", ascii: "[right floor]", utf8: "⌋"},
|
||||
EntityDefinition {name: "langle", latex_math_mode: true, latex: "\\langle", html: "⟨", ascii: "<", utf8: "⟨"},
|
||||
EntityDefinition {name: "rangle", latex_math_mode: true, latex: "\\rangle", html: "⟩", ascii: ">", utf8: "⟩"},
|
||||
EntityDefinition {name: "arccos", latex_math_mode: true, latex: "\\arccos", html: "arccos", ascii: "arccos", utf8: "arccos"},
|
||||
EntityDefinition {name: "arcsin", latex_math_mode: true, latex: "\\arcsin", html: "arcsin", ascii: "arcsin", utf8: "arcsin"},
|
||||
EntityDefinition {name: "arctan", latex_math_mode: true, latex: "\\arctan", html: "arctan", ascii: "arctan", utf8: "arctan"},
|
||||
EntityDefinition {name: "liminf", latex_math_mode: true, latex: "\\liminf", html: "liminf", ascii: "liminf", utf8: "liminf"},
|
||||
EntityDefinition {name: "limsup", latex_math_mode: true, latex: "\\limsup", html: "limsup", ascii: "limsup", utf8: "limsup"},
|
||||
EntityDefinition {name: "bullet", latex_math_mode: false, latex: "\\textbullet{}", html: "•", ascii: "*", utf8: "•"},
|
||||
EntityDefinition {name: "lowast", latex_math_mode: true, latex: "\\ast", html: "∗", ascii: "*", utf8: "∗"},
|
||||
EntityDefinition {name: "otimes", latex_math_mode: true, latex: "\\otimes", html: "⊗", ascii: "[circled times]", utf8: "⊗"},
|
||||
EntityDefinition {name: "smiley", latex_math_mode: true, latex: "\\ddot\\smile", html: "☺", ascii: ":-)", utf8: "☺"},
|
||||
EntityDefinition {name: "frowny", latex_math_mode: true, latex: "\\ddot\\frown", html: "☹", ascii: ":-(", utf8: "☹"},
|
||||
EntityDefinition {name: "spades", latex_math_mode: true, latex: "\\spadesuit", html: "♠", ascii: "[spades]", utf8: "♠"},
|
||||
EntityDefinition {name: "hearts", latex_math_mode: true, latex: "\\heartsuit", html: "♥", ascii: "[hearts]", utf8: "♥"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{2.5em}", html: "     ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "Acirc", latex_math_mode: false, latex: "\\^{A}", html: "Â", ascii: "A", utf8: "Â"},
|
||||
EntityDefinition {name: "acirc", latex_math_mode: false, latex: "\\^{a}", html: "â", ascii: "a", utf8: "â"},
|
||||
EntityDefinition {name: "Amacr", latex_math_mode: false, latex: "\\={A}", html: "Ā", ascii: "A", utf8: "Ã"},
|
||||
EntityDefinition {name: "amacr", latex_math_mode: false, latex: "\\={a}", html: "ā", ascii: "a", utf8: "ã"},
|
||||
EntityDefinition {name: "Aring", latex_math_mode: false, latex: "\\AA{}", html: "Å", ascii: "A", utf8: "Å"},
|
||||
EntityDefinition {name: "aring", latex_math_mode: false, latex: "\\aa{}", html: "å", ascii: "a", utf8: "å"},
|
||||
EntityDefinition {name: "AElig", latex_math_mode: false, latex: "\\AE{}", html: "Æ", ascii: "AE", utf8: "Æ"},
|
||||
EntityDefinition {name: "aelig", latex_math_mode: false, latex: "\\ae{}", html: "æ", ascii: "ae", utf8: "æ"},
|
||||
EntityDefinition {name: "Ecirc", latex_math_mode: false, latex: "\\^{E}", html: "Ê", ascii: "E", utf8: "Ê"},
|
||||
EntityDefinition {name: "ecirc", latex_math_mode: false, latex: "\\^{e}", html: "ê", ascii: "e", utf8: "ê"},
|
||||
EntityDefinition {name: "Icirc", latex_math_mode: false, latex: "\\^{I}", html: "Î", ascii: "I", utf8: "Î"},
|
||||
EntityDefinition {name: "icirc", latex_math_mode: false, latex: "\\^{i}", html: "î", ascii: "i", utf8: "î"},
|
||||
EntityDefinition {name: "Ocirc", latex_math_mode: false, latex: "\\^{O}", html: "Ô", ascii: "O", utf8: "Ô"},
|
||||
EntityDefinition {name: "ocirc", latex_math_mode: false, latex: "\\^{o}", html: "ô", ascii: "o", utf8: "ô"},
|
||||
EntityDefinition {name: "OElig", latex_math_mode: false, latex: "\\OE{}", html: "Œ", ascii: "OE", utf8: "Œ"},
|
||||
EntityDefinition {name: "oelig", latex_math_mode: false, latex: "\\oe{}", html: "œ", ascii: "oe", utf8: "œ"},
|
||||
EntityDefinition {name: "szlig", latex_math_mode: false, latex: "\\ss{}", html: "ß", ascii: "ss", utf8: "ß"},
|
||||
EntityDefinition {name: "Ucirc", latex_math_mode: false, latex: "\\^{U}", html: "Û", ascii: "U", utf8: "Û"},
|
||||
EntityDefinition {name: "ucirc", latex_math_mode: false, latex: "\\^{u}", html: "û", ascii: "u", utf8: "û"},
|
||||
EntityDefinition {name: "image", latex_math_mode: true, latex: "\\Im", html: "ℑ", ascii: "I", utf8: "ℑ"},
|
||||
EntityDefinition {name: "imath", latex_math_mode: true, latex: "\\imath", html: "ı", ascii: "[dotless i]", utf8: "ı"},
|
||||
EntityDefinition {name: "jmath", latex_math_mode: true, latex: "\\jmath", html: "ȷ", ascii: "[dotless j]", utf8: "ȷ"},
|
||||
EntityDefinition {name: "Alpha", latex_math_mode: false, latex: "A", html: "Α", ascii: "Alpha", utf8: "Α"},
|
||||
EntityDefinition {name: "alpha", latex_math_mode: true, latex: "\\alpha", html: "α", ascii: "alpha", utf8: "α"},
|
||||
EntityDefinition {name: "Gamma", latex_math_mode: true, latex: "\\Gamma", html: "Γ", ascii: "Gamma", utf8: "Γ"},
|
||||
EntityDefinition {name: "gamma", latex_math_mode: true, latex: "\\gamma", html: "γ", ascii: "gamma", utf8: "γ"},
|
||||
EntityDefinition {name: "Delta", latex_math_mode: true, latex: "\\Delta", html: "Δ", ascii: "Delta", utf8: "Δ"},
|
||||
EntityDefinition {name: "delta", latex_math_mode: true, latex: "\\delta", html: "δ", ascii: "delta", utf8: "δ"},
|
||||
EntityDefinition {name: "Theta", latex_math_mode: true, latex: "\\Theta", html: "Θ", ascii: "Theta", utf8: "Θ"},
|
||||
EntityDefinition {name: "theta", latex_math_mode: true, latex: "\\theta", html: "θ", ascii: "theta", utf8: "θ"},
|
||||
EntityDefinition {name: "Kappa", latex_math_mode: false, latex: "K", html: "Κ", ascii: "Kappa", utf8: "Κ"},
|
||||
EntityDefinition {name: "kappa", latex_math_mode: true, latex: "\\kappa", html: "κ", ascii: "kappa", utf8: "κ"},
|
||||
EntityDefinition {name: "Sigma", latex_math_mode: true, latex: "\\Sigma", html: "Σ", ascii: "Sigma", utf8: "Σ"},
|
||||
EntityDefinition {name: "sigma", latex_math_mode: true, latex: "\\sigma", html: "σ", ascii: "sigma", utf8: "σ"},
|
||||
EntityDefinition {name: "upsih", latex_math_mode: true, latex: "\\Upsilon", html: "ϒ", ascii: "upsilon", utf8: "ϒ"},
|
||||
EntityDefinition {name: "Omega", latex_math_mode: true, latex: "\\Omega", html: "Ω", ascii: "Omega", utf8: "Ω"},
|
||||
EntityDefinition {name: "omega", latex_math_mode: true, latex: "\\omega", html: "ω", ascii: "omega", utf8: "ω"},
|
||||
EntityDefinition {name: "varpi", latex_math_mode: true, latex: "\\varpi", html: "ϖ", ascii: "omega-pi", utf8: "ϖ"},
|
||||
EntityDefinition {name: "aleph", latex_math_mode: true, latex: "\\aleph", html: "ℵ", ascii: "aleph", utf8: "ℵ"},
|
||||
EntityDefinition {name: "gimel", latex_math_mode: true, latex: "\\gimel", html: "ℷ", ascii: "gimel", utf8: "ℷ"},
|
||||
EntityDefinition {name: "dalet", latex_math_mode: true, latex: "\\daleth", html: "ℸ", ascii: "dalet", utf8: "ד"},
|
||||
EntityDefinition {name: "THORN", latex_math_mode: false, latex: "\\TH{}", html: "Þ", ascii: "TH", utf8: "Þ"},
|
||||
EntityDefinition {name: "thorn", latex_math_mode: false, latex: "\\th{}", html: "þ", ascii: "th", utf8: "þ"},
|
||||
EntityDefinition {name: "cdots", latex_math_mode: true, latex: "\\cdots{}", html: "⋯", ascii: "...", utf8: "⋯"},
|
||||
EntityDefinition {name: "iexcl", latex_math_mode: false, latex: "!`", html: "¡", ascii: "!", utf8: "¡"},
|
||||
EntityDefinition {name: "ndash", latex_math_mode: false, latex: "--", html: "–", ascii: "-", utf8: "–"},
|
||||
EntityDefinition {name: "mdash", latex_math_mode: false, latex: "---", html: "—", ascii: "--", utf8: "—"},
|
||||
EntityDefinition {name: "acute", latex_math_mode: false, latex: "\\textasciiacute{}", html: "´", ascii: "'", utf8: "´"},
|
||||
EntityDefinition {name: "ldquo", latex_math_mode: false, latex: "\\textquotedblleft{}", html: "“", ascii: "\"", utf8: "“"},
|
||||
EntityDefinition {name: "rdquo", latex_math_mode: false, latex: "\\textquotedblright{}", html: "”", ascii: "\"", utf8: "”"},
|
||||
EntityDefinition {name: "bdquo", latex_math_mode: false, latex: "\\quotedblbase{}", html: "„", ascii: "\"", utf8: "„"},
|
||||
EntityDefinition {name: "lsquo", latex_math_mode: false, latex: "\\textquoteleft{}", html: "‘", ascii: "`", utf8: "‘"},
|
||||
EntityDefinition {name: "rsquo", latex_math_mode: false, latex: "\\textquoteright{}", html: "’", ascii: "'", utf8: "’"},
|
||||
EntityDefinition {name: "sbquo", latex_math_mode: false, latex: "\\quotesinglbase{}", html: "‚", ascii: ",", utf8: "‚"},
|
||||
EntityDefinition {name: "laquo", latex_math_mode: false, latex: "\\guillemotleft{}", html: "«", ascii: "<<", utf8: "«"},
|
||||
EntityDefinition {name: "raquo", latex_math_mode: false, latex: "\\guillemotright{}", html: "»", ascii: ">>", utf8: "»"},
|
||||
EntityDefinition {name: "tilde", latex_math_mode: false, latex: "\\textasciitilde{}", html: "~", ascii: "~", utf8: "~"},
|
||||
EntityDefinition {name: "slash", latex_math_mode: false, latex: "/", html: "/", ascii: "/", utf8: "/"},
|
||||
EntityDefinition {name: "under", latex_math_mode: false, latex: "\\_", html: "_", ascii: "_", utf8: "_"},
|
||||
EntityDefinition {name: "equal", latex_math_mode: false, latex: "=", html: "=", ascii: "=", utf8: "="},
|
||||
EntityDefinition {name: "pound", latex_math_mode: false, latex: "\\pounds{}", html: "£", ascii: "pound", utf8: "£"},
|
||||
EntityDefinition {name: "trade", latex_math_mode: false, latex: "\\texttrademark{}", html: "™", ascii: "TM", utf8: "™"},
|
||||
EntityDefinition {name: "minus", latex_math_mode: true, latex: "-", html: "−", ascii: "-", utf8: "−"},
|
||||
EntityDefinition {name: "times", latex_math_mode: false, latex: "\\texttimes{}", html: "×", ascii: "*", utf8: "×"},
|
||||
EntityDefinition {name: "frasl", latex_math_mode: false, latex: "/", html: "⁄", ascii: "/", utf8: "⁄"},
|
||||
EntityDefinition {name: "colon", latex_math_mode: true, latex: "\\colon", html: ":", ascii: ":", utf8: ":"},
|
||||
EntityDefinition {name: "radic", latex_math_mode: true, latex: "\\sqrt{\\,}", html: "√", ascii: "[square root]", utf8: "√"},
|
||||
EntityDefinition {name: "micro", latex_math_mode: false, latex: "\\textmu{}", html: "µ", ascii: "micro", utf8: "µ"},
|
||||
EntityDefinition {name: "prime", latex_math_mode: true, latex: "\\prime", html: "′", ascii: "'", utf8: "′"},
|
||||
EntityDefinition {name: "Prime", latex_math_mode: true, latex: "\\prime{}\\prime", html: "″", ascii: "''", utf8: "″"},
|
||||
EntityDefinition {name: "infin", latex_math_mode: true, latex: "\\infty", html: "∞", ascii: "[infinity]", utf8: "∞"},
|
||||
EntityDefinition {name: "infty", latex_math_mode: true, latex: "\\infty", html: "∞", ascii: "[infinity]", utf8: "∞"},
|
||||
EntityDefinition {name: "wedge", latex_math_mode: true, latex: "\\wedge", html: "∧", ascii: "[logical and]", utf8: "∧"},
|
||||
EntityDefinition {name: "smile", latex_math_mode: true, latex: "\\smile", html: "⌣", ascii: "[cup product]", utf8: "⌣"},
|
||||
EntityDefinition {name: "frown", latex_math_mode: true, latex: "\\frown", html: "⌢", ascii: "[Cap product]", utf8: "⌢"},
|
||||
EntityDefinition {name: "simeq", latex_math_mode: true, latex: "\\simeq", html: "≅", ascii: "[approx. equal to]", utf8: "≅"},
|
||||
EntityDefinition {name: "asymp", latex_math_mode: true, latex: "\\asymp", html: "≈", ascii: "[almost equal to]", utf8: "≈"},
|
||||
EntityDefinition {name: "equiv", latex_math_mode: true, latex: "\\equiv", html: "≡", ascii: "[identical to]", utf8: "≡"},
|
||||
EntityDefinition {name: "exist", latex_math_mode: true, latex: "\\exists", html: "∃", ascii: "[there exists]", utf8: "∃"},
|
||||
EntityDefinition {name: "empty", latex_math_mode: true, latex: "\\emptyset", html: "∅", ascii: "[empty set]", utf8: "∅"},
|
||||
EntityDefinition {name: "notin", latex_math_mode: true, latex: "\\notin", html: "∉", ascii: "[not an element of]", utf8: "∉"},
|
||||
EntityDefinition {name: "nabla", latex_math_mode: true, latex: "\\nabla", html: "∇", ascii: "[nabla]", utf8: "∇"},
|
||||
EntityDefinition {name: "angle", latex_math_mode: true, latex: "\\angle", html: "∠", ascii: "[angle]", utf8: "∠"},
|
||||
EntityDefinition {name: "lceil", latex_math_mode: true, latex: "\\lceil", html: "⌈", ascii: "[left ceiling]", utf8: "⌈"},
|
||||
EntityDefinition {name: "rceil", latex_math_mode: true, latex: "\\rceil", html: "⌉", ascii: "[right ceiling]", utf8: "⌉"},
|
||||
EntityDefinition {name: "crarr", latex_math_mode: true, latex: "\\hookleftarrow", html: "↵", ascii: "<-'", utf8: "↵"},
|
||||
EntityDefinition {name: "oplus", latex_math_mode: true, latex: "\\oplus", html: "⊕", ascii: "[circled plus]", utf8: "⊕"},
|
||||
EntityDefinition {name: "check", latex_math_mode: true, latex: "\\checkmark", html: "✓", ascii: "[checkmark]", utf8: "✓"},
|
||||
EntityDefinition {name: "cedil", latex_math_mode: false, latex: "\\c{}", html: "¸", ascii: "[cedilla]", utf8: "¸"},
|
||||
EntityDefinition {name: "oline", latex_math_mode: true, latex: "\\overline{~}", html: "‾", ascii: "[overline]", utf8: "‾"},
|
||||
EntityDefinition {name: "clubs", latex_math_mode: true, latex: "\\clubsuit", html: "♣", ascii: "[clubs]", utf8: "♣"},
|
||||
EntityDefinition {name: "diams", latex_math_mode: true, latex: "\\diamondsuit", html: "♦", ascii: "[diamonds]", utf8: "◆"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{2.0em}", html: "    ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "Auml", latex_math_mode: false, latex: "\\\"{A}", html: "Ä", ascii: "Ae", utf8: "Ä"},
|
||||
EntityDefinition {name: "auml", latex_math_mode: false, latex: "\\\"{a}", html: "ä", ascii: "ae", utf8: "ä"},
|
||||
EntityDefinition {name: "Euml", latex_math_mode: false, latex: "\\\"{E}", html: "Ë", ascii: "E", utf8: "Ë"},
|
||||
EntityDefinition {name: "euml", latex_math_mode: false, latex: "\\\"{e}", html: "ë", ascii: "e", utf8: "ë"},
|
||||
EntityDefinition {name: "Idot", latex_math_mode: false, latex: "\\.{I}", html: "&idot;", ascii: "I", utf8: "İ"},
|
||||
EntityDefinition {name: "Iuml", latex_math_mode: false, latex: "\\\"{I}", html: "Ï", ascii: "I", utf8: "Ï"},
|
||||
EntityDefinition {name: "iuml", latex_math_mode: false, latex: "\\\"{i}", html: "ï", ascii: "i", utf8: "ï"},
|
||||
EntityDefinition {name: "Ouml", latex_math_mode: false, latex: "\\\"{O}", html: "Ö", ascii: "Oe", utf8: "Ö"},
|
||||
EntityDefinition {name: "ouml", latex_math_mode: false, latex: "\\\"{o}", html: "ö", ascii: "oe", utf8: "ö"},
|
||||
EntityDefinition {name: "Uuml", latex_math_mode: false, latex: "\\\"{U}", html: "Ü", ascii: "Ue", utf8: "Ü"},
|
||||
EntityDefinition {name: "uuml", latex_math_mode: false, latex: "\\\"{u}", html: "ü", ascii: "ue", utf8: "ü"},
|
||||
EntityDefinition {name: "Yuml", latex_math_mode: false, latex: "\\\"{Y}", html: "Ÿ", ascii: "Y", utf8: "Ÿ"},
|
||||
EntityDefinition {name: "yuml", latex_math_mode: false, latex: "\\\"{y}", html: "ÿ", ascii: "y", utf8: "ÿ"},
|
||||
EntityDefinition {name: "fnof", latex_math_mode: false, latex: "\\textit{f}", html: "ƒ", ascii: "f", utf8: "ƒ"},
|
||||
EntityDefinition {name: "real", latex_math_mode: true, latex: "\\Re", html: "ℜ", ascii: "R", utf8: "ℜ"},
|
||||
EntityDefinition {name: "Beta", latex_math_mode: false, latex: "B", html: "Β", ascii: "Beta", utf8: "Β"},
|
||||
EntityDefinition {name: "beta", latex_math_mode: true, latex: "\\beta", html: "β", ascii: "beta", utf8: "β"},
|
||||
EntityDefinition {name: "Zeta", latex_math_mode: false, latex: "Z", html: "Ζ", ascii: "Zeta", utf8: "Ζ"},
|
||||
EntityDefinition {name: "zeta", latex_math_mode: true, latex: "\\zeta", html: "ζ", ascii: "zeta", utf8: "ζ"},
|
||||
EntityDefinition {name: "Iota", latex_math_mode: false, latex: "I", html: "Ι", ascii: "Iota", utf8: "Ι"},
|
||||
EntityDefinition {name: "iota", latex_math_mode: true, latex: "\\iota", html: "ι", ascii: "iota", utf8: "ι"},
|
||||
EntityDefinition {name: "beth", latex_math_mode: true, latex: "\\beth", html: "ℶ", ascii: "beth", utf8: "ב"},
|
||||
EntityDefinition {name: "dots", latex_math_mode: false, latex: "\\dots{}", html: "…", ascii: "...", utf8: "…"},
|
||||
EntityDefinition {name: "quot", latex_math_mode: false, latex: "\\textquotedbl{}", html: """, ascii: "\"", utf8: "\""},
|
||||
EntityDefinition {name: "circ", latex_math_mode: false, latex: "\\^{}", html: "ˆ", ascii: "^", utf8: "∘"},
|
||||
EntityDefinition {name: "vert", latex_math_mode: true, latex: "\\vert{}", html: "|", ascii: "|", utf8: "|"},
|
||||
EntityDefinition {name: "vbar", latex_math_mode: false, latex: "|", html: "|", ascii: "|", utf8: "|"},
|
||||
EntityDefinition {name: "sect", latex_math_mode: false, latex: "\\S", html: "§", ascii: "section", utf8: "§"},
|
||||
EntityDefinition {name: "para", latex_math_mode: false, latex: "\\P{}", html: "¶", ascii: "paragraph", utf8: "¶"},
|
||||
EntityDefinition {name: "plus", latex_math_mode: false, latex: "+", html: "+", ascii: "+", utf8: "+"},
|
||||
EntityDefinition {name: "ddag", latex_math_mode: false, latex: "\\ddag{}", html: "‡", ascii: "[doubledagger]", utf8: "‡"},
|
||||
EntityDefinition {name: "nbsp", latex_math_mode: false, latex: "~", html: " ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "ensp", latex_math_mode: false, latex: "\\hspace*{.5em}", html: " ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "emsp", latex_math_mode: false, latex: "\\hspace*{1em}", html: " ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "cent", latex_math_mode: false, latex: "\\textcent{}", html: "¢", ascii: "cent", utf8: "¢"},
|
||||
EntityDefinition {name: "euro", latex_math_mode: false, latex: "\\texteuro{}", html: "€", ascii: "EUR", utf8: "€"},
|
||||
EntityDefinition {name: "copy", latex_math_mode: false, latex: "\\textcopyright{}", html: "©", ascii: "(c)", utf8: "©"},
|
||||
EntityDefinition {name: "sup1", latex_math_mode: false, latex: "\\textonesuperior{}", html: "¹", ascii: "^1", utf8: "¹"},
|
||||
EntityDefinition {name: "sup2", latex_math_mode: false, latex: "\\texttwosuperior{}", html: "²", ascii: "^2", utf8: "²"},
|
||||
EntityDefinition {name: "sup3", latex_math_mode: false, latex: "\\textthreesuperior{}", html: "³", ascii: "^3", utf8: "³"},
|
||||
EntityDefinition {name: "prod", latex_math_mode: true, latex: "\\prod", html: "∏", ascii: "[product]", utf8: "∏"},
|
||||
EntityDefinition {name: "macr", latex_math_mode: false, latex: "\\textasciimacron{}", html: "¯", ascii: "[macron]", utf8: "¯"},
|
||||
EntityDefinition {name: "prop", latex_math_mode: true, latex: "\\propto", html: "∝", ascii: "[proportional to]", utf8: "∝"},
|
||||
EntityDefinition {name: "land", latex_math_mode: true, latex: "\\land", html: "∧", ascii: "[logical and]", utf8: "∧"},
|
||||
EntityDefinition {name: "cong", latex_math_mode: true, latex: "\\cong", html: "≅", ascii: "[approx. equal to]", utf8: "≅"},
|
||||
EntityDefinition {name: "prec", latex_math_mode: true, latex: "\\prec", html: "≺", ascii: "[precedes]", utf8: "≺"},
|
||||
EntityDefinition {name: "succ", latex_math_mode: true, latex: "\\succ", html: "≻", ascii: "[succeeds]", utf8: "≻"},
|
||||
EntityDefinition {name: "nsub", latex_math_mode: true, latex: "\\not\\subset", html: "⊄", ascii: "[not a subset of]", utf8: "⊄"},
|
||||
EntityDefinition {name: "sube", latex_math_mode: true, latex: "\\subseteq", html: "⊆", ascii: "[subset of or equal to]", utf8: "⊆"},
|
||||
EntityDefinition {name: "nsup", latex_math_mode: true, latex: "\\not\\supset", html: "⊅", ascii: "[not a superset of]", utf8: "⊅"},
|
||||
EntityDefinition {name: "supe", latex_math_mode: true, latex: "\\supseteq", html: "⊇", ascii: "[superset of or equal to]", utf8: "⊇"},
|
||||
EntityDefinition {name: "isin", latex_math_mode: true, latex: "\\in", html: "∈", ascii: "[element of]", utf8: "∈"},
|
||||
EntityDefinition {name: "perp", latex_math_mode: true, latex: "\\perp", html: "⊥", ascii: "[up tack]", utf8: "⊥"},
|
||||
EntityDefinition {name: "sdot", latex_math_mode: true, latex: "\\cdot", html: "⋅", ascii: "[dot]", utf8: "⋅"},
|
||||
EntityDefinition {name: "cdot", latex_math_mode: true, latex: "\\cdot", html: "⋅", ascii: "[dot]", utf8: "⋅"},
|
||||
EntityDefinition {name: "lang", latex_math_mode: true, latex: "\\langle", html: "⟨", ascii: "<", utf8: "⟨"},
|
||||
EntityDefinition {name: "rang", latex_math_mode: true, latex: "\\rangle", html: "⟩", ascii: ">", utf8: "⟩"},
|
||||
EntityDefinition {name: "hbar", latex_math_mode: true, latex: "\\hbar", html: "ℏ", ascii: "hbar", utf8: "ℏ"},
|
||||
EntityDefinition {name: "larr", latex_math_mode: true, latex: "\\leftarrow", html: "←", ascii: "<-", utf8: "←"},
|
||||
EntityDefinition {name: "gets", latex_math_mode: true, latex: "\\gets", html: "←", ascii: "<-", utf8: "←"},
|
||||
EntityDefinition {name: "lArr", latex_math_mode: true, latex: "\\Leftarrow", html: "⇐", ascii: "<=", utf8: "⇐"},
|
||||
EntityDefinition {name: "uarr", latex_math_mode: true, latex: "\\uparrow", html: "↑", ascii: "[uparrow]", utf8: "↑"},
|
||||
EntityDefinition {name: "uArr", latex_math_mode: true, latex: "\\Uparrow", html: "⇑", ascii: "[dbluparrow]", utf8: "⇑"},
|
||||
EntityDefinition {name: "rarr", latex_math_mode: true, latex: "\\rightarrow", html: "→", ascii: "->", utf8: "→"},
|
||||
EntityDefinition {name: "rArr", latex_math_mode: true, latex: "\\Rightarrow", html: "⇒", ascii: "=>", utf8: "⇒"},
|
||||
EntityDefinition {name: "darr", latex_math_mode: true, latex: "\\downarrow", html: "↓", ascii: "[downarrow]", utf8: "↓"},
|
||||
EntityDefinition {name: "dArr", latex_math_mode: true, latex: "\\Downarrow", html: "⇓", ascii: "[dbldownarrow]", utf8: "⇓"},
|
||||
EntityDefinition {name: "harr", latex_math_mode: true, latex: "\\leftrightarrow", html: "↔", ascii: "<->", utf8: "↔"},
|
||||
EntityDefinition {name: "hArr", latex_math_mode: true, latex: "\\Leftrightarrow", html: "⇔", ascii: "<=>", utf8: "⇔"},
|
||||
EntityDefinition {name: "cosh", latex_math_mode: true, latex: "\\cosh", html: "cosh", ascii: "cosh", utf8: "cosh"},
|
||||
EntityDefinition {name: "coth", latex_math_mode: true, latex: "\\coth", html: "coth", ascii: "coth", utf8: "coth"},
|
||||
EntityDefinition {name: "sinh", latex_math_mode: true, latex: "\\sinh", html: "sinh", ascii: "sinh", utf8: "sinh"},
|
||||
EntityDefinition {name: "tanh", latex_math_mode: true, latex: "\\tanh", html: "tanh", ascii: "tanh", utf8: "tanh"},
|
||||
EntityDefinition {name: "bull", latex_math_mode: false, latex: "\\textbullet{}", html: "•", ascii: "*", utf8: "•"},
|
||||
EntityDefinition {name: "star", latex_math_mode: true, latex: "\\star", html: "*", ascii: "*", utf8: "⋆"},
|
||||
EntityDefinition {name: "odot", latex_math_mode: true, latex: "\\odot", html: "o", ascii: "[circled dot]", utf8: "ʘ"},
|
||||
EntityDefinition {name: "ordf", latex_math_mode: false, latex: "\\textordfeminine{}", html: "ª", ascii: "_a_", utf8: "ª"},
|
||||
EntityDefinition {name: "ordm", latex_math_mode: false, latex: "\\textordmasculine{}", html: "º", ascii: "_o_", utf8: "º"},
|
||||
EntityDefinition {name: "zwnj", latex_math_mode: false, latex: "\\/{}", html: "‌", ascii: "", utf8: ""},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{1.5em}", html: "   ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "ell", latex_math_mode: true, latex: "\\ell", html: "ℓ", ascii: "ell", utf8: "ℓ"},
|
||||
EntityDefinition {name: "Eta", latex_math_mode: false, latex: "H", html: "Η", ascii: "Eta", utf8: "Η"},
|
||||
EntityDefinition {name: "eta", latex_math_mode: true, latex: "\\eta", html: "η", ascii: "eta", utf8: "η"},
|
||||
EntityDefinition {name: "Rho", latex_math_mode: false, latex: "P", html: "Ρ", ascii: "Rho", utf8: "Ρ"},
|
||||
EntityDefinition {name: "rho", latex_math_mode: true, latex: "\\rho", html: "ρ", ascii: "rho", utf8: "ρ"},
|
||||
EntityDefinition {name: "Tau", latex_math_mode: false, latex: "T", html: "Τ", ascii: "Tau", utf8: "Τ"},
|
||||
EntityDefinition {name: "Phi", latex_math_mode: true, latex: "\\Phi", html: "Φ", ascii: "Phi", utf8: "Φ"},
|
||||
EntityDefinition {name: "phi", latex_math_mode: true, latex: "\\phi", html: "φ", ascii: "phi", utf8: "ɸ"},
|
||||
EntityDefinition {name: "Chi", latex_math_mode: false, latex: "X", html: "Χ", ascii: "Chi", utf8: "Χ"},
|
||||
EntityDefinition {name: "chi", latex_math_mode: true, latex: "\\chi", html: "χ", ascii: "chi", utf8: "χ"},
|
||||
EntityDefinition {name: "Psi", latex_math_mode: true, latex: "\\Psi", html: "Ψ", ascii: "Psi", utf8: "Ψ"},
|
||||
EntityDefinition {name: "psi", latex_math_mode: true, latex: "\\psi", html: "ψ", ascii: "psi", utf8: "ψ"},
|
||||
EntityDefinition {name: "tau", latex_math_mode: true, latex: "\\tau", html: "τ", ascii: "tau", utf8: "τ"},
|
||||
EntityDefinition {name: "piv", latex_math_mode: true, latex: "\\varpi", html: "ϖ", ascii: "omega-pi", utf8: "ϖ"},
|
||||
EntityDefinition {name: "ETH", latex_math_mode: false, latex: "\\DH{}", html: "Ð", ascii: "D", utf8: "Ð"},
|
||||
EntityDefinition {name: "eth", latex_math_mode: false, latex: "\\dh{}", html: "ð", ascii: "dh", utf8: "ð"},
|
||||
EntityDefinition {name: "shy", latex_math_mode: false, latex: "\\-", html: "­", ascii: "", utf8: ""},
|
||||
EntityDefinition {name: "amp", latex_math_mode: false, latex: "\\&", html: "&", ascii: "&", utf8: "&"},
|
||||
EntityDefinition {name: "dag", latex_math_mode: false, latex: "\\dag{}", html: "†", ascii: "[dagger]", utf8: "†"},
|
||||
EntityDefinition {name: "yen", latex_math_mode: false, latex: "\\textyen{}", html: "¥", ascii: "yen", utf8: "¥"},
|
||||
EntityDefinition {name: "EUR", latex_math_mode: false, latex: "\\texteuro{}", html: "€", ascii: "EUR", utf8: "€"},
|
||||
EntityDefinition {name: "USD", latex_math_mode: false, latex: "\\$", html: "$", ascii: "$", utf8: "$"},
|
||||
EntityDefinition {name: "reg", latex_math_mode: false, latex: "\\textregistered{}", html: "®", ascii: "(r)", utf8: "®"},
|
||||
EntityDefinition {name: "div", latex_math_mode: false, latex: "\\textdiv{}", html: "÷", ascii: "/", utf8: "÷"},
|
||||
EntityDefinition {name: "sum", latex_math_mode: true, latex: "\\sum", html: "∑", ascii: "[sum]", utf8: "∑"},
|
||||
EntityDefinition {name: "deg", latex_math_mode: false, latex: "\\textdegree{}", html: "°", ascii: "degree", utf8: "°"},
|
||||
EntityDefinition {name: "not", latex_math_mode: false, latex: "\\textlnot{}", html: "¬", ascii: "[angled dash]", utf8: "¬"},
|
||||
EntityDefinition {name: "neg", latex_math_mode: true, latex: "\\neg{}", html: "¬", ascii: "[angled dash]", utf8: "¬"},
|
||||
EntityDefinition {name: "lor", latex_math_mode: true, latex: "\\lor", html: "∨", ascii: "[logical or]", utf8: "∨"},
|
||||
EntityDefinition {name: "vee", latex_math_mode: true, latex: "\\vee", html: "∨", ascii: "[logical or]", utf8: "∨"},
|
||||
EntityDefinition {name: "cap", latex_math_mode: true, latex: "\\cap", html: "∩", ascii: "[intersection]", utf8: "∩"},
|
||||
EntityDefinition {name: "cup", latex_math_mode: true, latex: "\\cup", html: "∪", ascii: "[union]", utf8: "∪"},
|
||||
EntityDefinition {name: "int", latex_math_mode: true, latex: "\\int", html: "∫", ascii: "[integral]", utf8: "∫"},
|
||||
EntityDefinition {name: "sim", latex_math_mode: true, latex: "\\sim", html: "∼", ascii: "~", utf8: "∼"},
|
||||
EntityDefinition {name: "neq", latex_math_mode: true, latex: "\\neq", html: "≠", ascii: "[not equal to]", utf8: "≠"},
|
||||
EntityDefinition {name: "leq", latex_math_mode: true, latex: "\\le", html: "≤", ascii: "<=", utf8: "≤"},
|
||||
EntityDefinition {name: "geq", latex_math_mode: true, latex: "\\ge", html: "≥", ascii: ">=", utf8: "≥"},
|
||||
EntityDefinition {name: "lll", latex_math_mode: true, latex: "\\lll", html: "⋘", ascii: "<<<", utf8: "⋘"},
|
||||
EntityDefinition {name: "ggg", latex_math_mode: true, latex: "\\ggg", html: "⋙", ascii: ">>>", utf8: "⋙"},
|
||||
EntityDefinition {name: "sub", latex_math_mode: true, latex: "\\subset", html: "⊂", ascii: "[subset of]", utf8: "⊂"},
|
||||
EntityDefinition {name: "sup", latex_math_mode: true, latex: "\\supset", html: "⊃", ascii: "[superset of]", utf8: "⊃"},
|
||||
EntityDefinition {name: "ang", latex_math_mode: true, latex: "\\angle", html: "∠", ascii: "[angle]", utf8: "∠"},
|
||||
EntityDefinition {name: "mho", latex_math_mode: true, latex: "\\mho", html: "℧", ascii: "mho", utf8: "℧"},
|
||||
EntityDefinition {name: "arg", latex_math_mode: true, latex: "\\arg", html: "arg", ascii: "arg", utf8: "arg"},
|
||||
EntityDefinition {name: "cos", latex_math_mode: true, latex: "\\cos", html: "cos", ascii: "cos", utf8: "cos"},
|
||||
EntityDefinition {name: "cot", latex_math_mode: true, latex: "\\cot", html: "cot", ascii: "cot", utf8: "cot"},
|
||||
EntityDefinition {name: "csc", latex_math_mode: true, latex: "\\csc", html: "csc", ascii: "csc", utf8: "csc"},
|
||||
EntityDefinition {name: "deg", latex_math_mode: true, latex: "\\deg", html: "°", ascii: "deg", utf8: "deg"},
|
||||
EntityDefinition {name: "det", latex_math_mode: true, latex: "\\det", html: "det", ascii: "det", utf8: "det"},
|
||||
EntityDefinition {name: "dim", latex_math_mode: true, latex: "\\dim", html: "dim", ascii: "dim", utf8: "dim"},
|
||||
EntityDefinition {name: "exp", latex_math_mode: true, latex: "\\exp", html: "exp", ascii: "exp", utf8: "exp"},
|
||||
EntityDefinition {name: "gcd", latex_math_mode: true, latex: "\\gcd", html: "gcd", ascii: "gcd", utf8: "gcd"},
|
||||
EntityDefinition {name: "hom", latex_math_mode: true, latex: "\\hom", html: "hom", ascii: "hom", utf8: "hom"},
|
||||
EntityDefinition {name: "inf", latex_math_mode: true, latex: "\\inf", html: "inf", ascii: "inf", utf8: "inf"},
|
||||
EntityDefinition {name: "ker", latex_math_mode: true, latex: "\\ker", html: "ker", ascii: "ker", utf8: "ker"},
|
||||
EntityDefinition {name: "lim", latex_math_mode: true, latex: "\\lim", html: "lim", ascii: "lim", utf8: "lim"},
|
||||
EntityDefinition {name: "log", latex_math_mode: true, latex: "\\log", html: "log", ascii: "log", utf8: "log"},
|
||||
EntityDefinition {name: "max", latex_math_mode: true, latex: "\\max", html: "max", ascii: "max", utf8: "max"},
|
||||
EntityDefinition {name: "min", latex_math_mode: true, latex: "\\min", html: "min", ascii: "min", utf8: "min"},
|
||||
EntityDefinition {name: "sec", latex_math_mode: true, latex: "\\sec", html: "sec", ascii: "sec", utf8: "sec"},
|
||||
EntityDefinition {name: "sin", latex_math_mode: true, latex: "\\sin", html: "sin", ascii: "sin", utf8: "sin"},
|
||||
EntityDefinition {name: "sup", latex_math_mode: true, latex: "\\sup", html: "⊃", ascii: "sup", utf8: "sup"},
|
||||
EntityDefinition {name: "tan", latex_math_mode: true, latex: "\\tan", html: "tan", ascii: "tan", utf8: "tan"},
|
||||
EntityDefinition {name: "ast", latex_math_mode: true, latex: "\\ast", html: "∗", ascii: "*", utf8: "*"},
|
||||
EntityDefinition {name: "uml", latex_math_mode: false, latex: "\\textasciidieresis{}", html: "¨", ascii: "[diaeresis]", utf8: "¨"},
|
||||
EntityDefinition {name: "zwj", latex_math_mode: false, latex: "", html: "‍", ascii: "", utf8: ""},
|
||||
EntityDefinition {name: "lrm", latex_math_mode: false, latex: "", html: "‎", ascii: "", utf8: ""},
|
||||
EntityDefinition {name: "rlm", latex_math_mode: false, latex: "", html: "‏", ascii: "", utf8: ""},
|
||||
EntityDefinition {name: "sad", latex_math_mode: true, latex: "\\ddot\\frown", html: "☹", ascii: ":-(", utf8: "☹"},
|
||||
EntityDefinition {name: "loz", latex_math_mode: true, latex: "\\lozenge", html: "◊", ascii: "[lozenge]", utf8: "⧫"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{1.0em}", html: "  ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "AA", latex_math_mode: false, latex: "\\AA{}", html: "Å", ascii: "A", utf8: "Å"},
|
||||
EntityDefinition {name: "Mu", latex_math_mode: false, latex: "M", html: "Μ", ascii: "Mu", utf8: "Μ"},
|
||||
EntityDefinition {name: "mu", latex_math_mode: true, latex: "\\mu", html: "μ", ascii: "mu", utf8: "μ"},
|
||||
EntityDefinition {name: "nu", latex_math_mode: true, latex: "\\nu", html: "ν", ascii: "nu", utf8: "ν"},
|
||||
EntityDefinition {name: "Nu", latex_math_mode: false, latex: "N", html: "Ν", ascii: "Nu", utf8: "Ν"},
|
||||
EntityDefinition {name: "Xi", latex_math_mode: true, latex: "\\Xi", html: "Ξ", ascii: "Xi", utf8: "Ξ"},
|
||||
EntityDefinition {name: "xi", latex_math_mode: true, latex: "\\xi", html: "ξ", ascii: "xi", utf8: "ξ"},
|
||||
EntityDefinition {name: "Pi", latex_math_mode: true, latex: "\\Pi", html: "Π", ascii: "Pi", utf8: "Π"},
|
||||
EntityDefinition {name: "pi", latex_math_mode: true, latex: "\\pi", html: "π", ascii: "pi", utf8: "π"},
|
||||
EntityDefinition {name: "lt", latex_math_mode: false, latex: "\\textless{}", html: "<", ascii: "<", utf8: "<"},
|
||||
EntityDefinition {name: "gt", latex_math_mode: false, latex: "\\textgreater{}", html: ">", ascii: ">", utf8: ">"},
|
||||
EntityDefinition {name: "pm", latex_math_mode: false, latex: "\\textpm{}", html: "±", ascii: "+-", utf8: "±"},
|
||||
EntityDefinition {name: "ne", latex_math_mode: true, latex: "\\ne", html: "≠", ascii: "[not equal to]", utf8: "≠"},
|
||||
EntityDefinition {name: "le", latex_math_mode: true, latex: "\\le", html: "≤", ascii: "<=", utf8: "≤"},
|
||||
EntityDefinition {name: "ge", latex_math_mode: true, latex: "\\ge", html: "≥", ascii: ">=", utf8: "≥"},
|
||||
EntityDefinition {name: "ll", latex_math_mode: true, latex: "\\ll", html: "≪", ascii: "<<", utf8: "≪"},
|
||||
EntityDefinition {name: "Ll", latex_math_mode: true, latex: "\\lll", html: "⋘", ascii: "<<<", utf8: "⋘"},
|
||||
EntityDefinition {name: "gg", latex_math_mode: true, latex: "\\gg", html: "≫", ascii: ">>", utf8: "≫"},
|
||||
EntityDefinition {name: "Gg", latex_math_mode: true, latex: "\\ggg", html: "⋙", ascii: ">>>", utf8: "⋙"},
|
||||
EntityDefinition {name: "in", latex_math_mode: true, latex: "\\in", html: "∈", ascii: "[element of]", utf8: "∈"},
|
||||
EntityDefinition {name: "ni", latex_math_mode: true, latex: "\\ni", html: "∋", ascii: "[contains as member]", utf8: "∋"},
|
||||
EntityDefinition {name: "to", latex_math_mode: true, latex: "\\to", html: "→", ascii: "->", utf8: "→"},
|
||||
EntityDefinition {name: "lg", latex_math_mode: true, latex: "\\lg", html: "lg", ascii: "lg", utf8: "lg"},
|
||||
EntityDefinition {name: "ln", latex_math_mode: true, latex: "\\ln", html: "ln", ascii: "ln", utf8: "ln"},
|
||||
EntityDefinition {name: "Pr", latex_math_mode: true, latex: "\\Pr", html: "Pr", ascii: "Pr", utf8: "Pr"},
|
||||
EntityDefinition {name: "_ ", latex_math_mode: false, latex: "\\hspace*{0.5em}", html: " ", ascii: " ", utf8: " "},
|
||||
EntityDefinition {name: "S", latex_math_mode: false, latex: "\\S", html: "§", ascii: "section", utf8: "§"},
|
||||
EntityDefinition {name: "P", latex_math_mode: false, latex: "\\P{}", html: "¶", ascii: "paragraph", utf8: "¶"},
|
||||
];
|
||||
@@ -12,7 +12,6 @@ use crate::error::CustomError;
|
||||
use crate::error::MyError;
|
||||
use crate::error::Res;
|
||||
use crate::parser::OrgSource;
|
||||
use crate::types::Keyword;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ContextElement<'r, 's> {
|
||||
@@ -22,28 +21,14 @@ pub(crate) enum ContextElement<'r, 's> {
|
||||
/// Stores the name of the current element to prevent directly nesting elements of the same type.
|
||||
Context(&'r str),
|
||||
|
||||
/// Stores the name of the current object to prevent directly nesting elements of the same type.
|
||||
ContextObject(&'r str),
|
||||
|
||||
/// Indicates if elements should consume the whitespace after them.
|
||||
ConsumeTrailingWhitespace(bool),
|
||||
|
||||
/// Indicate that we are parsing a paragraph that already has affiliated keywords.
|
||||
///
|
||||
/// The value stored is the start of the element after the affiliated keywords. In this way, we can ensure that we do not exit an element immediately after the affiliated keyword had been consumed.
|
||||
HasAffiliatedKeyword(HasAffiliatedKeywordInner<'r, 's>),
|
||||
|
||||
/// This is just here to use the 's lifetime until I'm sure we can eliminate it from ContextElement.
|
||||
#[allow(dead_code)]
|
||||
Placeholder(PhantomData<&'s str>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct HasAffiliatedKeywordInner<'r, 's> {
|
||||
pub(crate) start_after_affiliated_keywords: OrgSource<'s>,
|
||||
pub(crate) keywords: &'r Vec<Keyword<'s>>,
|
||||
}
|
||||
|
||||
pub(crate) struct ExitMatcherNode<'r> {
|
||||
// TODO: Should this be "&'r DynContextMatcher<'c>" ?
|
||||
pub(crate) exit_matcher: &'r DynContextMatcher<'r>,
|
||||
@@ -116,7 +101,10 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(self))
|
||||
)]
|
||||
pub(crate) fn check_exit_matcher(
|
||||
&'r self,
|
||||
i: OrgSource<'s>,
|
||||
@@ -163,7 +151,10 @@ impl<'g, 'r, 's> Context<'g, 'r, 's> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(_context))
|
||||
)]
|
||||
fn document_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(any(feature = "compare", feature = "foreign_document_test"))]
|
||||
pub trait FileAccessInterface: Sync + Debug {
|
||||
fn read_file(&self, path: &str) -> Result<String, std::io::Error>;
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "compare", feature = "foreign_document_test")))]
|
||||
pub trait FileAccessInterface: Debug {
|
||||
fn read_file(&self, path: &str) -> Result<String, std::io::Error>;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use super::constants::DEFAULT_ORG_ENTITIES;
|
||||
use super::constants::DEFAULT_ORG_LINK_PARAMETERS;
|
||||
use super::FileAccessInterface;
|
||||
use super::LocalFileAccessInterface;
|
||||
use crate::context::constants::DEFAULT_ORG_ELEMENT_AFFILIATED_KEYWORDS;
|
||||
use crate::context::constants::DEFAULT_ORG_ELEMENT_DUAL_KEYWORDS;
|
||||
use crate::context::constants::DEFAULT_ORG_ELEMENT_KEYWORD_TRANSLATION_ALIST;
|
||||
use crate::context::constants::DEFAULT_ORG_ELEMENT_PARSED_KEYWORDS;
|
||||
use crate::types::IndentationLevel;
|
||||
use crate::types::Object;
|
||||
|
||||
@@ -34,11 +40,6 @@ pub struct GlobalSettings<'g, 's> {
|
||||
/// Corresponds to org-footnote-section elisp variable.
|
||||
pub footnote_section: &'g str,
|
||||
|
||||
/// The label format for references inside src/example blocks.
|
||||
///
|
||||
/// Corresponds to org-coderef-label-format elisp variable.
|
||||
pub coderef_label_format: &'g str,
|
||||
|
||||
/// The allowed protocols for links (for example, the "https" in "https://foo.bar/").
|
||||
///
|
||||
/// Corresponds to org-link-parameters elisp variable.
|
||||
@@ -50,12 +51,53 @@ pub struct GlobalSettings<'g, 's> {
|
||||
///
|
||||
/// This is set by including #+LINK in the org-mode document.
|
||||
pub link_templates: BTreeMap<String, String>,
|
||||
|
||||
/// The special characters that can be written in org-mode like \infin for the infinity symbol.
|
||||
///
|
||||
/// MUST be sorted with the largest names first. Otherwise the parser may match a shorter substring of a longer entity.
|
||||
///
|
||||
/// Corresponds to org-entities elisp variable.
|
||||
pub entities: &'g [EntityDefinition<'s>],
|
||||
|
||||
/// Keywords that contain the standard set of objects (excluding footnote references).
|
||||
///
|
||||
/// Corresponds to org-element-parsed-keywords elisp variable.
|
||||
pub element_parsed_keywords: &'g [&'s str],
|
||||
|
||||
/// Keywords that can have a secondary value in square brackets.
|
||||
///
|
||||
/// Corresponds to org-element-dual-keywords elisp variable.
|
||||
pub element_dual_keywords: &'g [&'s str],
|
||||
|
||||
/// Keywords that can be affiliated with an element.
|
||||
///
|
||||
/// Corresponds to org-element-affiliated-keywords elisp variable.
|
||||
pub element_affiliated_keywords: &'g [&'s str],
|
||||
|
||||
/// Mapping of keyword names.
|
||||
///
|
||||
/// Corresponds to org-element-keyword-translation-alist elisp variable.
|
||||
pub element_keyword_translation_alist: &'g [(&'s str, &'s str)],
|
||||
}
|
||||
|
||||
pub const DEFAULT_TAB_WIDTH: IndentationLevel = 8;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EntityDefinition<'a> {
|
||||
pub name: &'a str,
|
||||
pub latex_math_mode: bool,
|
||||
pub latex: &'a str,
|
||||
pub html: &'a str,
|
||||
pub ascii: &'a str,
|
||||
// Skipping latin1 because it is detrimental to the future. If anyone out there is using latin1, take a long look in the mirror and change your ways.
|
||||
pub utf8: &'a str,
|
||||
}
|
||||
|
||||
impl<'g, 's> GlobalSettings<'g, 's> {
|
||||
fn new() -> GlobalSettings<'g, 's> {
|
||||
debug_assert!(
|
||||
DEFAULT_ORG_ENTITIES.is_sorted_by(|a, b| b.name.len().partial_cmp(&a.name.len()))
|
||||
);
|
||||
GlobalSettings {
|
||||
radio_targets: Vec::new(),
|
||||
file_access: &LocalFileAccessInterface {
|
||||
@@ -67,9 +109,13 @@ impl<'g, 's> GlobalSettings<'g, 's> {
|
||||
tab_width: DEFAULT_TAB_WIDTH,
|
||||
odd_levels_only: HeadlineLevelFilter::default(),
|
||||
footnote_section: "Footnotes",
|
||||
coderef_label_format: "(ref:%s)",
|
||||
link_parameters: &DEFAULT_ORG_LINK_PARAMETERS,
|
||||
link_templates: BTreeMap::new(),
|
||||
entities: &DEFAULT_ORG_ENTITIES,
|
||||
element_parsed_keywords: &DEFAULT_ORG_ELEMENT_PARSED_KEYWORDS,
|
||||
element_dual_keywords: &DEFAULT_ORG_ELEMENT_DUAL_KEYWORDS,
|
||||
element_affiliated_keywords: &DEFAULT_ORG_ELEMENT_AFFILIATED_KEYWORDS,
|
||||
element_keyword_translation_alist: &DEFAULT_ORG_ELEMENT_KEYWORD_TRANSLATION_ALIST,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,29 +137,3 @@ impl Default for HeadlineLevelFilter {
|
||||
HeadlineLevelFilter::OddEven
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_ORG_LINK_PARAMETERS: [&'static str; 23] = [
|
||||
"id",
|
||||
"eww",
|
||||
"rmail",
|
||||
"mhe",
|
||||
"irc",
|
||||
"info",
|
||||
"gnus",
|
||||
"docview",
|
||||
"bibtex",
|
||||
"bbdb",
|
||||
"w3m",
|
||||
"doi",
|
||||
"file+sys",
|
||||
"file+emacs",
|
||||
"shell",
|
||||
"news",
|
||||
"mailto",
|
||||
"https",
|
||||
"http",
|
||||
"ftp",
|
||||
"help",
|
||||
"file",
|
||||
"elisp",
|
||||
];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::error::Res;
|
||||
use crate::parser::OrgSource;
|
||||
|
||||
mod constants;
|
||||
mod context;
|
||||
mod exiting;
|
||||
mod file_access_interface;
|
||||
@@ -21,10 +22,10 @@ type DynMatcher<'c> = dyn Matcher + 'c;
|
||||
pub(crate) use context::Context;
|
||||
pub(crate) use context::ContextElement;
|
||||
pub(crate) use context::ExitMatcherNode;
|
||||
pub(crate) use context::HasAffiliatedKeywordInner;
|
||||
pub(crate) use exiting::ExitClass;
|
||||
pub use file_access_interface::FileAccessInterface;
|
||||
pub use file_access_interface::LocalFileAccessInterface;
|
||||
pub use global_settings::EntityDefinition;
|
||||
pub use global_settings::GlobalSettings;
|
||||
pub use global_settings::HeadlineLevelFilter;
|
||||
pub use global_settings::DEFAULT_TAB_WIDTH;
|
||||
|
||||
@@ -11,7 +11,14 @@ macro_rules! children_iter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next.next().map(Into::<AstNode>::into)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let size = self.next.len();
|
||||
(size, Some(size))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> ExactSizeIterator for $itertype<'r, 's> {}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
@@ -42,7 +49,13 @@ macro_rules! empty_iter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
None
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
(0, Some(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> ExactSizeIterator for $itertype<'r, 's> {}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
@@ -79,7 +92,14 @@ $fieldname: $innertype,
|
||||
.or_else(|| self.$fieldname.next().map(Into::<AstNode>::into))
|
||||
),*
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let size = self.$firstfieldname.len()$( + self.$fieldname.len() ),*;
|
||||
(size, Some(size))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 's> ExactSizeIterator for $itertype<'r, 's> {}
|
||||
|
||||
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||
type Item = AstNode<'r, 's>;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![feature(exit_status_error)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(path_file_prefix)]
|
||||
#![feature(is_sorted)]
|
||||
// TODO: #![warn(missing_docs)]
|
||||
|
||||
#[cfg(feature = "compare")]
|
||||
|
||||
160
src/parser/affiliated_keyword.rs
Normal file
160
src/parser/affiliated_keyword.rs
Normal file
@@ -0,0 +1,160 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take_until;
|
||||
use nom::character::complete::anychar;
|
||||
use nom::combinator::all_consuming;
|
||||
use nom::combinator::eof;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::map_parser;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::peek;
|
||||
use nom::combinator::recognize;
|
||||
use nom::multi::many0;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
|
||||
use super::object_parser::standard_set_object;
|
||||
use super::util::confine_context;
|
||||
use crate::context::parser_with_context;
|
||||
use crate::context::Context;
|
||||
use crate::context::ContextElement;
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::types::AffiliatedKeywordValue;
|
||||
use crate::types::AffiliatedKeywords;
|
||||
use crate::types::Keyword;
|
||||
|
||||
pub(crate) fn parse_affiliated_keywords<'g, 's, AK>(
|
||||
global_settings: &'g GlobalSettings<'g, 's>,
|
||||
input: AK,
|
||||
) -> AffiliatedKeywords<'s>
|
||||
where
|
||||
AK: IntoIterator<Item = Keyword<'s>>,
|
||||
{
|
||||
let mut ret = BTreeMap::new();
|
||||
for kw in input {
|
||||
let translated_name = translate_name(global_settings, kw.key);
|
||||
if is_single_string_keyword(global_settings, translated_name.as_str()) {
|
||||
ret.insert(
|
||||
translated_name,
|
||||
AffiliatedKeywordValue::SingleString(kw.value),
|
||||
);
|
||||
} else if is_list_of_single_string_keyword(global_settings, translated_name.as_str()) {
|
||||
let list_of_strings = ret
|
||||
.entry(translated_name)
|
||||
.or_insert_with(|| AffiliatedKeywordValue::ListOfStrings(Vec::with_capacity(1)));
|
||||
match list_of_strings {
|
||||
AffiliatedKeywordValue::ListOfStrings(list_of_strings)
|
||||
if list_of_strings.is_empty() =>
|
||||
{
|
||||
list_of_strings.push(kw.value);
|
||||
}
|
||||
AffiliatedKeywordValue::ListOfStrings(list_of_strings) => {
|
||||
list_of_strings.clear();
|
||||
list_of_strings.push(kw.value);
|
||||
}
|
||||
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
||||
}
|
||||
} else if is_list_of_objects_keyword(global_settings, translated_name.as_str()) {
|
||||
let initial_context = ContextElement::document_context();
|
||||
let initial_context = Context::new(global_settings, List::new(&initial_context));
|
||||
|
||||
let (_remaining, optional_objects) = opt(all_consuming(map(
|
||||
tuple((
|
||||
take_until("["),
|
||||
tag("["),
|
||||
map_parser(
|
||||
recognize(many_till(anychar, peek(tuple((tag("]"), eof))))),
|
||||
confine_context(|i| {
|
||||
all_consuming(many0(parser_with_context!(standard_set_object)(
|
||||
&initial_context,
|
||||
)))(i)
|
||||
}),
|
||||
),
|
||||
tag("]"),
|
||||
eof,
|
||||
)),
|
||||
|(_, _, objects, _, _)| objects,
|
||||
)))(kw.key.into())
|
||||
.expect("Object parser should always succeed.");
|
||||
|
||||
// TODO: This should be omitting footnote references
|
||||
let (_remaining, objects) = all_consuming(many0(parser_with_context!(
|
||||
standard_set_object
|
||||
)(&initial_context)))(kw.value.into())
|
||||
.expect("Object parser should always succeed.");
|
||||
let list_of_lists = ret.entry(translated_name).or_insert_with(|| {
|
||||
AffiliatedKeywordValue::ListOfListsOfObjects(Vec::with_capacity(1))
|
||||
});
|
||||
match list_of_lists {
|
||||
AffiliatedKeywordValue::ListOfListsOfObjects(list_of_lists) => {
|
||||
list_of_lists.push((optional_objects, objects));
|
||||
}
|
||||
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
||||
}
|
||||
} else {
|
||||
let list_of_strings = ret
|
||||
.entry(translated_name)
|
||||
.or_insert_with(|| AffiliatedKeywordValue::ListOfStrings(Vec::with_capacity(1)));
|
||||
match list_of_strings {
|
||||
AffiliatedKeywordValue::ListOfStrings(list_of_strings) => {
|
||||
list_of_strings.push(kw.value);
|
||||
}
|
||||
_ => panic!("Invalid AffiliatedKeywordValue type."),
|
||||
}
|
||||
}
|
||||
}
|
||||
AffiliatedKeywords { keywords: ret }
|
||||
}
|
||||
|
||||
fn translate_name<'g, 's>(global_settings: &'g GlobalSettings<'g, 's>, name: &'s str) -> String {
|
||||
let name_until_optval = name
|
||||
.split_once("[")
|
||||
.map(|(before, _after)| before)
|
||||
.unwrap_or(name);
|
||||
for (src, dst) in global_settings.element_keyword_translation_alist {
|
||||
if name_until_optval.eq_ignore_ascii_case(src) {
|
||||
return dst.to_lowercase();
|
||||
}
|
||||
}
|
||||
name_until_optval.to_lowercase()
|
||||
}
|
||||
|
||||
fn is_single_string_keyword<'g, 's>(
|
||||
_global_settings: &'g GlobalSettings<'g, 's>,
|
||||
name: &'s str,
|
||||
) -> bool {
|
||||
// TODO: Is this defined by an elisp variable?
|
||||
for single_string_name in ["plot", "name"] {
|
||||
if name.eq_ignore_ascii_case(single_string_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_list_of_single_string_keyword<'g, 's>(
|
||||
_global_settings: &'g GlobalSettings<'g, 's>,
|
||||
name: &'s str,
|
||||
) -> bool {
|
||||
// TODO: Is this defined by an elisp variable?
|
||||
for single_string_name in ["results"] {
|
||||
if name.eq_ignore_ascii_case(single_string_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_list_of_objects_keyword<'g, 's>(
|
||||
global_settings: &'g GlobalSettings<'g, 's>,
|
||||
name: &'s str,
|
||||
) -> bool {
|
||||
for parsed_keyword in global_settings.element_parsed_keywords {
|
||||
if name.eq_ignore_ascii_case(parsed_keyword) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -29,7 +29,10 @@ use crate::parser::util::get_consumed;
|
||||
use crate::types::AngleLink;
|
||||
use crate::types::LinkType;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn angle_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -68,7 +71,10 @@ struct PathAngle<'s> {
|
||||
application: Option<&'s str>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn path_angle<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -83,7 +89,10 @@ fn path_angle<'b, 'g, 'r, 's>(
|
||||
Ok((remaining, path))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(_context))
|
||||
)]
|
||||
fn path_angle_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -91,7 +100,10 @@ fn path_angle_end<'b, 'g, 'r, 's>(
|
||||
tag(">")(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn parse_angle_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -102,7 +114,10 @@ fn parse_angle_link<'b, 'g, 'r, 's>(
|
||||
))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn parse_file_angle_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -137,7 +152,10 @@ fn parse_file_angle_link<'b, 'g, 'r, 's>(
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn parse_protocol_angle_link<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
|
||||
@@ -9,14 +9,12 @@ use nom::combinator::opt;
|
||||
use nom::combinator::peek;
|
||||
use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
use nom::multi::many0;
|
||||
use nom::multi::many_till;
|
||||
use nom::sequence::tuple;
|
||||
use nom::InputTake;
|
||||
|
||||
use super::keyword::affiliated_keyword;
|
||||
use super::affiliated_keyword::parse_affiliated_keywords;
|
||||
use super::org_source::BracketDepth;
|
||||
use super::util::get_name;
|
||||
use super::util::maybe_consume_trailing_whitespace_if_not_exiting;
|
||||
use super::util::start_of_line;
|
||||
use super::OrgSource;
|
||||
@@ -28,14 +26,21 @@ use crate::error::Res;
|
||||
use crate::parser::util::get_consumed;
|
||||
use crate::parser::util::org_line_ending;
|
||||
use crate::types::BabelCall;
|
||||
use crate::types::Keyword;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
pub(crate) fn babel_call<'b, 'g, 'r, 's>(
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context, affiliated_keywords))
|
||||
)]
|
||||
pub(crate) fn babel_call<'b, 'g, 'r, 's, AK>(
|
||||
affiliated_keywords: AK,
|
||||
remaining: OrgSource<'s>,
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, BabelCall<'s>> {
|
||||
let (remaining, affiliated_keywords) = many0(affiliated_keyword)(input)?;
|
||||
|
||||
) -> Res<OrgSource<'s>, BabelCall<'s>>
|
||||
where
|
||||
AK: IntoIterator<Item = Keyword<'s>>,
|
||||
{
|
||||
start_of_line(remaining)?;
|
||||
let (remaining, _) = tuple((space0, tag("#+"), tag_no_case("call"), tag(":")))(remaining)?;
|
||||
|
||||
@@ -47,7 +52,10 @@ pub(crate) fn babel_call<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
BabelCall {
|
||||
source: Into::<&str>::into(source),
|
||||
name: get_name(&affiliated_keywords),
|
||||
affiliated_keywords: parse_affiliated_keywords(
|
||||
context.get_global_settings(),
|
||||
affiliated_keywords,
|
||||
),
|
||||
value: Into::<&str>::into(line_break.take(0)),
|
||||
call: None,
|
||||
inside_header: None,
|
||||
@@ -70,7 +78,10 @@ pub(crate) fn babel_call<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
BabelCall {
|
||||
source: Into::<&str>::into(source),
|
||||
name: get_name(&affiliated_keywords),
|
||||
affiliated_keywords: parse_affiliated_keywords(
|
||||
context.get_global_settings(),
|
||||
affiliated_keywords,
|
||||
),
|
||||
value: Into::<&str>::into(value).trim_end(),
|
||||
call: call.map(Into::<&str>::into),
|
||||
inside_header: inside_header.map(Into::<&str>::into),
|
||||
|
||||
@@ -2,6 +2,7 @@ use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::tag_no_case;
|
||||
use nom::character::complete::anychar;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::recognize;
|
||||
use nom::combinator::verify;
|
||||
@@ -30,24 +31,27 @@ use crate::parser::util::get_consumed;
|
||||
use crate::types::Citation;
|
||||
use crate::types::Object;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn citation<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, Citation<'s>> {
|
||||
// TODO: Despite being a standard object, citations cannot exist inside the global prefix/suffix for other citations because citations must contain something that matches @key which is forbidden inside the global prefix/suffix. This TODO is to evaluate if its worth putting in an explicit check for this (which can be easily accomplished by checking the output of `get_bracket_depth()`). I suspect its not worth it because I expect, outside of intentionally crafted inputs, this parser will exit immediately inside a citation since it is unlikely to find the "[cite" substring inside a citation global prefix/suffix.
|
||||
let (remaining, _) = tag_no_case("[cite")(input)?;
|
||||
let (remaining, _) = opt(citestyle)(remaining)?;
|
||||
let (remaining, style) = opt(citestyle)(remaining)?;
|
||||
let (remaining, _) = tag(":")(remaining)?;
|
||||
let (remaining, _prefix) =
|
||||
let (remaining, prefix) =
|
||||
must_balance_bracket(opt(parser_with_context!(global_prefix)(context)))(remaining)?;
|
||||
|
||||
let (remaining, _references) =
|
||||
let (remaining, references) =
|
||||
separated_list1(tag(";"), parser_with_context!(citation_reference)(context))(remaining)?;
|
||||
let (remaining, _suffix) = must_balance_bracket(opt(tuple((
|
||||
tag(";"),
|
||||
parser_with_context!(global_suffix)(context),
|
||||
))))(remaining)?;
|
||||
let (remaining, suffix) = must_balance_bracket(opt(map(
|
||||
tuple((tag(";"), parser_with_context!(global_suffix)(context))),
|
||||
|(_, suffix)| suffix,
|
||||
)))(remaining)?;
|
||||
let (remaining, _) = tag("]")(remaining)?;
|
||||
let (remaining, _trailing_whitespace) =
|
||||
maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?;
|
||||
@@ -56,16 +60,23 @@ pub(crate) fn citation<'b, 'g, 'r, 's>(
|
||||
remaining,
|
||||
Citation {
|
||||
source: source.into(),
|
||||
style: style.map(Into::<&str>::into),
|
||||
prefix: prefix.unwrap_or(Vec::new()),
|
||||
suffix: suffix.unwrap_or(Vec::new()),
|
||||
children: references,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
fn citestyle<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, _) = tuple((tag("/"), style))(input)?;
|
||||
let (remaining, _) = opt(tuple((tag("/"), variant)))(remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
Ok((remaining, source))
|
||||
map(
|
||||
tuple((
|
||||
tag("/"),
|
||||
recognize(tuple((style, opt(tuple((tag("/"), variant)))))),
|
||||
)),
|
||||
|(_, style)| style,
|
||||
)(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
@@ -82,7 +93,10 @@ fn variant<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
})))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn global_prefix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -108,7 +122,10 @@ fn global_prefix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatche
|
||||
move |context, input: OrgSource<'_>| _global_prefix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn _global_prefix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -131,7 +148,10 @@ fn _global_prefix_end<'b, 'g, 'r, 's>(
|
||||
))(input)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn global_suffix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -156,7 +176,10 @@ fn global_suffix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatche
|
||||
move |context, input: OrgSource<'_>| _global_suffix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn _global_suffix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -186,6 +209,7 @@ mod tests {
|
||||
use crate::context::GlobalSettings;
|
||||
use crate::context::List;
|
||||
use crate::parser::element_parser::element;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Element;
|
||||
use crate::types::GetStandardProperties;
|
||||
|
||||
@@ -213,7 +237,16 @@ mod tests {
|
||||
.get(0)
|
||||
.expect("Len already asserted to be 1"),
|
||||
&Object::Citation(Citation {
|
||||
source: "[cite:@foo]"
|
||||
source: "[cite:@foo]",
|
||||
style: None,
|
||||
prefix: vec![],
|
||||
suffix: vec![],
|
||||
children: vec![CitationReference {
|
||||
source: "@foo",
|
||||
key: "foo",
|
||||
prefix: vec![],
|
||||
suffix: vec![]
|
||||
}]
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::anychar;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::not;
|
||||
use nom::combinator::opt;
|
||||
use nom::combinator::recognize;
|
||||
@@ -28,47 +29,65 @@ use crate::parser::util::WORD_CONSTITUENT_CHARACTERS;
|
||||
use crate::types::CitationReference;
|
||||
use crate::types::Object;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn citation_reference<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, CitationReference<'s>> {
|
||||
let (remaining, _prefix) =
|
||||
let (remaining, prefix) =
|
||||
must_balance_bracket(opt(parser_with_context!(key_prefix)(context)))(input)?;
|
||||
let (remaining, _key) = parser_with_context!(citation_reference_key)(context)(remaining)?;
|
||||
let (remaining, _suffix) =
|
||||
let (remaining, key) = parser_with_context!(citation_reference_key)(context)(remaining)?;
|
||||
let (remaining, suffix) =
|
||||
must_balance_bracket(opt(parser_with_context!(key_suffix)(context)))(remaining)?;
|
||||
let without_closing_semi_remaining = remaining;
|
||||
let (remaining, _closing_semi) = opt(tag(";"))(remaining)?;
|
||||
let source = get_consumed(input, remaining);
|
||||
|
||||
Ok((
|
||||
remaining,
|
||||
without_closing_semi_remaining,
|
||||
CitationReference {
|
||||
source: source.into(),
|
||||
key: key.into(),
|
||||
prefix: prefix.unwrap_or(Vec::new()),
|
||||
suffix: suffix.unwrap_or(Vec::new()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn citation_reference_key<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||
let (remaining, source) = recognize(tuple((
|
||||
let (remaining, source) = map(
|
||||
tuple((
|
||||
tag("@"),
|
||||
many1(verify(
|
||||
recognize(many1(verify(
|
||||
preceded(
|
||||
not(parser_with_context!(exit_matcher_parser)(context)),
|
||||
anychar,
|
||||
),
|
||||
|c| {
|
||||
WORD_CONSTITUENT_CHARACTERS.contains(*c) || "-.:?~`'/*@+|(){}<>&_^$#%~".contains(*c)
|
||||
WORD_CONSTITUENT_CHARACTERS.contains(*c)
|
||||
|| "-.:?~`'/*@+|(){}<>&_^$#%~".contains(*c)
|
||||
},
|
||||
))),
|
||||
)),
|
||||
)))(input)?;
|
||||
|(_, key)| key,
|
||||
)(input)?;
|
||||
Ok((remaining, source))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn key_prefix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -89,7 +108,10 @@ fn key_prefix<'b, 'g, 'r, 's>(
|
||||
Ok((remaining, children))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn key_suffix<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -114,7 +136,10 @@ fn key_prefix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _key_prefix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn _key_prefix_end<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -141,7 +166,10 @@ fn key_suffix_end(starting_bracket_depth: BracketDepth) -> impl ContextMatcher {
|
||||
move |context, input: OrgSource<'_>| _key_suffix_end(context, input, starting_bracket_depth)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(_context))
|
||||
)]
|
||||
fn _key_suffix_end<'b, 'g, 'r, 's>(
|
||||
_context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
|
||||
@@ -24,7 +24,10 @@ use crate::types::Clock;
|
||||
use crate::types::ClockStatus;
|
||||
use crate::types::Timestamp;
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
pub(crate) fn clock<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
@@ -55,7 +58,10 @@ pub(crate) fn clock<'b, 'g, 'r, 's>(
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(ret, level = "debug", skip(context))
|
||||
)]
|
||||
fn clock_timestamp<'b, 'g, 'r, 's>(
|
||||
context: RefContext<'b, 'g, 'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user