Parse headlines (but don’t do or show anything special)

This commit is contained in:
Renaud Casenave-Péré 2022-12-03 22:35:50 +01:00
parent a5bc9ba86b
commit f4967150e4
4 changed files with 86 additions and 11 deletions

View file

@ -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)

View file

@ -20,6 +20,8 @@ ListItem {
source: {
if (nodeType == "org-line")
return "OrgLine.qml";
else if (nodeType == "org-headline")
return "OrgLine.qml";
}
}

View file

@ -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);

View file

@ -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", "", ""));
},