Giter Club home page Giter Club logo

org-ml's People

Contributors

cfraizer avatar cwsteinbach avatar eyeinsky avatar luis-henriquez-perez avatar miciah avatar myshevchuk avatar ndwarshuis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

org-ml's Issues

How do you modify children of `org-data` type.

I have a node of the form:

(org-data (:begin 1 :end 700) (section) (headline) (headline))

I want to change the number of headlines. Specfically I want to add my own headlines and make sure the headlines are in alphabetical order based on title. However, org-ml-set-children raises the error (error "Child type restrictions not found for %s" type) for org-data. I'd like to be able to modify the children of the org-data type and use (setf (buffer-string) (org-ml-to-string modified-node)) to change the buffer.

Also I could not find a build function for the org-data type.

org-ml-parse-headlines: require spaces after asterisks

I'm getting the points of headlines to use with org-ml-update-headline-at and found a false positive when using (org-ml-parse-headlines 'all):

*this is some bold text* in a paragraph

* this is a headline

Both of these get returned as headlines

I think this is the pattern?:

org-ml/org-ml.el

Line 6988 in a2f7101

(->> (org-ml--parse-patterns-where which "^\\*")

A "Hello World"?

I find this project more promising and accessible than org-element.

Thanks for the efforts!

But is there somewhere a "hello world"?

Yeah I see a good amt of documentation in docs/api-refeence.md

I am looking for a simple end-to-end reference with setting up of hooks, export etc

ie some toy example that uses org-ml API and say transforms some org file into another?

If possible something that transforms:

*** Lorem Ipsum :LAW:

into

#+begin_law
Lorem Ipsum
#+end_law

would be wonderful.

But if even a simpler eg is given/pointed out I can hack from there on.

filtering by tag and property values?

I wonder if you could provide some examples of filtering an org node tree, maybe analogously to the way org agenda or org-sparse-tree allow filtering? I am trying to convert a library to use org-ml, and I'd like to be able to parse a buffer, then filter for the headlines I need & use some properties from those headlines for an HTTP request. Does org-ml have dedicated functions for the parsing, or will I need to just become a better programmer and write my own? Thanks!

Functions using org-element--parse-elements possibly broken with latest Org

Hi,

In Org commit fc80d052d, which was recently merged into the 9.5 release, the following addition was made to org-element--parse-elements:

(defun org-element--parse-elements 
  (beg end mode structure granularity visible-only acc)
...
+      (org-element-put-property acc :granularity granularity)
...)

The definition of org-element-put-property does not allow for acc to be nil:

(defsubst org-element-put-property (element property value)
  "In ELEMENT set PROPERTY to VALUE.
Return modified element."
  (if (stringp element) (org-add-props element nil property value)
    (setcar (cdr element) (plist-put (nth 1 element) property value))
    element))

I haven't investigated the scope on which Org-ml has been affected, just for example org-ml--parse-headline-subtree-at has the following call:

(org-element--parse-elements b e 'first-section
                                          nil nil nil nil)

In effect, the above call results in (setcar nil ...) throwing an error (wrong-type-argument consp nil).

org-ml-parse-subtrees ignores subtrees starting on level 2

** second level

(org-parse-subtrees 'all) => nil

Surprising and not documented. But the code is clear:

(defun org-ml-parse-subtrees (which)
  "Return list of subtree nodes from current buffer.

WHICH has analogous meaning to that in `org-ml-parse-headlines'
except applied to subtrees not individual headlines."
  (org-ml--parse-patterns-where which "^\\* "))

Should indent/unindent be called promote/demote?

Hi and thanks for org-ml!
I was looking for functions doing what in org is usually called "promoting" and "demoting" (for example org-promote) and realized that this is achieved with the indent/unindent functions.

Would it be better to use function names like "demote" and "promote" to better reflect the terminology in org-mode (even though I realize that org-ml intentionally departs from some of the terminology in org-element)? "Indent" is also used for things relating to real or displayed whitespace in org-mode.

Sometimes :end is incorrect

Consider this org-mode file:

#+TITLE: Test Title

There’s still room for improvement:

+ A few big chunks of this file are still mostly verbatim copies from
  my old configuration file with little by way of new documentation.
+ There’s still a bunch of undocumented configuration in libraries in
  =~/.emacs.d/personal/*.el= that would benefit from greater
  documentation.

* heading

Insert something here.

I'm trying to walk through it, parsing each org element. Suppose I get to point 59.

If you goto point 59 and run (org-element-at-point), it will return something like this:

(plain-list (:type unordered :begin 59 :end 347
  :contents-begin 59 :contents-end 346 :structure ...)

If you run (om-parse-element-at 59), it will return something like this:

(plain-list (:type unordered :begin 59 :end 346
  :contents-begin 59 :contents-end 346 :structure ...)

Note that :end is one character short here. Unfortunately, if you run (om-parse-element-at 346), you'll discover that you get back the same plain-list and you're in an infinite loop.

Unfortunately, it isn't always one character short, so I don't think the solution is to always add one. But I haven't worked out from the output of om-parse-element-at when I should add one.

Bug or misundertanding on my part?

headline-node-property drawer is inserted after a newline (i.e. invalid syntax)

Here's a test case. Evaluate the following elisp while on the foo headline (e.g. with eval-expression):

(let ((headline (org-ml-parse-this-subtree)))
	(save-excursion
		(goto-char (point-min))
		(insert (org-ml-to-string (org-ml-headline-set-node-property "FOO" "BAR" headline)))))
* foo

** bar

With org-ml Version: 4.0.1, this inserts on my machine:

* foo

:PROPERTIES:
:FOO:      BAR
:END:
** bar


This (missing newline) works fine:

* foo
** bar

It seems that set-node-property returns a weird section before the property drawer?:

(headline (:raw-value "foo" :begin 1 :end 15 :pre-blank 0 :contents-begin 7 :contents-end 14 ...) 
    (section (:post-blank 0 :begin nil :end nil :parent nil :contents-begin nil :contents-end nil ...)
    (property-drawer (:post-blank 0 :begin nil :end nil :parent nil :contents-begin nil :contents-end nil ...) (node-property ...)))
    (headline (:raw-value "bar" :begin 7 :end 14 :pre-blank 0 :contents-begin nil :contents-end nil ...)))

Semantics of :parent and ways to reparent/orphan nodes

I'm writing code that extracts elements from a number of org-mode buffers and writes new elements based on them into a new buffer. I've encountered two places where I've wanted to change the parent:

  • It is sometimes natural to clone a section (say) from one tree and add it as a child to another tree. In this case, it would seem prudent to reparent the cloned node to its new parent
  • I like to print the actual object sexps during debugging, and in those situations, it's much easier to see the structure of the tree when the node's parent is set to, say, nil.

This led me to look for ways to reparent/orphan elements/objects in the API, but this doesn't seem to be supported, and in some cases is specifically disallowed. (Property ’:parent’ is unsettable for type ’headline’ when trying to set :parent with org-ml-set-property, for instance.)

I assume you have reasons for this; I was wondering what those are. Is there a semantic difference between the node referred to by the :parent property and whichever org-element list a node is currently enclosed in? Are there approved ways to create a node from the content of another node, but with a different/empty :parent property?

Sorry if this is already documented; I looked, but didn't come across anything. Thanks for humoring my curiosity, and thanks for this outstanding library.

how to keep properties of org-element or org-ql headlines

I think I'm asking a well-formed questions, but I do feel a little unsure, os apologies if this is inaccurate.

From what I can tell, org-element and org-ql store headline properties as simple plist properties in the headline's definition. org-ml seems to separate them out into a property drawer. I'd like to, for instance, grab a headline with properties from one buffer and reproduce it in a different buffer with a couple of property changes and a large number of child headlines. My thought was to do something like:

(let* ((assignment (car (org-ql-select "./Assignments.org"
                         '(and (heading "Fake Assignment for Testing")(tags "assignment")))))
       (students '("Jimmy" "Mary" "Sunit" "Jasmine"))
       (children  (--map (org-ml-build-headline :level 2 :title `(,it)) students)))
  (->> (org-ml-set-children children assignment)
       (org-ml-to-trimmed-string)))

but the resultant string eliminates the parent's property drawer. I guess I need to manually recreate the property drawer and add it a a child? Yet this seems unnecessarily complex. Is there some trick for extracting the property drawer from a headline object returned by org-element?

in some cases (e.g org-link abbreviations) parsing functions don't preserve original text

Hello!
I love om.el, but I've hit one problem that might be a bug.
I use org-link abbreviations in my orgmode files, where an initial keyword in a link, followed by a colon, can cause the rest of the link to be converted or changed before the link is followed. So "wiki:blah" as a link could end up taking the user to a "~/txt/wiki/blah.org" file instead. The transformations are defined in org-link-abbrev-alist.

When I'm parsing one of these files, this link destination is expanded in the parsed results -- which means that if I use that value to update the current file, the original abbreviation is changed into its fully expanded form. That means that updating can create a side-effect of expanding these links.

Here's a small test-case which I think works on its own:

(let ((test-org "Hello [[test:foo]]")
      (org-link-abbrev-alist '(("test" . "i-am-transformed-from-"))))
     (with-temp-buffer
      (insert test-org)
      (om-to-trimmed-string (om-parse-this-element))))

As you should hopefully see, the result doesn't match the input.


org-ml-to-string returns title property concatenated 4 times

* bar foo
# (org-ml-to-string (org-ml-get-property :title (org-ml-parse-this-headline)))

# this evaluates to 1:
# (length (org-ml-get-property :title (org-ml-parse-this-headline)))

Just evaluate the call in the comment, it returns the title text concatenated four times. Am I somehow still using this incorrectly?

stray `:END:` markers are duplicated on `headline-set-node-property`

Edit: again, this seems to be an org-element bug? The org-format is also not very strict and/or explicit on this...

Evalute

(org-ml-update* (org-ml-headline-set-node-property "TEST" "TEST" it) (org-ml-parse-this-subtree))

on

* test

:END:

results in:

* test

:PROPERTIES:
:TEST:     TEST
:END:
:END:
:END:

Subsequent evaluations of the same quickly spiral into oblivion:

* test

:PROPERTIES:
:TEST:     TEST
:END:
:PROPERTIES:
:TEST:     TEST
:END:
:END:
:END:
:END:
:END:

$ ls -alh
-rwxr-xr-x 1 hrehfeld hrehfeld 4.1M Oct 31 22:59 test.org

(org-ml-parse-this-subtree) and (org-element-parse-buffer) parse a drawer named END:

(headline 
  (:raw-value "TEST" :begin 1 :end 15 :pre-blank 1 :contents-begin 9 :contents-end 15 :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :post-blank 0 :footnote-section-p nil :archivedp nil :commentedp nil :post-affiliated 1 :title (#("TEST" 0 4 (:parent #0))) :parent nil) 
  (section (:begin 9 :end 15 :contents-begin 9 :contents-end 15 :post-blank 0 :post-affiliated 9 :parent #0) 
  (drawer (:begin 9 :end 15 :drawer-name "END" :contents-begin nil :contents-end nil :post-blank 0 :post-affiliated 9 :parent #1))))

Interestingly, this doesn't duplicate:

(org-ml-update* #'identity (org-ml-parse-this-subtree))

but this does:

(org-ml-insert-tail (point) (org-ml-parse-this-subtree))

So does this:

(org-ml-update* (org-ml-headline-set-title! "TEST" nil it) (org-ml-parse-this-subtree))

Maybe because the first doesn't update at all?

:raw-link Not working

If I got a headline

* TODO [[https://xyz.tld][FooBar]]

And try to get the raw-link via

(->> (om-parse-this-headline)
     (om-get-property :title)
     (-first-item)
     (om-get-property :raw-link))

I get the error

om--arg-error: Argument type error: "Unsettable property ’:raw-link’ for type ’link’ requested; settable properties are :path, :format, :type, :raw-link, :application, :search-option, :post-blank"

Problem with `eval-with-compile`

I reported a bug against straight.el that appears to be a problem in om.el:

I get:

Debugger entered--Lisp error: (void-variable om-elements)
  (-intersection om-branch-nodes-permitting-child-objects om-elements)
  (defconst om-branch-elements-permitting-child-objects (-intersection om-branch-nodes-permitting-child-objects om-elements) ("/Users/ndw/.emacs.d/straight/build/om/om.elc" . 741))
  require(om)
  eval((require (quote om)) nil)
  elisp--eval-last-sexp(t)
  eval-last-sexp(t)
  eval-print-last-sexp(nil)
  funcall-interactively(eval-print-last-sexp nil)
  call-interactively(eval-print-last-sexp nil nil)
  command-execute(eval-print-last-sexp)

The maintainer of straight.el says:

That is a bug in the package as far as I can tell. It should not be using eval-when-compile for that code. When I run make compile from the package's Makefile, then manually evaluate the resulting .elc files, I get the same error. Given that, I don't think the problem lies with straight.el.

Hope this is useful.

Tables with empty cells not correctly parsed

Hi,

it seems the parser for tables doesn't work. Here is an example:

|    2 | 1 | 1    | 0     | -1 | -1   | 0 |
|------+---+------+-------+----+------+---|
| P(a) | a | a    | a     | a  | V(a) |   |
|      |   | P(b) | b     | b  | b    | b |
|      |   |      | P(c)) | c- | c-   | c |

running (org-ml-to-string (org-ml-parse-this-element)) returns this

| 2     | 1  | 1  | 0 | -1 |   -1 | 0 |
|-------+----+----+---+----+------+---|
| P(a)  | a  | a  | a | a  | V(a) |   |
| P(b)  | b  | b  | b | b  |      |   |
| P(c)) | c- | c- | c |    |      |   |

So it seems empty cells are shifted to the end of the table.

Cannot create headline

Both build-headline functions seem to be broken.

With either

(om-build-headline :title "really impressive title")
(om-build-headline! :title-text "really impressive title")

I get om--arg-error: Argument type error: "Unsettable property ’:post-blank’ for type ’headline’ requested; settable properties are :archivedp, :commentedp, :footnote-section-p, :level, :pre-blank, :priority, :tags, :title, :todo-keyword, :raw-value, :todo-type"

Emacs Version:
GNU Emacs 26.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.10)

Issue when using org-ml-build-table! with a list of lists (for multiple rows)

The documentation for org-ml-build-table! says that "row-lists is a list of lists," but when I try to use a list of lists I get an error. E.g., (org-ml-build-table! '(("R" "A") ("G" "E"))) throws an error, whereas (apply #'org-ml-build-table! '(("R" "A") ("G" "E"))) works as expected (as does the example in the documentation).

`org-ml-update` does change point even when wrapped with `(save-excursion FORM)`

* Foo Bar
#  doesn't change point
# (org-ml-update* (identity it) (org-ml-parse-this-headline))

# changes point to beginning of * Foo
# (org-ml-update* (org-ml-headline-set-node-property "title" "test" it) (org-ml-parse-this-headline)) 

# changes point to beginning of * Foo
# (save-excursion (org-ml-update* (org-ml-headline-set-node-property "title" "test" it) (org-ml-parse-this-headline)))

I sortof understand why this might happen, however it would be awesome to have better behavior here.

Doesn't org-mode have some sort of logic to save & find context around links? Maybe we can hijack that, otherwise it might be possible to save a priority queue of things to jump to near point.

subtree corruption issues with org-ml-update

Hi,

I'm trying to frame a proper response to your helpful comment in #33, but am running into an issue that looksl ike it might be a bug.

I'm generating a long set of subtrees with this code:


* Fake Assignment forTesting :ASSIGNMENT:
:PROPERTIES:
:ASSIGNMENT_WEIGHT: 10
:ASSIGNMENTID: 735871
:ASSIGNMENT_NAME: Fake Assignment for Testing
:ORG_LMS_ASSIGNMENT_DIRECTORY: fake-assignment-for-testing
:GRADING_TYPE: letter_grade
:IS_QUIZ:  nil
:ORG_LMS_EMAIL_COMMENTS: t
:ORG_LMS_CANVAS_COMMENTS: t
:END:
#+begin_src emacs-lisp
(save-excursion
(forward-line)
(--map (insert
        (format "** TODO Matthew Price %s
:PROPERTIES:
:GRADE:    %s
:CHITS:    0
:NICKNAME: Matthew
:FIRSTNAME: Matthew
:LASTNAME: Price
:MAIL_TO:  [email protected]
:GITHUB:
:ORG_LMS_REPO_BASENAME:
:STUDENTID: 85514
:GRADE_URL: https://q.utoronto.ca/courses/35724/gradebook/speed_grader?assignment_id=735871
:COURSEID: 35724
:BASECOMMIT: none
:ORG_LMS_ASSIGNMENT_DIRECTORY: fake-assignment-for-testing
:MAIL_REPLY: [email protected]
:MAIL_SUBJECT: Comments on Assignment 
:END:
fdsfds %s %s %s

" it it it it it )) (number-sequence 1 100)))
#+end_src

After the trees have been created, I try to modify them in place with:

** Final Subtree
#+begin_src emacs-lisp :results code 
(save-excursion 
  (outline-up-heading 1)
  (let ((items 
         (->>  (org-ml-parse-subtree-at (point))
               (org-ml-match '((:todo-keyword "TODO"))))))
    
    (--map  
     (org-ml-update (lambda (hl)
		      (org-ml-set-property :todo-keyword "READY" hl)) 
it)  items)))
#+end_src

When I run this code, I lose any whitespace at the end of an updated subtree, so that the next subtree pops up into the section of the previous heading. As a result, the structure breaks down. 

I'm assuming this is an issue with mapping over multiple headlings -- I don't see the issue when I replace only one heading at a time. 

Do you see an obvious problem with my code? 

org-ml-parse-table-row-at parses only the first table row

Hi! I've just started experimenting with org-ml and find it awesome!

It seems that org-ml-parse-table-row-at parses only the first table row of a table and return nil if point it elsewhere in the table.

Here's the following minimal example to reproduce the issue:

test.org:

| a | b |
|---+---|
| c | d |

test.el:

(with-current-buffer "test.org"
  (->> (org-ml-parse-table-row-at 10) ;;  first row, (point) 1 to 10
       (org-ml-get-type)))

=> table-row

(with-current-buffer "test.org"
  (->> (org-ml-parse-table-row-at 11) ;; second row and onwards
       (org-ml-get-type)))

=> nil

Current melpa broken with `(invalid-function (make-plist ...`?

I just updated the package, is this related to something else?

Debugger entered--Lisp error: (invalid-function (make-plist (arg init) (let* ((kw (org-ml--symbol-to-keyword arg)) (kw-get `(cadr (plist-member ... ...))) (val (if init `(or ... ...) kw-get))) (cons kw `(,arg ,val)))))
  (make-plist (arg init) (let* ((kw (org-ml--symbol-to-keyword arg)) (kw-get `(cadr (plist-member ,kws-sym '...))) (val (if init `(or ,kw-get ,init) kw-get))) (cons kw `(,arg ,val))))()
  org-ml--make-kwarg-let(--kw-args inside-header)
  #f(compiled-function (it) #<bytecode 0x1580d089ebe1>)(inside-header)
  mapcar(#f(compiled-function (it) #<bytecode 0x1580d089ebe1>) (inside-header arguments end-header post-blank))
  org-ml--transform-lambda((call &key inside-header arguments end-header post-blank) ("Build a babel-call element node.\n\nThe following pr..." (->> (org-ml--build-leaf-node 'babel-call post-blank) (org-ml--set-properties-nocheck-nil (list :value :begin :end :parent :post-affiliated)) (org-ml-set-properties (list :inside-header inside-header :arguments arguments :end-header end-header :call call)))) org-ml-build-babel-call)
  #f(compiled-function (name arglist &rest body) "Define NAME as a function with BODY.\n\nThis is like `cl-defun' except it allows &key to be used in\nconjunction with &rest without freaking out. ARGLIST can be specified\nusing the following syntax:\n\n([VAR] ...\n [&key (VAR [INITFORM])...]\n [&rest VAR])\n\nwhere VAR is a symbol for the variable identifier and INITFORM is an\natom or form that will be the default value for keyword VAR if it is\nnot give in a function call.\n\nWhen calling functions defined with this, keywords can be given in any\norder as long as they are after all positional arguments, and rest\narguments will be interpreted as anything not belonging to a key-val\npair (but only if &rest was used to define the function). This implies\nthat keywords may not be used as values for the rest argument in\nfunction calls." #<bytecode 0x1580cfb1bf01>)(org-ml-build-babel-call (call &key inside-header arguments end-header post-blank) "Build a babel-call element node.\n\nThe following pr..." (->> (org-ml--build-leaf-node 'babel-call post-blank) (org-ml--set-properties-nocheck-nil (list :value :begin :end :parent :post-affiliated)) (org-ml-set-properties (list :inside-header inside-header :arguments arguments :end-header end-header :call call))))
  macroexpand((org-ml--defun-kw org-ml-build-babel-call (call &key inside-header arguments end-header post-blank) "Build a babel-call element node.\n\nThe following pr..." (->> (org-ml--build-leaf-node 'babel-call post-blank) (org-ml--set-properties-nocheck-nil (list :value :begin :end :parent :post-affiliated)) (org-ml-set-properties (list :inside-header inside-header :arguments arguments :end-header end-header :call call)))))
  (let* ((type (car entry)) (name (intern (format "org-ml-build-%s" type))) (props (->> (cdr entry) (--remove (eq :post-blank (car it))) (-non-nil) (-group-by #'org-ml--autodef-categorize-prop))) (pos-args (->> (alist-get 'req props) (--map (org-ml--autodef-kwd-to-sym (car it))))) (kw-args (->> (alist-get 'key props) (--map (let ((prop ...) (default ...)) (if default `... prop))))) (rest-arg (cond ((memq type org-element-greater-elements) 'element-nodes) ((memq type org-element-object-containers) 'object-nodes))) (args (let ((a `(... &key ... post-blank))) (if rest-arg `(,@a &rest ,rest-arg) a))) (const-props (-some->> (alist-get 'const props) (--mapcat (list (car it) (plist-get (cdr it) :const))) (org-ml--autodef-prop-form 2 #'org-ml--set-property-nocheck #'org-ml--set-properties-nocheck))) (nil-props (-some->> (alist-get 'null props) (-map #'car) (org-ml--autodef-prop-form 1 #'org-ml--set-property-nocheck-nil #'org-ml--set-properties-nocheck-nil))) (strict-props (-some->> (append (alist-get 'key props) (alist-get 'req props)) (-map #'car) (--mapcat (list it (org-ml--autodef-kwd-to-sym it))) (org-ml--autodef-prop-form 2 #'org-ml-set-property #'org-ml-set-properties))) (doc (org-ml--autodef-make-docstring type rest-arg props)) (builder (let ((a `(... post-blank))) (if rest-arg `(org-ml--build-branch-node ,@a ,rest-arg) `(org-ml--build-leaf-node ,@a)))) (body (if (or strict-props nil-props const-props) `(->> ,@(-non-nil ...)) builder))) (macroexpand `(org-ml--defun-kw ,name ,args ,doc ,body)))
  org-ml--autodef-build-node-form((babel-call (:call :pred org-ml--is-oneline-string :type-desc "a oneline string" :require t) (:inside-header :encode org-ml--encode-plist :pred org-ml--is-plist :decode org-ml--decode-plist :plist t :type-desc "a plist") (:arguments :encode org-ml--encode-string-list-comma-delim :decode org-ml--decode-string-list-comma-delim :pred org-ml--is-string-list :string-list t :type-desc "a lthing elist of oneline strings") (:end-header :encode org-ml--encode-plist :pred org-ml--is-plist :decode org-ml--decode-plist :plist t :type-desc "a plist") (:value) (:post-blank :pred org-ml--is-non-neg-integer :shift org-ml--shift-non-neg-integer) (:begin) (:end) (:parent) (:post-affiliated)))
  (closure (... t) (it) (org-ml--autodef-build-node-form it))((babel-call (:call :pred org-ml--is-oneline-string :type-desc "a oneline string" :require t) (:inside-header :encode org-ml--encode-plist :pred org-ml--is-plist :decode org-ml--decode-plist :plist t :type-desc "a plist") (:arguments :encode org-ml--encode-string-list-comma-delim :decode org-ml--decode-string-list-comma-delim :pred org-ml--is-string-list :string-list t :type-desc "a list of oneline strings") (:end-header :encode org-ml--encode-plist :pred org-ml--is-plist :decode org-ml--decode-plist :plist t :type-desc "a plist") (:value) (:post-blank :pred org-ml--is-non-neg-integer :shift org-ml--shift-non-neg-integer) (:begin) (:end) (:parent) (:post-affiliated)))
  mapcar((closure ... ... ...) (... ... ... ... ... ... ... ... ... ... ... ... ... ... ...))
  (--map (org-ml--autodef-build-node-form it) it)
  (-as-> (--map (org-ml--autodef-build-node-form it) it) it)
  (let ((it (--remove (eq 'plain-text (car it)) org-ml--property-alist))) (-as-> (--map (org-ml--autodef-build-node-form it) it) it))
  (-as-> (--remove (eq 'plain-text (car it)) org-ml--property-alist) it (--map (org-ml--autodef-build-node-form it) it))
  (--> (--remove (eq 'plain-text (car it)) org-ml--property-alist) (--map (org-ml--autodef-build-node-form it) it))
  (let ((forms (--> (--remove (eq 'plain-text (car it)) org-ml--property-alist) (--map (org-ml--autodef-build-node-form it) it)))) `(progn ,@forms))
  (closure (t) nil "Define all build node functions." (let ((forms (--> (--remove (eq 'plain-text (car it)) org-ml--property-alist) (--map (org-ml--autodef-build-node-form it) it)))) `(progn ,@forms)))()
  (org-ml--autodef-build-node-functions)
  eval-buffer(#<buffer  *load*> nil "/home/hrehfeld/.emacs.d/elpa/org-ml-20200927.1906/..." nil t)  ; Reading at buffer position 59573
  load-with-code-conversion("/home/hrehfeld/.emacs.d/elpa/org-ml-20200927.1906/..." "/home/hrehfeld/.emacs.d/elpa/org-ml-20200927.1906/..." t t)
  require(org-ml nil t)
  (not (require 'org-ml nil t))
  (if (not (require 'org-ml nil t)) (display-warning 'use-package (format "Cannot load %s" 'org-ml) :error))
  (condition-case err (if (not (require 'org-ml nil t)) (display-warning 'use-package (format "Cannot load %s" 'org-ml) :error)) ((debug error) (funcall use-package--warning285 :catch err)))
  (progn (use-package-ensure-elpa 'org-ml '(t) 'nil) (defvar use-package--warning285 #'(lambda (keyword err) (let ((msg (format "%s/%s: %s" ... keyword ...))) (display-warning 'use-package msg :error)))) (condition-case err (if (not (require 'org-ml nil t)) (display-warning 'use-package (format "Cannot load %s" 'org-ml) :error)) ((debug error) (funcall use-package--warning285 :catch err))))
  (progn (progn (use-package-ensure-elpa 'org-ml '(t) 'nil) (defvar use-package--warning285 #'(lambda (keyword err) (let ((msg ...)) (display-warning 'use-package msg :error)))) (condition-case err (if (not (require 'org-ml nil t)) (display-warning 'use-package (format "Cannot load %s" 'org-ml) :error)) ((debug error) (funcall use-package--warning285 :catch err)))))
  eval((progn (progn (use-package-ensure-elpa 'org-ml '(t) 'nil) (defvar use-package--warning285 #'(lambda (keyword err) (let (...) (display-warning ... msg :error)))) (condition-case err (if (not (require 'org-ml nil t)) (display-warning 'use-package (format "Cannot load %s" 'org-ml) :error)) ((debug error) (funcall use-package--warning285 :catch err))))) t)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Version flag in org-ml.el: ;; Version: 4.0.1

GNU Emacs 27.1.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.22, cairo version 1.17.3) of 2020-08-23

This also happens with:

$ emacs -Q

(add-to-list 'load-path "~/.emacs.d/elpa/org-ml-20200927.1906/")
(add-to-list 'load-path "~/.emacs.d/elpa/dash-20200803.1520/")
(add-to-list 'load-path "~/.emacs.d/elpa/s-20180406.808/")


(require 'org-ml)

and also if I add the recently updated org packages:

(add-to-list 'load-path "~/.emacs.d/elpa/org-plus-contrib-20201005/")
(add-to-list 'load-path "~/.emacs.d/elpa/org-20201005/")

recommended way to build a headline with properties?

Is this the recommended way to do that:

#+BEGIN_SRC emacs-lisp
(concat (->> (om-build-headline :todo-keyword "TODO" :archivedp t :commentedp t :priority 65)
	     (om-to-trimmed-string))
	"\n"
	(->>
	 (om-build-property-drawer! '(key val))
	 (om-to-trimmed-string)))
#+END_SRC

Is there a way to get the properties indented?

I thought the properties would be a child node of a headline, but that seems to be illegal.

`org-ml-headline-set-node-property` unable to set property to nil

context: I'm trying to remove the properties drawer from a node before I render it as a string.

The issue I'm running into can be shown with the last example in the docs here.

with the content:

* headline
:PROPERTIES:
:ID:       fake
:END:

The example code returns the whole content, instead of just the headline like in the example:

(->> (org-ml-parse-this-headline)
     (org-ml-headline-set-node-property "ID" nil)
     (org-ml-to-trimmed-string))
;; => "* headline\n:PROPERTIES:\n:ID:       fake\n:END:"
;; ! expected: "* headline"

EDIT: org version: Org mode version 9.4 (release_9.4-174-gf6e41c @ /home/neeasade/.emacs.d/straight/build/org/)
EDIT: org-ml version: d856ac6

OT: Thank you so much for org-ml. It has given me the tools for shaping org the way I want, and helped me cross the gap to "complete" WRT my personal notes system.

Fix melpa homepage link

The homepage link is marked as
image

Which is a broken link, I had to remove the .el to come to this page :)

Source block parameters are tricky to access

Given two source blocks with a tangle parameter, accessing the tangle parameter is quite different depending on if it is found in a HEADER or on the BEGIN_SRC line.
As a minimal example, here is the contents of an org file named org-ml-header-bug-minimal-example.org with the following contents:

#+TITLE: Org Ml Header Bug Minimal Example
* A code block with a tangle argument in a HEADER
#+HEADER: :tangle ~/path/to/hello-org-ml.el
#+BEGIN_SRC emacs-lisp
(message "%s" "hello org-ml")
#+END_SRC
* A code block with a tangle argument on the BEGIN_SRC line
#+BEGIN_SRC emacs-lisp :tangle ~/path/to/hello-org-ml.el
(message "%s" "hello org-ml")
#+END_SRC

I can access the tangle parameter of the second source block in the following way:

ELISP> (save-excursion (set-buffer "org-ml-header-bug-minimal-example.org") (org-ml-parse-element-at 316))
(src-block
 (:language "emacs-lisp" :switches nil :parameters ":tangle ~/path/to/hello-org-ml.el" :begin 261 :end 358 :number-lines nil :preserve-indent nil :retain-labels t :use-labels t :label-fmt nil :value "(message \"%s\" \"hello org-ml\")
" :post-blank 0 :post-affiliated 261 :parent nil))

ELISP> (org-ml-get-property :parameters *)
(:tangle ~/path/to/hello-org-ml\.el)

ELISP> (plist-get * :tangle)
~/path/to/hello-org-ml\.el
ELISP> (with-temp-file * (insert "hello org-ml"))
*** Eval error ***  Wrong type argument: stringp, ~/path/to/hello-org-ml\.el
ELISP> (symbol-name *)
"~/path/to/hello-org-ml.el"
ELISP> (with-temp-file * (insert "hello org-ml"))
nil

Whereas with the first block, where the tangle parameter is in the header, I can access the tangle parameter like this:

ELISP> (save-excursion (set-buffer "org-ml-header-bug-minimal-example.org") (org-ml-parse-element-at 160))
(src-block
 (:language "emacs-lisp" :switches nil :parameters nil :begin 94 :end 201 :number-lines nil :preserve-indent nil :retain-labels t :use-labels t :label-fmt nil :value "(message \"%s\" \"hello org-ml\")
" :post-blank 0 :post-affiliated 138 :header
(":tangle ~/path/to/hello-org-ml.el")
:parent nil))

ELISP> (org-ml-get-property :header *)
*** Eval error ***  Argument type error: "Type ’src-block’ does not have property ’:header’"
ELISP> (org-ml--get-property-nocheck :header *)
(":tangle ~/path/to/hello-org-ml.el")

ELISP> (car *)
":tangle ~/path/to/hello-org-ml.el"
ELISP> (s-chop-prefix ":tangle " *)
"~/path/to/hello-org-ml.el"
ELISP> (with-temp-file * (insert "Hello org-ml"))
nil

It would be nice if there was a function for consistently getting a source block parameter regardless of whether or not that parameter is in a HEADER. At a more granular level, it would be nice if source block parameters were consistently parsed as either plists of symbols or lists of strings, but not both depending on where it is specified. It would also be preferable for org-ml-get-property to not throw an error when accessing the :header property of a source block.

I realize this stuff may not be trivial to change in a way that makes sense for the overall functionality of this library, and I completely understand if you don't want to spend time on this. This library is generally great to work with, so thank you for all your hard work putting it together!

Bug: om-headline-set-node-property returns ':post-blank' error

Trying to set properties with om-headline-set-node-property returns the error:

om--arg-error: Argument type error: "Type ’node-property’ does not have property ’:post-blank’"

Here's the function:

(->> (om-parse-this-headline)
         (om-update (lambda (hl)
                      (->> hl
                           (om-headline-set-node-property "FOO" "BAR")))))

And it errors on headers with properties as well as headers without.

Parse a timestamp string (e.g. from a CREATED property)?

Is there an elegant way to parse a timestamp string like "[2020-10-30 09:25]"?

Currently I'm doing:

(defun my-org-ml-parse-timestamp (str)
	(with-temp-buffer
		(insert str)
		(goto-char (point-min))
		(org-ml-parse-this-object)))

org-ml-build-headline! fails if title-text looks like a list item

Hello, I have encountered a bug while trying to use this library to build an Org document from a parsed HTML document.

I'll show you just a couple of examples:

(org-ml-build-headline! :title-text "Hello")
; => OK

(org-ml-build-headline! :title-text "1. Hello")
; => Argument type error: "Secondary string must only contain objects"

This is because org-ml-headline-set-title! uses org-ml-build-secondary-string! internally, which uses org-ml--from-string to parse title-text. The function is aware of the Org syntax, so it parses even lists:

;; If `string` is "1. Hello", the result will contain a list item
(->> (org-ml--from-string (concat " " string))
                    (org-ml--get-descendent '(0))
                    (org-ml-get-children))

Feature request(?): Getting keyword values

Consider the following toplevel section:

#+STYLE: <link rel="stylesheet" type="text/css" href="style.css">
#+STARTUP: indent
#+TITLE: This is the title of the file

Toplevel section text

This generates the following org-element tree (via org-ml-parse-this-toplevel-section):

(section
 (:begin 1 :end 148 :contents-begin 1 :contents-end 147 :post-blank 1 :post-affiliated 1 :parent nil)
 (keyword
  (:key "STYLE" :value "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">" :begin 1 :end 67 :post-blank 0 :post-affiliated 1 :parent #0))
 (keyword
  (:key "STARTUP" :value "indent" :begin 67 :end 85 :post-blank 0 :post-affiliated 67 :parent #0))
 (keyword
  (:key "TITLE" :value "This is the title of the file" :begin 85 :end 125 :post-blank 1 :post-affiliated 85 :parent #0))
 (paragraph
  (:begin 125 :end 147 :contents-begin 125 :contents-end 147 :post-blank 0 :post-affiliated 125 :parent #0)
  #("Toplevel section text\n" 0 22
    (:parent #1))))

My goal is to get the value of the TITLE keyword. (I.e., "This is the title of the file") I don't see how I can get there directly with the org-ml API, other than filtering the section node's children for keyword objects with the appropriate key.

Am I missing a more straightforward way to get key/value information from the child keywords of an element? If not, I think some kind of simple API for access to keywords would be useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.