Parse headlines (but don’t do or show anything special)
This commit is contained in:
parent
a5bc9ba86b
commit
f4967150e4
4 changed files with 86 additions and 11 deletions
|
|
@ -3,12 +3,16 @@
|
|||
(:export #:org-node
|
||||
#:org-document
|
||||
#:org-line
|
||||
#:org-headline
|
||||
#:previous-of
|
||||
#:next-of
|
||||
#:raw-text-of
|
||||
#:line-ending-of
|
||||
#:depth-of
|
||||
#:title-of
|
||||
#:make-org-document
|
||||
#:make-org-line
|
||||
#:make-org-headline
|
||||
#:append-node
|
||||
#:collect-nodes))
|
||||
(in-package :sextant/org/nodes)
|
||||
|
|
@ -40,12 +44,28 @@
|
|||
:initform ""
|
||||
:documentation "The format of the line ending of this node.")))
|
||||
|
||||
(defclass org-headline (org-line)
|
||||
((depth :initarg :depth
|
||||
:type number
|
||||
:accessor depth-of
|
||||
:initform 0
|
||||
:documentation "The depth of this headline.")
|
||||
(title :initarg :title
|
||||
:type string
|
||||
:accessor title-of
|
||||
:initform ""
|
||||
:documentation "The title of this headline.")))
|
||||
|
||||
(defun make-org-document (first-node)
|
||||
(make-instance 'org-document :next first-node))
|
||||
|
||||
(defun make-org-line (raw-text line-ending)
|
||||
(make-instance 'org-line :raw-text raw-text :line-ending line-ending))
|
||||
|
||||
(defun make-org-headline (depth title raw-text line-ending)
|
||||
(make-instance 'org-headline :depth depth :title title
|
||||
:raw-text raw-text :line-ending line-ending))
|
||||
|
||||
|
||||
|
||||
(defun append-node (node next)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ ListItem {
|
|||
source: {
|
||||
if (nodeType == "org-line")
|
||||
return "OrgLine.qml";
|
||||
else if (nodeType == "org-headline")
|
||||
return "OrgLine.qml";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
#include <ecl/ecl.h>
|
||||
|
||||
namespace sextant
|
||||
|
|
@ -11,6 +14,14 @@ namespace sextant
|
|||
namespace parser
|
||||
{
|
||||
|
||||
inline std::u32string to_u32string (const std::string& arg)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
|
||||
std::u32string u32str = converter.from_bytes (arg.c_str ());
|
||||
|
||||
return u32str;
|
||||
}
|
||||
|
||||
inline cl_object to_cl_object(bool arg)
|
||||
{
|
||||
return arg ? ECL_T : ECL_NIL;
|
||||
|
|
@ -31,6 +42,11 @@ namespace sextant
|
|||
return ecl_make_unsigned_integer(arg);
|
||||
}
|
||||
|
||||
inline cl_object to_cl_object(std::size_t arg)
|
||||
{
|
||||
return ecl_make_unsigned_integer(arg);
|
||||
}
|
||||
|
||||
inline cl_object to_cl_object(const char* arg)
|
||||
{
|
||||
size_t len = strlen(arg);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
#include "node_sink.hh"
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <vector>
|
||||
|
||||
#include "lexy/callback.hpp"
|
||||
|
|
@ -16,6 +14,12 @@ namespace sextant
|
|||
{
|
||||
namespace parser
|
||||
{
|
||||
struct text_line
|
||||
{
|
||||
std::string text;
|
||||
std::string eol;
|
||||
};
|
||||
|
||||
namespace grammar
|
||||
{
|
||||
namespace dsl = lexy::dsl;
|
||||
|
|
@ -32,23 +36,56 @@ namespace sextant
|
|||
static constexpr auto value = lexy::as_string<std::string>;
|
||||
};
|
||||
|
||||
struct raw_line
|
||||
struct line
|
||||
{
|
||||
static constexpr auto rule = dsl::terminator(dsl::p<eol>).opt_list(dsl::capture(dsl::code_point));
|
||||
static constexpr auto rule = dsl::terminator (dsl::p<eol>).opt_list (dsl::capture (dsl::code_point));
|
||||
static constexpr auto value = lexy::as_string<std::string> >>
|
||||
lexy::callback<cl_object>([](lexy::nullopt&&, std::string&& eol) {
|
||||
return ast_funcall("MAKE-ORG-LINE", "", eol);
|
||||
},
|
||||
lexy::callback<text_line>([](lexy::nullopt&&, std::string&& eol) {
|
||||
return text_line{"", eol};
|
||||
},
|
||||
[](std::string&& str, std::string&& eol) {
|
||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
|
||||
std::u32string u32str = converter.from_bytes(str.c_str());
|
||||
return ast_funcall("MAKE-ORG-LINE", u32str, eol);
|
||||
return text_line{str, eol};
|
||||
});
|
||||
};
|
||||
|
||||
struct headline_depth
|
||||
{
|
||||
static constexpr auto rule = dsl::list(dsl::capture(dsl::lit_c<'*'>)) + dsl::ascii::space;
|
||||
static constexpr auto value = lexy::as_string<std::string>;
|
||||
};
|
||||
|
||||
struct org_headline
|
||||
{
|
||||
static constexpr auto rule = dsl::p<headline_depth> + dsl::p<line>;
|
||||
static constexpr auto value = lexy::callback<cl_object>([](std::string&& depth, lexy::nullopt&&) {
|
||||
return ast_funcall("MAKE-ORG-HEADLINE", depth.size(), "", depth, "");
|
||||
},
|
||||
[](std::string&& depth, text_line&& line) {
|
||||
return ast_funcall ("MAKE-ORG-HEADLINE", depth.size(), to_u32string(line.text), to_u32string(depth + " " + line.text), line.eol);
|
||||
});
|
||||
};
|
||||
|
||||
struct org_line
|
||||
{
|
||||
static constexpr auto rule = dsl::p<line>;
|
||||
static constexpr auto value = lexy::callback<cl_object>([](text_line&& line) {
|
||||
return ast_funcall("MAKE-ORG-LINE", to_u32string(line.text), line.eol);
|
||||
});
|
||||
};
|
||||
|
||||
struct org_node
|
||||
{
|
||||
static constexpr auto rule = [] {
|
||||
auto headline = dsl::peek(dsl::p<headline_depth>) >> dsl::p<org_headline>;
|
||||
return headline | dsl::else_ >> dsl::p<org_line>;
|
||||
}();
|
||||
|
||||
static constexpr auto value = lexy::forward<cl_object>;
|
||||
};
|
||||
|
||||
struct document
|
||||
{
|
||||
static constexpr auto rule = dsl::terminator(dsl::eof).opt_list(dsl::p<raw_line>);
|
||||
static constexpr auto rule = dsl::terminator(dsl::eof).opt_list(dsl::p<org_node>);
|
||||
static constexpr auto value = append_node >> lexy::callback<cl_object>([](lexy::nullopt&&) {
|
||||
return ast_funcall("MAKE-ORG-DOCUMENT", ast_funcall("MAKE-ORG-LINE", "", ""));
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue