Commit 9fa31b5f authored by phil's avatar phil

parse sections and move mean test to a different namespace

parent da01b503
......@@ -6,6 +6,15 @@ A Clojure library designed to ... well, that part is up to you.
FIXME
## References
- https://orgmode.org/worg/dev/org-syntax.html
- https://orgmode.org/worg/dev/org-element-api.html
- https://github.com/Engelberg/instaparse
- https://en.wikipedia.org/wiki/Context-free_grammar
- https://en.wikipedia.org/wiki/Parsing_expression_grammar
- https://www.regular-expressions.info
## License
Copyright © 2019 [200ok llc](https://200ok.ch/).
......@@ -13,4 +22,3 @@ Copyright © 2019 [200ok llc](https://200ok.ch/).
This program and the accompanying materials are made available under
the terms of the GNU Affero General Public License Version 3 which is
made available at https://www.gnu.org/licenses/agpl-3.0.en.html.
S = (headline|emptyline)*
<s> = <#"\s+">
whitespace = #'\s'
<s> = <#"[ \t]+">
endofline = #'$'
newline = '\n'
<eol> = <(newline|endofline)>
(* <eol = #"(\R|$|\z)" *)
<word> = #'[^\n\s]+'
emptyline = whitespace* <(newline|endofline)>
emptyline = [s] <(newline|endofline)>
headline = stars [s priority] [s comment-flag] s title [s tags] eol
stars = #'\*+'
......@@ -18,6 +18,11 @@ tags = <':'> ( tag <':'> )+
<tag> = #'[a-zA-Z0-9_@#%]+'
<contentline> = #".*"
content = {(emptyline|!headline contentline) eol}
section = headline (content|epsilon)
sections = {section}
(* UNTESTED
affiliated_keywords = "#+" (key | attr_backend) ": " value
......@@ -27,10 +32,10 @@ key = "HEADER" | "NAME" | "PLOT" | (("RESULTS" | "CAPTION") [ optional ])
attr_backend = "ATTR_" backend
backend = #"[a-zA-Z0-9-_]+"
greater_block = '#+BEGIN_' name [whitespace parameters] newline contents '#+END_' name
greater_block = '#+BEGIN_' name [s parameters] newline contents '#+END_' name
name = #'[^\s]+'
parameters = #'[^\n]+'
dynamic_block = '#+BEGIN:' whitespace name [whitespace parameters] contents '#+END:'
dynamic_block = '#+BEGIN:' s name [s parameters] contents '#+END:'
*)
(ns org-parser.parser-test
(:require [org-parser.parser :as parser]
#?(:clj [clojure.test :as t :refer :all]
:cljs [cljs.test :as t :include-macros true])))
(deftest headline
(let [parse #(parser/org % :start :headline)]
(testing "with crazy characters in title"
(is (= [:headline [:stars "*****"] [:title "hello" "wörld⛄" ":"]]
(parse "***** hello wörld⛄ :"))))))
......@@ -3,6 +3,21 @@
#?(:clj [clojure.test :as t :refer :all]
:cljs [cljs.test :as t :include-macros true])))
;; if parse is successful it returns a vector otherwise a map
(deftest word
(let [parse #(parser/org % :start :word)]
(testing "single"
(is (= ["a"]
(parse "a"))))
(testing "single with trailing space"
(is (map? (parse "ab "))))
(testing "single with trailing newline"
(is (map? (parse "a\n"))))))
(deftest tags
(let [parse #(parser/org % :start :tags)]
(testing "single"
......@@ -15,6 +30,7 @@
(is (= [:tags "az" "AZ" "09" "_@#%"]
(parse ":az:AZ:09:_@#%:"))))))
(deftest headline
(let [parse #(parser/org % :start :headline)]
(testing "boring"
......@@ -29,9 +45,46 @@
(testing "with priority and tags"
(is (= [:headline [:stars "****"] [:priority "B"] [:title "hello" "world"] [:tags "the" "end"]]
(parse "**** [#B] hello world :the:end:"))))
(testing "title cannot have multiple lines"
(is (map? (parse "* a\nb"))))
(testing "with comment flag"
(is (= [:headline [:stars "*****"] [:comment-flag] [:title "hello" "world"]]
(parse "***** COMMENT hello world"))))
(testing "with crazy characters in title"
(is (= [:headline [:stars "*****"] [:title "hello" "wörld⛄" ":"]]
(parse "***** hello wörld⛄ :"))))))
(parse "***** COMMENT hello world"))))))
(deftest content
(let [parse #(parser/org % :start :content)]
(testing "boring"
(is (= [:content "anything" "goes"]
(parse "anything\ngoes"))))))
(deftest sections
(let [parse #(parser/org % :start :sections)]
(testing "boring"
(is (= [:sections
[:section
[:headline [:stars "*"] [:title "hello" "world"]]
[:content "this is the first section"]]
[:section
[:headline [:stars "**"] [:title "and" "this"]]
[:content "is another section"]]]
(parse "* hello world
this is the first section
** and this
is another section"))))
(testing "boring with empty lines"
(is (= [:sections
[:section
[:headline [:stars "*"] [:title "hello" "world"]]
[:content "this is the first section"]
[:emptyline]]
[:section
[:headline [:stars "**"] [:title "and" "this"]]
[:content [:emptyline] "is another section"]]]
(parse "* hello world
this is the first section
** and this
is another section"))))))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment