emacs-orgmode@gnu.org archives
help / color / mirror / code / Atom feed
* Re: [RFC] Document level property drawer
@ 2019-10-20  2:28 Gustav Wikström
2019-10-22 21:24  Marco Wahl
 (2 more replies)
0 siblings, 3 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-20  2:28 UTC (permalink / raw)
To: marcowahlsoft; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 3402 bytes --]

Hi!

I'll start with the most important info at the top. I've applied the
patch! But before anyone comes screaming I'll just say it's applied on
a separate branch. After consultation with Nicolas Goaziou that was
seen as the most reasonable thing to do. The idea is that it's high
time to start wrapping up 9.3 for a release and (even though I
personally would like to have this in there) since this patch might
continue to generate discussion and possibly bugs and fixes it's more
safe to let this come after the 9.3 release.

Sooo, a separate branch is created in the Org mode repository named
"next". I'm not entirely sure how we're supposed to work with it. But
I've anyways pushed my (non-breaking) patch there.

Comments on what you've written below!

Marco Wahl writes:

> > @Marco Wahl; As I understand you've applied the patch and tried it
> > out. Have you found any issues yet? What do you think of the patch
> > after having used it for a while?
>
> Indeed I applied your patch and have it applied still.  Please note that
> I did nothing fancy and in particular I did not try to break the patch.

Got it.

> The patch works good for me.

Nice to hear!

> Noteworthy observations AFAICT:
>
> 1. I could not translate my personal "#+TODO: . N ~ | x c g >" into a
> respective :TODO: property.

Yes, that's true. The reason is that there is no TODO-property that
fits in property drawers right now. I.e. special properties such as
TODO, TAGS, priority, scheduling and deadlines that have special
syntax for the outline still have no defined meaning for outline level
0. I ofc. think that's an oversight ;) But I may also be a bit crazy.

A conclusion to draw from that, that may be worth writing more about,
is that the property drawer for node level 0 will not be able to
replace all file-level keywords that exist today.  Only properties that
currently can also be defined in property drawers in the outline will
work in the property drawer on level 0.  Makes sense?

The idea I had for all the other keywords that apply for the whole
file was to create another drawer, what I called a settings drawer.
Because the TODO-keyword you refer to above really is a setting that
you're making for the current file, much the same as when you make
changes in global, folder local or file local variables using the
standard emacs framework.

I've attached an investigation I did of the world of Org mode
keywords. It was done quite a while back and some things in there are
subjective and may not represent my current picture of the "ideal".
Nonetheless, maybe an interesting read for the ... other crazy people
out there?

> 2. With org-ids turned on and point before the first heading, function
> org-store-link creates an org-id property at the document level.
>
> Regarding number 1. I think a list of document-level properties which
> don't behave the same when used in the document property drawer would be
> nice.  Ideally this list is empty AFAICT.  Maybe I overlook something.
> Is this an issue?

Ahh, see the attachment ;) Maybe can give answers to some of your
thoughts.

> I think observation 2. is just a little surprise but turns out to be
> natural when the document level property drawer is enabled.

>
>
> Still +1 for the inclusion of the patch and HTH,
> --

Thanks
Gustav

[-- Attachment #2: Investigation.org --]
[-- Type: application/octet-stream, Size: 12130 bytes --]

:PROPERTIES:
:ID:       ccbcc594-6ea0-42d4-af6d-62b93bb951d1
:COLUMNS:  %item %has-entry-syntax
:END:
#+TITLE: Investigation of keywords in org-mode

There are LOADS of them. They are used for configurations of various
kind. Many have ambigous names and it's not always clear what they're
for or in what context they're used. Some are document-level content.
Some change the emacs org-mode state for the buffer. This node sums up
my investigation of them.

* Startup
:PROPERTIES:
:has-entry-syntax: nil
:END:
Used to customize the org-mode configuration for the current buffer.

- Visibility :: [[info:org#Initial visibility][info:org#Initial visibility]]
- Blocks :: [[info:org#Blocks][info:org#Blocks]]
- Column Width and Alignment :: [[info:org#Column Width and Alignment][info:org#Column Width and Alignment]]
- Setting constants-unit-system :: [[info:org#References][info:org#References]]
- Closing items :: [[info:org#Closing items][info:org#Closing items]]
- Setting org-tag-persistent-alist :: [[info:org#Setting Tags][info:org#Setting Tags]]
- Logging Clocking in/out :: [[info:org#Clocking commands][info:org#Clocking commands]]
- Logging refiling :: [[info:org#Refile and Copy][info:org#Refile and Copy]]
- Setting org-Pretty-entities :: [[info:org#Special Symbols][info:org#Special Symbols]]
- Previewing Latex :: [[info:org#Previewing LaTeX fragments][info:org#Previewing LaTeX fragments]]
- Inline images customization :: [[info:org#Images][info:org#Images]]
- Footnotes customization :: [[info:org#Creating Footnotes][info:org#Creating Footnotes]]
- Setting beamer minor mode :: [[info:org#Editing support][info:org#Editing support]]
- Displaying headline-stars :: [[info:org#Clean View][info:org#Clean View]]
- Various other customization :: [[info:org#In-buffer Settings][info:org#In-buffer Settings]]

To see all options, =M-C-i= (pcomplete) on the following row:
#+STARTUP:

or look at the constant =org-startup-options= defined in org.el.

Common for all startup-keywords is that they take no parameters. Each
value has a predefined configuration. For example hideblocks &
nohideblocks are two startup-options that both set
org-hide-block-startup. But to different values.

Startup modifies the state of the run-time.

One benefit of having them is for easy and concise user-configuration
inside each buffer. But it basically is the same as setting file local
variables for safe Org mode defcustoms. Why not just promote that
instead? Or provide syntactic sugar for it inside a "settings
drawer"?!... That would both reduce complexity and increase
configurability.

Making the setting-drawer work similar to property-drawers might allow
for a "Set Startup" interactive function that can take the same
arguments as are available for the Startup-keyword today. I'm sure
using startup has it's merits for those who are used to it, so
depricating it in favour of another more general solution is not an
option.

* Property
:PROPERTIES:
:has-entry-syntax: t
:END:
The property keyword is used to set properties for the whole document.
Main intention seems to be for inheritance-purposes. When working in a
multi-file project (not yet supported that well...) having
document-properties are meaningful also without inheritance. One can
imagine a set of org-mode files without headlines in a folder where
one would want to set ID's for example, and link between the files
using these ID's.

Property-keywords can be defined anywhere inside the file, even inside
headlines. The property that is set using the keyword-syntax always
applies to the whole document (unless overridden in headlines). If one
property is defined multiple times the last definition is used.

*I propose to depricate property-keywords* in its current form, and
introduce (1) a property-drawer for the document node and (2) a new
kind of property-keyword that is only valid at a certain point in the
buffer. Properties in property-drawers should override the existing
properties set by (the existing) property-keyword, as long as both
ways to define document-level properties are supported.

** New kind of property-keyword
The new kind of property-keyword would be on the form
=#+{propertyname}: {propertyvalue}= and would only be applicable if
entered directly at the top of the buffer, below potential
comment-lines but before any blank line and before the setting drawer
and the property drawer. Ideally a property-keyword shall override a
property set in the document property drawer, if the keyword is
defined in both places.

* Options
:PROPERTIES:
:HAS-ENTRY-SYNTAX: t
:END:
The options-keyword is used solemly when exporting. This is
unfortunately not obvious by the naming of the keyword.

The same functionality exist also for subtrees. Then the
export-options are specified as properties with the key
'EXPORT_OPTIONS'.

*I propose to depricate the Options-keyword* and start using the
document-level property-drawer.

* Various Export-keywords
:PROPERTIES:
:HAS-ENTRY-SYNTAX: t
:END:
Keywords such as Title, Subtitle, Author, Date, Email are documented
as "export-keywords". Ref: [[info:org#Export Settings][info:org#Export Settings]]

*I propose to relabel these keywords as document keywords*. That label
is more fitting and does not provide any negative side-effects since
an export anyways is supposed to export org-mode information. If
anything, the relabeling promotes the keywords to first-class citizens
within org-mode.

I also propose to specify a fixed set of document-keywords that
org-mode support (i.e. document them) and provide a command to easily
insert them into the buffer. The location of these keywords should be
at the top of the buffer, after potential comment-lines but before the
document-level settings-drawer and properties-drawer.

Unsupported document-keywords can also be included but might not be
guaranteed to be exported, or function correctly from other
perspectives. But by their location in the top of the buffer, they
should be recognized as document-keywords non the less.

The reason for not wanting to depricate the keywords for these
properties and delegate them to the properties-drawer is that these
are keywords that makes sense to visually promote inside a buffer. I'm
for example quite often using a =#+TITLE:= line to declare the title
of the document. Hiding that line inside the properties-drawer is
counter-intuitive. I might however want to "demote" some of the
document-level keywords into a drawer for various reasons. So allowing
document-keywords to also be specified as keywords makes sense.

* Category
:PROPERTIES:
:HAS-ENTRY-SYNTAX: t
:END:

Can either be defined at document-level with =#+CATEGORY= or at
entry-level with a property named the same.

*I propose to depricate the #+CATEGORY syntax* in favour of a category
property inside the proposed document-level property-drawer.

* Filetags
:PROPERTIES:
:HAS-ENTRY-SYNTAX: normal tag inheritance
:END:

Filetags are tags set on document-level.

*I propose to depricate the #+FILETAGS syntax* in favour of a tags
property inside the proposed document-level property-drawer.

Now this might be a bit confusing since the Tags-keyword also exist on
document-level. More on that in it's own entry: [[id:ba02b48b-261a-4e65-b9a2-dfc57391ae41][Tags]].

* Columns
:PROPERTIES:
:has-entry-syntax: t
:END:

Can either be defined at document-level with =#+COLUMNS= or at
entry-level with a property named the same.

*I propose to depricate the #+COLUMNS syntax* in favour of a columns
property inside the proposed document-level property-drawer.

* Archive
:PROPERTIES:
:HAS-ENTRY-SYNTAX: t
:END:

Can either be defined at document-level with =#+ARCHIVE= or at
entry-level with a property named the same.

*I propose to depricate the #+ARCHIVE syntax* in favour of an archive
property inside the proposed document-level property-drawer.

* TODO, SEQ_TODO, TYP_TODO
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
Setting the default allowed todo-values for a buffer (using the local
variable =org-todo-keywords-1=.

them as available keys in the proposed settings-drawer.

* Priorities
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
Setting default priority-values for a buffer.

priorities as an available key in the proposed settings-drawer.

* Tags
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:ID:       ba02b48b-261a-4e65-b9a2-dfc57391ae41
:END:

Tags-keyword is used when setting the buffer-local variable
org-current-tag-alist. This defines the default tags available for
autocompletion within the buffer.

There can be more than one Tags-keyword per file and all rows
accumulate together into the final list of tags available.

*I propose to depricate the tags-keyword* and instead add tags as a
keyword available in the proposed settings-drawer.

:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
Link-abbreviations that can be used throughout the document.

keyword available in the proposed settings-drawer.

* Constants
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
buffer-global constans that can be used by tables and nothing else.

Set by =org-set-regexps-and-options=, using
=org--setup-collect-keywords=, into
=org-table-formula-constants-local=. As I understand it.

They fit closely together with link-abbreviations in how the keywords
are used to populate buffer-wide special key-value pairs. They differ
from properties since they are special-purpose.

constants as a key available in the proposed settings-drawer.

* Setupfile
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
Outsourcing of settings to another file (or url).

setupfile as a key available in the proposed settings-drawer.

* Macro
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
Text snippets.

macro as a key available in the proposed settings-drawer.

* Inline-keywords
:PROPERTIES:
:HAS-ENTRY-SYNTAX: n/a
:END:
Keywords which are used to provide content at a certain location in the
file.

Keywords: =INCLUDE=, =TOC=, =ASCII=, =HTML=, =LATEX=, =ODT=,
=TEXINFO=, =BEAMER=, =INDEX=

I have no issue with these keywords.

* Affiliated keywords
:PROPERTIES:
:HAS-ENTRY-SYNTAX: n/a
:END:
Keywords that relates to or adds information to objects within the
buffer. List of keywords is found in
=org-element-affiliated-keywords=. (Ex. NAME, CAPTION, RESULT, etc.)

These are not of my concern here, I haven't used them much but when I
have I haven't had any problems with them. The functionality is clear.

* Misc
:PROPERTIES:
:HAS-ENTRY-SYNTAX: nil
:END:
There are more keywords... But with my current understanding there
were no keywords that would make my suggestions invalid. I just
didn't work my way through them all since I thought of them as very
specific and of minor importance.

** Bind
Used for very advanced exporting. They seem to apply to the whole
document but only when the document is being exported. I'll call it a
special kind of export keyword for now...

** Specific export-backend keywords
I didn't work my way though all export-backend keywords. My guess is
that most of them could fit into either of the proposed drawer, the
document-keywords section (for example the Description-keyword that
can be used in HTML-export) or that they are inline or affiliate
keywords, which I'm not addressing here.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-20  2:28 [RFC] Document level property drawer Gustav Wikström
@ 2019-10-22 21:24  Marco Wahl
2019-10-23  8:43  Marco Wahl
2 siblings, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2019-10-22 21:24 UTC (permalink / raw)
To: emacs-orgmode

Gustav Wikström <gustav@whil.se> writes:

[...]

> Sooo, a separate branch is created in the Org mode repository named
> "next". I'm not entirely sure how we're supposed to work with it. But
> I've anyways pushed my (non-breaking) patch there.

Okay, thanks.  I try to follow the development on the 'next' branch.

[...]

>> Noteworthy observations AFAICT:
>>
>> 1. I could not translate my personal "#+TODO: . N ~ | x c g >" into a
>> respective :TODO: property.
>
> Yes, that's true. The reason is that there is no TODO-property that
> fits in property drawers right now. I.e. special properties such as
> TODO, TAGS, priority, scheduling and deadlines that have special
> syntax for the outline still have no defined meaning for outline level
> 0. I ofc. think that's an oversight ;) But I may also be a bit crazy.
>
> A conclusion to draw from that, that may be worth writing more about,
> is that the property drawer for node level 0 will not be able to
> replace all file-level keywords that exist today.  Only properties that
> currently can also be defined in property drawers in the outline will
> work in the property drawer on level 0.  Makes sense?

Absolutely.

> The idea I had for all the other keywords that apply for the whole
> file was to create another drawer, what I called a settings drawer.
> Because the TODO-keyword you refer to above really is a setting that
> you're making for the current file, much the same as when you make
> changes in global, folder local or file local variables using the
> standard emacs framework.

The idea of a settings drawer makes sense AFAICS.

For the special case of TODO-keywords one could think about defining
them per subtree.  Possibly there are some low hanging fruit among the
whole-file-properties that have a natural interpretation per subtree.

> I've attached an investigation I did of the world of Org mode
> keywords. It was done quite a while back and some things in there are
> subjective and may not represent my current picture of the "ideal".
> Nonetheless, maybe an interesting read for the ... other crazy people
> out there?

Okay, I'll have a look at your investigation. ;)

BTW this document looks great to me at the first glance.

Thanks,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-20  2:28 [RFC] Document level property drawer Gustav Wikström
2019-10-22 21:24  Marco Wahl
@ 2019-10-23  8:43  Marco Wahl
2019-10-23  8:59    Gustav Wikström
2019-10-24 21:01    Gustav Wikström
2019-10-23 16:08  Adam Porter
2 siblings, 2 replies; 35+ messages in thread
From: Marco Wahl @ 2019-10-23  8:43 UTC (permalink / raw)
To: emacs-orgmode

> Sooo, a separate branch is created in the Org mode repository named
> "next". I'm not entirely sure how we're supposed to work with it. But
> I've anyways pushed my (non-breaking) patch there.

Thanks again.

One issue for me is the positioning of the level 0 property drawer.
Having the requirement for that drawer starting in the very first line
is too strong for me.

I guess one would at least like to have the option to add some
configuration with the ‘-*-...-*-’ construct which currently only works
in the first line.

Further I think one would also like to place #+: configuration lines
there in particular the #+title: line.

What about allowing lines starting with character # above the level 0
property drawer?  And put a newly created level 0 property drawer below
the first line in the file that does not start with #?

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-23  8:43  Marco Wahl
@ 2019-10-23  8:59    Gustav Wikström
2019-10-24 21:01    Gustav Wikström
1 sibling, 0 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-23  8:59 UTC (permalink / raw)
To: Marco Wahl

Hi,

> One issue for me is the positioning of the level 0 property drawer.
> Having the requirement for that drawer starting in the very first
> line is too strong for me. I guess one would at least like to have
> the option to add some configuration with the ‘-*-...-*-’ construct
> which currently only works in the first line.

Hmm, that should work right now. 0..n comment lines are supposed to be
allowed anyways. I can debug that a bit later to see if something has
gone amiss.

> Further I think one would also like to place #+: configuration lines
> there in particular the #+title: line. What about allowing lines
> starting with character # above the level 0 property drawer? And put
> a newly created level 0 property drawer below the first line in the

The first patch allowed both coments ("# "-lines) and keyword lines
(#+...:) as well. But I removed keyword lines for now to start with a
bit more strict definition, per request from Nicolas. I think the
parser will be happy if there is as little information abouve the
drawer as possible, since it will have to retrace itself from the
first line of the buffer every time it needs to verify that the drawer
actually is the "proper" property drawer. If that makes sense. So the
more restrictive we can allow us to be, the better the performance and
the easier it will be to understand where the drawer goes. And less
complexity.

Happy to get more feedback on that decision though!

Thanks! Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-20  2:28 [RFC] Document level property drawer Gustav Wikström
2019-10-22 21:24  Marco Wahl
2019-10-23  8:43  Marco Wahl
@ 2019-10-23 16:08  Adam Porter
2 siblings, 0 replies; 35+ messages in thread
To: emacs-orgmode

Gustav,

There are a lot of deprecation recommendations in your attached
document:

> I propose to depricate property-keywords
> I propose to depricate the Options-keyword
> I propose to relabel these keywords as document keywords
> I propose to depricate the #+CATEGORY syntax
> I propose to depricate the #+FILETAGS syntax
> I propose to depricate the #+COLUMNS syntax
> I propose to depricate the #+ARCHIVE syntax
> I propose to depricate the TODO-keywords
> I propose to depricate the priorities-keyword
> I propose to depricate the tags-keyword
> I propose to depricate the link-keyword
> I propose to depricate the constants-keyword
> I propose to depricate the setupfile-keyword
> I propose to depricate the Macro-keyword

However, I propose that we don't deprecate any of those.  Org has been
around for over a decade now.  Such drastic changes would not serve
users well.

Note that I'm taking your use of the word "deprecate" to mean what
it's expected to mean in this context: that the software developers
recommend against using it, with the intention to eventually remove
support for the feature.  We shouldn't be removing any such features
from Org.

Not only would it not serve users well, but it would make the software
much more complicated.  As it stands, finding, e.g. a #+CATEGORY:
keyword and getting its value is as simple as:

(save-excursion
(goto-char (point-min))
(when (re-search-forward (rx bol "#+CATEGORY:" (1+ blank)
(group (1+ nonl)))
nil t)
(match-string 1)))

Hiding those keywords in drawers means that either:

a) Eligible drawers must be located, and then the desired
property must be searched for inside of them.

b) Possibly valid properties must be located, and each one must be
confirmed to be inside an eligible drawer.

What benefit would this added complexity serve?  To put the keywords
in one place in the document?  There are already multiple ways to
achieve that.

I can't emphasize enough how important stability and consistency is
for Org and its file formats right now.  As I've said, there are new
implementations in development, which have the potential to bring a
lot of publicity and new users to Org.  For example, this one was
mentioned on a Hacker News post a few days ago:

https://github.com/mickael-kerjean/filestash

In the same HN post were examples of implementations for Vim and
VSCode.  Already, especially in the VSCode ones, there were apparent
incompatibilities in their implementations of the Org file format.

As well, there are now parsers in JavaScript, Python, and Rust.

Markdown is by far the most popular plain-text format, and has been
for years, but it has long suffered from competing, slightly
incompatible flavors and implementations.  Reddit has theirs, GitHub
has theirs, etc.

Org's file format may finally be gaining some momentum.  Let's not
jeopardize Org's chances by making implementors' job more difficult

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-23  8:43  Marco Wahl
2019-10-23  8:59    Gustav Wikström
@ 2019-10-24 21:01    Gustav Wikström
2019-10-25 12:58      Marco Wahl
From: Gustav Wikström @ 2019-10-24 21:01 UTC (permalink / raw)
To: Marco Wahl; +Cc: emacs-orgmode

Hi,

> One issue for me is the positioning of the level 0 property drawer.
> Having the requirement for that drawer starting in the very first
> line is too strong for me. I guess one would at least like to have
> the option to add some configuration with the ‘-*-...-*-’ construct
> which currently only works in the first line.

Hmm, that should work right now. 0..n comment lines are supposed to be
allowed anyways. I can debug that a bit later to see if something has
gone amiss.

> Further I think one would also like to place #+: configuration lines
> there in particular the #+title: line. What about allowing lines
> starting with character # above the level 0 property drawer? And put
> a newly created level 0 property drawer below the first line in the

The first patch allowed both coments ("# "-lines) and keyword lines
(#+...:) as well. But I removed keyword lines for now to start with a
bit more strict definition, per request from Nicolas. I think the
parser will be happy if there is as little information abouve the
drawer as possible, since it will have to retrace itself from the
first line of the buffer every time it needs to verify that the drawer
actually is the "proper" property drawer. If that makes sense. So the
more restrictive we can allow us to be, the better the performance and
the easier it will be to understand where the drawer goes. And less
complexity.

Happy to get more feedback on that decision though!

Thanks! Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-24 21:01    Gustav Wikström
@ 2019-10-25 12:58      Marco Wahl
0 siblings, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2019-10-25 12:58 UTC (permalink / raw)
To: emacs-orgmode

>> One issue for me is the positioning of the level 0 property drawer.
>> Having the requirement for that drawer starting in the very first
>> line is too strong for me. I guess one would at least like to have
>> the option to add some configuration with the ‘-*-...-*-’ construct
>> which currently only works in the first line.
>
> Hmm, that should work right now. 0..n comment lines are supposed to be
> allowed anyways. I can debug that a bit later to see if something has
> gone amiss.

You are right!  No need to debug anything.  I had #+: lines before the
first property drawer.  Sorry for the confusion.

>> Further I think one would also like to place #+: configuration lines
>> there in particular the #+title: line. What about allowing lines
>> starting with character # above the level 0 property drawer? And put
>> a newly created level 0 property drawer below the first line in the
>
> The first patch allowed both coments ("# "-lines) and keyword lines
> (#+...:) as well. But I removed keyword lines for now to start with a
> bit more strict definition, per request from Nicolas. I think the
> parser will be happy if there is as little information abouve the
> drawer as possible, since it will have to retrace itself from the
> first line of the buffer every time it needs to verify that the drawer
> actually is the "proper" property drawer. If that makes sense. So the
> more restrictive we can allow us to be, the better the performance and
> the easier it will be to understand where the drawer goes. And less
> complexity.

Okay.  I keep going with this setting.

I can imagine that the parser is happy with less possibilities
and the user is happy with fast parsing.

But I'm not 100% convinced that #+: lines should not be allowed before
the level 0 property drawer.  E.g. #+title: in the first line looks nice
AFAICT.

> Happy to get more feedback on that decision though!

Hopefully some more feedback comes in...

Best regards,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2020-01-15  8:18          Sebastian Miele
@ 2020-02-01 19:59            Marco Wahl
0 siblings, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2020-02-01 19:59 UTC (permalink / raw)
To: emacs-orgmode

>> Sebastian Miele <sebastian.miele@gmail.com> writes:

>>> I would like to be able to make a clear distinction between properties
>>> that are visible by default and properties that are not. Maybe it would
>>> be possible to allow some #+.. syntax following headings for subtree
>>> properties that are visible by default. A requirement could be made that
>>> such property specifications always have to be followed by a property
>>> drawer, even if that is empty. Then everything #+.. that is before the
>>> property drawer would belong to the heading/subtree, and everything #+..
>>> that follows the drawer would be treated as it is until now.
>>>
>>> Please tell me if I missed something and Org is already capable of
>>> something like that. If not, are there others who would like
>>> visible-by-default property specifications for headings/subtrees in
>>> addition to invisible-by-default property specifications in drawers,
>>> too?
>>
>> I don't think Org is capable of this out of the box right now.  Further
>> I don't feel the need for a visible-by-default property, but that's just
>> me.
>
> After a few more months of living without that feature I must say that I
> basically live perfectly well without that, too. I just do not define
> source block header args in property drawers. It gets a bit verbose at
> times. But not to the degree of being painful.

Sounds good to me.

>>> Finally, I would like to state an opinion: If there is
>>> visible-by-default (by #+..) and invisible-by-default (by drawers)
>>> syntax for headings/subtrees, including level 0, it may be viable to
>>> require them to be disjoint for each heading/subtree. Most probably it
>>> would be good practice, anyway. And the precedence question raised
>>> previously in this thread would be eliminated.
>>
>> I may not feel the need for the visible/invisible-by-default properties
>> but actually I like the idea of #+ properties parallel to the property
>> drawers as visible by default properties.  But since the #+ properties
>> may appear anywhere in the Org file and affect the whole file it would
>> be difficult or even impossible to give them reliable meaning for
>> subtrees AFAICS.
>
> In the meantime I had a look into worg/dev/org-syntax.org. From the
> document: "Property drawers are a special type of drawer containing
> properties attached to a headline. They are located right after a
> headline and its planning information."

Thanks for the quote.

> So, currently, #+ properties may not appear between a heading and a
> property drawer. At least not without turning the property drawer into a
> non-special drawer. So, in principle, it would be possible to change the
> syntax of Org to allow #+ properties between headings and (possibly
> empty) property drawers in order to denote visible-by-default
> properties attached to a heading.

Sounds true AFAICS.

> Moreover, this change probably would introduce very little to no
> backwards incompatibility. With the change it would not be possible to
> turn property drawers into non-special drawers by putting a #+ property
> before them. Now it is possible to sort of uncomment property drawers by
> putting #+ properties before them. This "feature" probably is hardly
> used, if at all.

I also think this is very corner case-y.

All in all I think your idea is good.  But the masses did not scream for
that change so I think your idea is something for a wishlist to wait for
further discussion.

Best regards,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2020-01-13 21:52        Marco Wahl
@ 2020-01-15  8:18          Sebastian Miele
2020-02-01 19:59            Marco Wahl
From: Sebastian Miele @ 2020-01-15  8:18 UTC (permalink / raw)
To: Marco Wahl; +Cc: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

> Sebastian Miele <sebastian.miele@gmail.com> writes:
>
>> But for such properties to satisfactorily work for me, they would have
>> to be visible by default. E.g. I would want the header-args to be
>> immediately visible just like they are when they are written after
>> #+BEGIN_SRC or #+HEADER. Otherwise I would find myself constantly
>> wondering whether this or that property drawer contains something
>> essential and every TAB on a collapsed headline would have be followed
>> by an accompanying move to the property drawer and a TAB there.
>>
>> On the other hand, there are properties that are very good candidates
>> for remaining hidden by default, like ID.
>>
>> I would like to be able to make a clear distinction between properties
>> that are visible by default and properties that are not. Maybe it would
>> be possible to allow some #+.. syntax following headings for subtree
>> properties that are visible by default. A requirement could be made that
>> such property specifications always have to be followed by a property
>> drawer, even if that is empty. Then everything #+.. that is before the
>> property drawer would belong to the heading/subtree, and everything #+..
>> that follows the drawer would be treated as it is until now.
>>
>> Please tell me if I missed something and Org is already capable of
>> something like that. If not, are there others who would like
>> visible-by-default property specifications for headings/subtrees in
>> addition to invisible-by-default property specifications in drawers,
>> too?
>
> I don't think Org is capable of this out of the box right now.  Further
> I don't feel the need for a visible-by-default property, but that's just
> me.

After a few more months of living without that feature I must say that I
basically live perfectly well without that, too. I just do not define
source block header args in property drawers. It gets a bit verbose at
times. But not to the degree of being painful.

>> Finally, I would like to state an opinion: If there is
>> visible-by-default (by #+..) and invisible-by-default (by drawers)
>> syntax for headings/subtrees, including level 0, it may be viable to
>> require them to be disjoint for each heading/subtree. Most probably it
>> would be good practice, anyway. And the precedence question raised
>> previously in this thread would be eliminated.
>
> I may not feel the need for the visible/invisible-by-default properties
> but actually I like the idea of #+ properties parallel to the property
> drawers as visible by default properties.  But since the #+ properties
> may appear anywhere in the Org file and affect the whole file it would
> be difficult or even impossible to give them reliable meaning for
> subtrees AFAICS.

In the meantime I had a look into worg/dev/org-syntax.org. From the
document: "Property drawers are a special type of drawer containing
properties attached to a headline. They are located right after a

So, currently, #+ properties may not appear between a heading and a
property drawer. At least not without turning the property drawer into a
non-special drawer. So, in principle, it would be possible to change the
syntax of Org to allow #+ properties between headings and (possibly
empty) property drawers in order to denote visible-by-default

Moreover, this change probably would introduce very little to no
backwards incompatibility. With the change it would not be possible to
turn property drawers into non-special drawers by putting a #+ property
before them. Now it is possible to sort of uncomment property drawers by
putting #+ properties before them. This "feature" probably is hardly
used, if at all.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-01 12:38      Sebastian Miele
@ 2020-01-13 21:52        Marco Wahl
2020-01-15  8:18          Sebastian Miele
From: Marco Wahl @ 2020-01-13 21:52 UTC (permalink / raw)
To: Sebastian Miele; +Cc: emacs-orgmode

Sebastian Miele <sebastian.miele@gmail.com> writes:

> But for such properties to satisfactorily work for me, they would have
> to be visible by default. E.g. I would want the header-args to be
> immediately visible just like they are when they are written after
> #+BEGIN_SRC or #+HEADER. Otherwise I would find myself constantly
> wondering whether this or that property drawer contains something
> essential and every TAB on a collapsed headline would have be followed
> by an accompanying move to the property drawer and a TAB there.
>
> On the other hand, there are properties that are very good candidates
> for remaining hidden by default, like ID.
>
> I would like to be able to make a clear distinction between properties
> that are visible by default and properties that are not. Maybe it would
> be possible to allow some #+.. syntax following headings for subtree
> properties that are visible by default. A requirement could be made that
> such property specifications always have to be followed by a property
> drawer, even if that is empty. Then everything #+.. that is before the
> property drawer would belong to the heading/subtree, and everything #+..
> that follows the drawer would be treated as it is until now.
>
> Please tell me if I missed something and Org is already capable of
> something like that. If not, are there others who would like
> visible-by-default property specifications for headings/subtrees in
> addition to invisible-by-default property specifications in drawers,
> too?

I don't think Org is capable of this out of the box right now.  Further
I don't feel the need for a visible-by-default property, but that's just
me.

> Finally, I would like to state an opinion: If there is
> visible-by-default (by #+..) and invisible-by-default (by drawers)
> syntax for headings/subtrees, including level 0, it may be viable to
> require them to be disjoint for each heading/subtree. Most probably it
> would be good practice, anyway. And the precedence question raised
> previously in this thread would be eliminated.

I may not feel the need for the visible/invisible-by-default properties
but actually I like the idea of #+ properties parallel to the property
drawers as visible by default properties.  But since the #+ properties
may appear anywhere in the Org file and affect the whole file it would
be difficult or even impossible to give them reliable meaning for
subtrees AFAICS.

My 2ct,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-24 22:29 Gustav Wikström
0 siblings, 0 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-24 22:29 UTC (permalink / raw)

> There are a lot of deprecation recommendations in your attached
> document:
>
> > I propose to depricate property-keywords
> > I propose to depricate the Options-keyword
> > I propose to relabel these keywords as document keywords
> > I propose to depricate the #+CATEGORY syntax
> > I propose to depricate the #+FILETAGS syntax
> > I propose to depricate the #+COLUMNS syntax
> > I propose to depricate the #+ARCHIVE syntax
> > I propose to depricate the TODO-keywords
> > I propose to depricate the priorities-keyword
> > I propose to depricate the tags-keyword
> > I propose to depricate the link-keyword
> > I propose to depricate the constants-keyword
> > I propose to depricate the setupfile-keyword
> > I propose to depricate the Macro-keyword
>

Thanks!

> However, I propose that we don't deprecate any of those.  Org has been
> around for over a decade now.  Such drastic changes would not serve
> users well.

I think you're right in the fact that Org mode will need to continue
to understand them. I'll say again that I wrote the document quite a
while ago. It's unedited and initially meant for my eyes only. So "to
deprecate" may be perceived to strong and I certainly didn't mean to
cut them out straight away. I don't think the diverse use of keywords
are good for the future of Org mode though, and I do think there is
value in trying to consolidate functionality and possibly promote
something that is more clear and easy to understand. Many of the
existing keywords have a corresponding property-syntax. For those I
think it would be good to start promoting using properties instead of
keywords (as I've written over and over again :) ). Other keywords
affect the Org mode configuration for the current buffer. They are
basically shortcuts to customization for the current buffer. Which led
me to proposing a settings drawer. It may be that it initially is
enough to just update the documentation with a chapter about keywords
and categorizing them in some groups based on intended purpose. I do
however still like the idea of collecting those keywords in a drawer

> Note that I'm taking your use of the word "deprecate" to mean what
> it's expected to mean in this context: that the software developers
> recommend against using it, with the intention to eventually remove
> support for the feature.  We shouldn't be removing any such features
> from Org.
>
> Not only would it not serve users well, but it would make the software
> much more complicated.  As it stands, finding, e.g. a #+CATEGORY:
> keyword and getting its value is as simple as:
>
>     (save-excursion
>       (goto-char (point-min))
>       (when (re-search-forward (rx bol "#+CATEGORY:" (1+ blank)
>                                    (group (1+ nonl)))
>                                nil t)
>         (match-string 1)))
>
> Hiding those keywords in drawers means that either:
>
> a) Eligible drawers must be located, and then the desired
> property must be searched for inside of them.
>
> b) Possibly valid properties must be located, and each one must be
> confirmed to be inside an eligible drawer.
>
> What benefit would this added complexity serve?  To put the keywords
> in one place in the document?  There are already multiple ways to
> achieve that.

I don't agree here. Keywords today break the outline and have no
positional requirements. Both a property and a settings drawer would
have a fixed position to make it easy to locate, both programmatically,
visually and by search.

> I can't emphasize enough how important stability and consistency is
> for Org and its file formats right now.  As I've said, there are new
> implementations in development, which have the potential to bring a
> lot of publicity and new users to Org.  For example, this one was
> mentioned on a Hacker News post a few days ago:

There is always a balance between stability, backwards compatibility
and progression. I agree that backwards compatibility and stability is
important. But I also argue that progression is important. Good if Org
mode is gaining traction! But that doesn't mean we can't improve it
further, for it to gain even more traction! And in the larger scheme
of things, Org mode still is tiny. So let's not oversell ourselves
here. It's almost like a catch 22. But the largest hinderance for Org
mode to grow further is probably its ties with Emacs, the very thing
that makes Org mode into the powerhouse it is!

> https://github.com/mickael-kerjean/filestash
>
> In the same HN post were examples of implementations for Vim and
> VSCode.  Already, especially in the VSCode ones, there were apparent
> incompatibilities in their implementations of the Org file format.

I've been a promoter of separating the Org mode syntax from Emacs for
a long time. I think I've written about it on this list previously as
well. So I know what you mean. That still isn't any argument for
stopping progress and improvement.

> As well, there are now parsers in JavaScript, Python, and Rust.
>
> Markdown is by far the most popular plain-text format, and has been
> for years, but it has long suffered from competing, slightly
> incompatible flavors and implementations.  Reddit has theirs, GitHub
> has theirs, etc.
>
> Org's file format may finally be gaining some momentum.  Let's not
> jeopardize Org's chances by making implementors' job more difficult

I think that's a bit to defensive from Org mode's perspective. Yes, we
should promote other tools to start implementing Org mode parsers. No,
we shouldn't make it more difficult. But also let's not stop all
progress with the belief that it will make life easier. I believe that
a document property drawer that follows the syntax of the outline
drawer will make life easier for those you're talking about. Though in
the end it's always the end users we have to think most about.

I think your lobbying against this has had effect though, since the
property drawer already is out of 9.3 and in a separate branch.

Regards,
Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-15 17:49  Gustav Wikström
2019-10-16  0:48    Adam Porter
@ 2019-10-16  9:48    Marco Wahl
1 sibling, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2019-10-16  9:48 UTC (permalink / raw)
To: emacs-orgmode

Gustav Wikström <gustav@whil.se> writes:

> I'd like to take the next step with this patch. I'm hesitant to do it
> without wider support though, since only a few people have commented.
>
> @Marco Wahl; As I understand you've applied the patch and tried it
> out. Have you found any issues yet? What do you think of the patch
> after having used it for a while?

Indeed I applied your patch and have it applied still.  Please note that
I did nothing fancy and in particular I did not try to break the patch.

The patch works good for me.

Noteworthy observations AFAICT:

1. I could not translate my personal "#+TODO: . N ~ | x c g >" into a
respective :TODO: property.

2. With org-ids turned on and point before the first heading, function
org-store-link creates an org-id property at the document level.

Regarding number 1. I think a list of document-level properties which
don't behave the same when used in the document property drawer would be
nice.  Ideally this list is empty AFAICT.  Maybe I overlook something.
Is this an issue?

I think observation 2. is just a little surprise but turns out to be
natural when the document level property drawer is enabled.

Still +1 for the inclusion of the patch and HTH,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-15 17:49  Gustav Wikström
2019-10-16  9:48    Marco Wahl
1 sibling, 0 replies; 35+ messages in thread
To: emacs-orgmode

Gustav Wikström <gustav@whil.se> writes:

> Hi again,
>
> I'd like to take the next step with this patch. I'm hesitant to do it
> without wider support though, since only a few people have commented.
>
> @Marco Wahl; As I understand you've applied the patch and tried it
> out. Have you found any issues yet? What do you think of the patch
> after having used it for a while?
>

Please do not merge your patch without the approval of the Org
maintainers.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-29 10:27 Gustav Wikström
2019-09-29 19:13  Marco Wahl
2019-09-30 16:01  Adam Porter
@ 2019-10-15 17:49  Gustav Wikström
2019-10-16  0:48    Adam Porter
2019-10-16  9:48    Marco Wahl
2 siblings, 2 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-15 17:49 UTC (permalink / raw)
To: emacs-orgmode, Marco Wahl; +Cc: Nicolas Goaziou

Hi again,

I'd like to take the next step with this patch. I'm hesitant to do it without wider support though, since only a few people have commented.

@Marco Wahl; As I understand you've applied the patch and tried it out. Have you found any issues yet? What do you think of the patch after having used it for a while?

Regards
Gustav

> -----Original Message-----
> From: Gustav Wikström
> Sent: den 29 september 2019 12:27
> To: emacs-orgmode@gnu.org
> Cc: Nicolas Goaziou <mail@nicolasgoaziou.fr>
> Subject: [RFC] Document level property drawer
>
> Hi,
>
> This patch introduces a document level property drawer.
>
> This has been discussed previously in a larger context:
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-06/msg00000.html
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-08/msg00339.html
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-09/msg00010.html
>
> The patch is a somewhat modified version of what was included in the third
>
> The following will be true for document level property drawers:
> 1) In the same way that one can have a property drawer for a heading, one
>    can have a property drawer for a whole document.
> 2) All existing commands that can work with property drawers will
>    (shall) work also on property drawers before the first heading.
> 3) Properties defined in a property drawer will have precedence over
>    properties defined as a property keyword, if the same property is
>    defined using both conventions.
> 4) The position for the document level property drawer is:
>    - At the first line in a file that is not a comment or a keyword.
>
>      I.e. the following will work:
>      #+begin_src org
>        # -*- mode: org -*-
>        ,#+TITLE: Test
>        :PROPERTIES:
>        :CATEGORY: Test
>        :END:
>
>        Preamble
>
>        Some content
>      #+end_src
>
>      but not this:
>      #+begin_src org
>        Some comment and/or empty line
>
>        :PROPERTIES:
>        :CATEGORY: Test
>        :END:
>
>        Some content
>      #+end_src
>
> What do you say?
>
> Regards
> Gustav Wikström

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-06  1:01      Adam Porter
@ 2019-10-07  7:46        Marco Wahl
0 siblings, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2019-10-07  7:46 UTC (permalink / raw)
To: emacs-orgmode

> Marco Wahl <marcowahlsoft@gmail.com> writes:
>
>> property definition syntax or at least think about a good place within
>> a file or a subtree for those definitions.  (There is at least
>> Sebastian Miele who wants to keep that syntax as he stated in another
>
> You do realize, don't you, how much software and how many documents such
> a change would break?  One of the primary reasons Org users use Org is
> that its file format is very long-lived and flexible.  There are even
> academic papers written in Org, exported to LaTeX, and a change such as
> that would break them, creating needless work for their authors or other
> interested parties to fix them up in order to still be exportable.

now.  I understand that the file-wide properties in their current
meaning need to stay a good while, maybe even as long as Org lives.

Back to the issue of the document level property drawer: could it be we

What is an example which shows how the introduction of a document level
property drawer breaks something in the Org universe?  (I think there is
none.)

Ciao,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-06  6:02 Gustav Wikström
0 siblings, 0 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-06  6:02 UTC (permalink / raw)
To: moptop99; +Cc: emacs-orgmode

Hi Matt,

Thanks for your comment! I can assure you that you need not worry
about the propsed patch here in terms of your workflow. This is in no
way a hasty, sloppy work. Care has been taken when developing it to
not break anything existing. I hear your concerns on the larger topic
of keywords though. But that's not something that is changing in this
patch.

> I'd like to just quickly chime in in support of Adam's caution on this
> issue. I can absolutely see advantages to document level properties, I
> have written many code fragments that rely on the use of keywords and
> expect org filensyntax to be consistent with what actually exists. I
> use these code fragments to hold together a somewhat fragile workflow
> that allows me to use org in a work environment that is not especially
> receptive to simple text documents. I have invested a lot of time in
> making those systems run and sometimes even I don't entirely remember
> what I did to make them possible.
>
> It would really, really suck to have those systems break. It would
> take me a lot of time to track down the causes and change what I
> needed to. VMs that currently pull in Emacs andnorg and my code would
> stop working. Old versions of my files would no longer render
> properly. My efforts to make my courses and other writings effectively
> reproducible by others would be significantly set back. Etc. I think
> these are the kinds of difficulties Adam means to describe.

Again, caution is ofc taken. In no way does this patch change any of
your existing properties. If something, it proposes a way for you to
simplify your setup if you at any time in the future choose to do
that.

The patch that is applied is tested and no existing functionailty is
changed. Ofc, if you have a critical flow I'd advice you to use the
stable branch of Org mode and not rely on the master branch, since
that branch from time to time will get bugs in it.

Regards
Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-06  5:35 Gustav Wikström
0 siblings, 0 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-06  5:35 UTC (permalink / raw)

[-- Attachment #1: Type: text/plain, Size: 8796 bytes --]

> > In no way is this a major, breaking change.  No document you have

> > today will break by the introduction of this.  The only thing changing

> > is if you *actively* create a document level property drawer and

> > choose to enter a property there that you already have defined in the

> > same document, using a property keyword.

>

> There is a bigger picture which you seem to be ignoring.

No I'm not ignoring any bigger picture. Hence the RFC which I'm asking

for comments about. So far a couple of positive remarks and your

comments on the other end of the spectrum.

> Org is distributed with Emacs itself.  Emacs versions are long-lived.

> People use old Emacs and Org versions for years, because few people

> build and install Emacs themselves, so most users use the versions

> included with their OS or other distributions.

Yes.

> Your proposed change would introduce a major change in the way document

> properties are interpreted.  This means that the same document, when

> used on Emacs/Org versions before and after this change, would be

> interpreted differently.  That's breaking forward-compatibility between

> versions, ones which will be in the wild for years.  That decision

> should not be taken lightly.

No, not really. Here we disagree again. I already interpret the

documents as an outline. And it seems others agree with me on that as

well. Your interpretation may be different but I fail to see where the

documentation agrees with your sentiment. The fact that some commands

that works for the outline doesn't work before the first headline has

been a shortcoming for a long time. I don't think that shortcoming is

something to continue to strive for.

Forward compatibility should indeed be taken into account. I don't

think the argument to stop this change due to breaking forward

compatibility is that strong though. If I as a user choose to use new

features, I agree to also use new software. As a package author you

can continue to rely on Org element and assume the user understands

that relation. If your packages creates property keywords today you

can continue to do so, or consider upgrading your package to depend on

Org mode 9.3 and start using the new feature to more easily insert

properties into a document level property drawer. If you do that you

of course have to mark your dependency to Org mode 9.3 as well.

> > Keywords that previously had file-wide effects will continue to have

> > that. That's not removed. So you must have misunderstood something

> > here.

>

> I did not misunderstand; I am looking from a different perspective.  In

> your proposal, line-based keywords can be overridden by document-level

> property drawers, while they currently are applied to the entire file

> regardless of any drawers.  That is a major change.

Ok, so correct me if I'm wrong here. The thing you object to in my

patch is the fact that the properties in the document level drawer

have a higher precedence over property keywords? Since it means that

outline level 0 have higher precedence than file level keywords? I've

already argued why I think that's natural. This order seems fine to

me: (from lowest to highest rank)

1. File level property keyword

2. Node level 0 property drawer property (file level property drawer)

3. Node level 1 property drawer property

4. Node level 2 property drawer property

5. ...and so on...

This feels less unintuitive and will be more difficult to explain to

new users:

1. Node level 0 property drawer property (file level property drawer)

2. File level property keyword

3. Node level 1 property drawer property

4. Node level 2 property drawer property

5. ...and so on...

I can't agree on changing to the second ranking only based on your

concerns. If more people were to back you up I think it's fair to have

that discussion though!

> >> What you're proposing is actually a fundamental change to the way Org

> >> documents are interpreted.  Org documents are not currently an

> >> outline, just a series of elements which may include an outline.

> >> Text and elements before a first heading are not part of a node,

> >> they're just text and elements in the document.

> >

> > I don't agree here. What I'm proposing in this patch doesn't change

> > the fundament of an Org mode document. I'd rather say it enhances the

> > fundament! Since the outline to a large extent is the fundament! The

> > following quote is from the documentation - Chapter 2, Document

> > Structure:

> >

> >   #+begin_quote Org is an outliner.  Outlines allow a document to be

> >   organized in a hierarchical structure, which, least for me, is the

> >   best representation of notes and thoughts.  #+end_quote

>

> Org is a collection of Emacs code built on top of Outline Mode, which

> interprets plain-text files in a certain way.  Since the beginning, such

> files have been interpreted such that content before the first heading

> is not part of an outline node.  Your proposal would change that.  For

> better or worse, it is a major change that has implications which you

> seem to be unconcerned with.

Of course I'm not unconcerned. I just don't know what you’re

trying to do here. Please take a look at your comment again and then

switch over to ORG-NEWS. Version 9.3 (I.e. a MINOR version) have 9

incompatible changes and 23 new features already pushed to master.

Those 32 changes all have implications for how Org mode documents are

interpreted. Your way of arguing in this thread could be done for many

of those changes. But then, why haven't you? Things change. Most

things to the better! This change being a big step to the better

according to me. And the change I'm proposing here isn't even a

breaking one. I get that it may have struck a nerve for you. But

please argue to the point of the issue instead of trying to blow this

thing up into some mayor breaking incompatible thing. Because it

isn't. It's a harmonization of a feature that already exist. To use it

you have to agree that things before the first headline symbolizes a

level-0 node. If you don't sympathize with that, then simply don't use

it. Your external packages won't need any modifications for this, Org

> > Thus, saying Org documents are not currently an outline again feels

> > disingenuous and at this point I struggle to take your comments

> > seriously.

>

> As a fellow Org developer, I empathize with the work you have put into

> your proposal and its code.  However, it would be best if you would

> consider these issues impartially.

arguing that this change is a major breaking one. If you really still

think that then persuade other members of this community who share

your concern to make their voices heard. Only your comment is on the

side of reject due to major breaking change. The others are positive.

But still few comments all together.

> Like it or not, there is a wider "ecosystem" around Org today, and it is

> growing.  Your proposal would have effects rippling downstream for years

> to come, and other people would have to spend time making changes to

> accommodate them.  Thus, the wider implications of your proposal should

> be very carefully considered.

For this proposed addition to Org mode I don't see where any change is

needed in the wider ecosystem. I do however encourage such change. For

some packages it can resolve issues and simplify development. Because

after this patch is applied there is support for programmatic insertion

of properties that applies to whole files, without having to worry

about positional preferences of the user for property keywords. The

preference when there is a conflict for a property between the keyword

and the drawer is already discussed. That is not a breaking change. If

existing documents break, then please let me know where and how, so I

can try to fix it.

> Org is a big, and growing, project with thousands of users.  We have a

> duty to take these considerations into account, so major changes, like

> your proposal, should be taken very seriously.

Of course it is taken seriously. Your responding to the RFC on the

mailing list. And I'm taking comments on the patch just due to that

concern.

/Gustav

[-- Attachment #2: Type: text/html, Size: 21652 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-06  1:05              Adam Porter
@ 2019-10-06  5:10                Matt Price
0 siblings, 0 replies; 35+ messages in thread
From: Matt Price @ 2019-10-06  5:10 UTC (permalink / raw)
To: Adam Porter; +Cc: Org Mode

[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]

> Marco Wahl <marcowahlsoft@gmail.com> writes:
>
> > Just I got the idea that for a good part this discussion is about
> > personal preferences.
>
> Personal preferences are relevant to this issue in that Org is flexible
> and allows users to configure it accordingly.  But that is not the only
> consideration at stake.  Consistency, compatibility, and longevity are
> even more important.
>
> > What I really find irritating is that "Org ... allows #+KEYWORD: lines
> > to appear anywhere in a file" (This sentence is from you) with the
> > meaning that the settings apply to the whole file.  I think this
> > interpretation of #+KEYWORD: lines is unnecessary and confusing.
>
> Regardless, that is the way Org works, and how it has for many years.
> We can't break that.
>

I'd like to just  quickly chime in in support of Adam's caution on this
issue. I can absolutely see advantages to document level properties, I have
written many code fragments that rely on the use of keywords and expect org
filensyntax to be consistent with what actually exists. I use these code
fragments to hold together a somewhat fragile workflow that allows me to
use org in a work environment that is not especially receptive to simple
text documents. I have invested a lot of time in making those systems run
and sometimes even I don't entirely remember what I did to make them
possible.

It would really, really suck to have those systems break. It would take me
a lot of time to track down the causes and change what I needed to. VMs
that currently pull in Emacs andnorg and my code would stop working. Old
versions of my files would no longer render properly. My efforts to make my
courses and other writings effectively reproducible by others would be
significantly set back. Etc. I think these are the kinds of difficulties

>
>

[-- Attachment #2: Type: text/html, Size: 2643 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-04 11:05            Marco Wahl
2019-10-06  5:10                Matt Price
To: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

> Just I got the idea that for a good part this discussion is about
> personal preferences.

Personal preferences are relevant to this issue in that Org is flexible
and allows users to configure it accordingly.  But that is not the only
consideration at stake.  Consistency, compatibility, and longevity are
even more important.

> What I really find irritating is that "Org ... allows #+KEYWORD: lines
> to appear anywhere in a file" (This sentence is from you) with the
> meaning that the settings apply to the whole file.  I think this
> interpretation of #+KEYWORD: lines is unnecessary and confusing.

Regardless, that is the way Org works, and how it has for many years.
We can't break that.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-04 10:38    Marco Wahl
@ 2019-10-06  1:01      Adam Porter
2019-10-07  7:46        Marco Wahl
To: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

> property definition syntax or at least think about a good place within
> a file or a subtree for those definitions.  (There is at least
> Sebastian Miele who wants to keep that syntax as he stated in another

You do realize, don't you, how much software and how many documents such
a change would break?  One of the primary reasons Org users use Org is
that its file format is very long-lived and flexible.  There are even
academic papers written in Org, exported to LaTeX, and a change such as
that would break them, creating needless work for their authors or other
interested parties to fix them up in order to still be exportable.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-05 18:20 Gustav Wikström
@ 2019-10-06  0:51  Adam Porter
0 siblings, 0 replies; 35+ messages in thread
To: emacs-orgmode

Gustav Wikström <gustav@whil.se> writes:

>> In Org, some keywords are special, like #+CATEGORY.  For many years,
>> such keywords have had file-wide effects regardless of their placement
>> in the file.  IIUC, your proposal would change that, and that would
>> still be a major, breaking change.
>
> This seems disingenuous.

To be disingenuous means, e.g.

Not ingenuous; wanting in noble candor or frankness; not frank or
open; uncandid; unworthily or meanly artful.

It's not friendly to imply that of me over a difference of
interpretation of Org syntax and traditions.  I hope you meant something
else.  I wouldn't spend my time studying your proposals and offering
feedback if I didn't want what's best for Org and its users.

> In no way is this a major, breaking change.  No document you have
> today will break by the introduction of this.  The only thing changing
> is if you *actively* create a document level property drawer and
> choose to enter a property there that you already have defined in the
> same document, using a property keyword.

There is a bigger picture which you seem to be ignoring.

Org is distributed with Emacs itself.  Emacs versions are long-lived.
People use old Emacs and Org versions for years, because few people
build and install Emacs themselves, so most users use the versions
included with their OS or other distributions.

Your proposed change would introduce a major change in the way document
properties are interpreted.  This means that the same document, when
used on Emacs/Org versions before and after this change, would be
interpreted differently.  That's breaking forward-compatibility between
versions, ones which will be in the wild for years.  That decision
should not be taken lightly.

> Keywords that previously had file-wide effects will continue to have
> that. That's not removed. So you must have missunderstood something
> here.

I did not misunderstand; I am looking from a different perspective.  In
your proposal, line-based keywords can be overridden by document-level
property drawers, while they currently are applied to the entire file
regardless of any drawers.  That is a major change.

>> > If you think of the document as an outline, something Org mode is
>> > all about, it makes sense to also think of things before the first
>> > headline as "node level 0". And with that way of conceptually
>> > thinking of the document it makes perfect sense to have a property
>> > drawer fixed at the top - in the same way as it is required for all
>> > other node levels.
>>
>> What you're proposing is actually a fundamental change to the way Org
>> documents are interpreted.  Org documents are not currently an
>> outline, just a series of elements which may include an outline.
>> Text and elements before a first heading are not part of a node,
>> they're just text and elements in the document.
>
> I don't agree here. What I'm proposing in this patch doesn't change
> the fundament of an Org mode document. I'd rather say it enhances the
> fundament! Since the outline to a large extent is the fundament! The
> following quote is from the documentation - Chapter 2, Document
> Structure:
>
>   #+begin_quote Org is an outliner.  Outlines allow a document to be
>   organized in a hierarchical structure, which, least for me, is the
>   best representation of notes and thoughts.  #+end_quote

Org is a collection of Emacs code built on top of Outline Mode, which
interprets plain-text files in a certain way.  Since the beginning, such
files have been interpreted such that content before the first heading
is not part of an outline node.  Your proposal would change that.  For
better or worse, it is a major change that has implications which you
seem to be unconcerned with.

> Thus, saying Org documents are not currently an outline again feels
> disingenuous and at this point I struggle to take your comments
> seriously.

As a fellow Org developer, I empathize with the work you have put into
your proposal and its code.  However, it would be best if you would
consider these issues impartially.

Like it or not, there is a wider "ecosystem" around Org today, and it is
growing.  Your proposal would have effects rippling downstream for years
to come, and other people would have to spend time making changes to
accommodate them.  Thus, the wider implications of your proposal should
be very carefully considered.

Org is a big, and growing, project with thousands of users.  We have a
duty to take these considerations into account, so major changes, like
your proposal, should be taken very seriously.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-05 18:20 Gustav Wikström
From: Gustav Wikström @ 2019-10-05 18:20 UTC (permalink / raw)

> IIUC, your proposal would work like this:
>
> #+BEGIN_SRC org
>   :PROPERTIES:
>   :CATEGORY: Gamma
>   :END:
>
>   # Category here is "Gamma"
>
>   ,* Node 1
>
>   # Category here is "Gamma"
>
>   ,* Node 2
>   :PROPERTIES:
>   :CATEGORY: Beta
>   :END:
>
>   # Category here is "Beta"
>
>   ,#+CATEGORY: Alpha
> #+END_SRC

You understand correctly. In that case precedence would kick in since
a category is defined using both a category keyword and a category
inside the document property drawer. The example above is mostly
theoretical since there is no use-case for having category set on
document level using both conventions. If the example above was a real
document I'd suggest removing either the category keyword or the
category property from the document property drawer.

> In Org, some keywords are special, like #+CATEGORY.  For many years,
> such keywords have had file-wide effects regardless of their placement
> in the file.  IIUC, your proposal would change that, and that would
> still be a major, breaking change.

This seems disingenuous. In no way is this a major, breaking change.
No document you have today will break by the introduction of this.
The only thing changing is if you *actively* create a document level
property drawer and choose to enter a property there that you already
have defined in the same document, using a property keyword.

Keywords that previously had file-wide effects will continue to have
that. That's not removed. So you must have missunderstood something
here.

I understand you dislike the preference of letting the property drawer
have a higher precedance than property keywords, if the same property
is defined in both ways. I've already argued why I think that is the
sane choice to make. But having that precedance doesn't break anything
since you cannot define a property drawer on document level today.

> > If you think of the document as an outline, something Org mode is all
> > about, it makes sense to also think of things before the first
> > headline as "node level 0". And with that way of conceptually thinking
> > of the document it makes perfect sense to have a property drawer fixed
> > at the top - in the same way as it is required for all other node
> > levels.
>
> What you're proposing is actually a fundamental change to the way Org
> documents are interpreted.  Org documents are not currently an outline,
> just a series of elements which may include an outline.  Text and
> elements before a first heading are not part of a node, they're just
> text and elements in the document.

I don't agree here. What I'm proposing in this patch doesn't change
the fundament of an Org mode document. I'd rather say it enhances the
fundament! Since the outline to a large extent is the fundament! The
following quote is from the documentation - Chapter 2, Document
Structure:

#+begin_quote
Org is an outliner.  Outlines allow a document to be organized in a
hierarchical structure, which, least for me, is the best representation
of notes and thoughts.
#+end_quote

Thus, saying Org documents are not currently an outline again feels
seriously.

Regards
Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-03 18:06          Adam Porter
@ 2019-10-04 11:05            Marco Wahl
2019-10-06  1:05              Adam Porter
From: Marco Wahl @ 2019-10-04 11:05 UTC (permalink / raw)
To: emacs-orgmode

> Marco Wahl <marcowahlsoft@gmail.com> writes:

>> You say the visibility is better for the #+-property keywords.  I say
>> they can occur _anywhere_ in the file and even in some drawers.  See
>> above "#+CATEGORY:  cat-doc-prop-keyword-2".
>>
>> Further you say
>>
>>>>> - However, it seems to me that the simplest, most natural protocol would
>>>>>   be for later declarations to override earlier ones.
>>
>> This means that cat-doc-prop-keyword-2 from the example defines the
>> CATEGORY property which at least I find not so natural.  And I already
>> stated what I find natural.

> Org may allow #+KEYWORD: lines to appear anywhere in a file, including
> in arbitrary drawers, but that's up to the user.  If the user chooses to
> hide them in drawers, it's his responsibility.
>
> AFAICT that's not a common or generally recommended thing to do.  Most
> Org files have such lines at the top of the file, and some under a
> heading at the bottom of the file with other settings.  Such lines don't
> need to be in drawers, and this proposal wouldn't change that.
>
> So I think it would be confusing if settings in a drawer at the top of
> the file were to absolutely override settings outside of drawers (which
> would mean that hidden settings could override plainly visible ones).
> The most natural protocol would be like written language: later
> declarations override earlier ones.

Just I got the idea that for a good part this discussion is about
personal preferences.  For me for example it's not a big deal if a
property is placed within a drawer or not.  I don't care much about the
"visibility" of a property setting.  Of course I respect other views

What I really find irritating is that "Org ... allows #+KEYWORD: lines
to appear anywhere in a file" (This sentence is from you) with the
meaning that the settings apply to the whole file.  I think this
interpretation of #+KEYWORD: lines is unnecessary and confusing.

BTW I find it completely natural that--let's for simplicity assume an
Org file without any drawers--#+KEYWORD: settings that appear later in
a file replace earlier settings.

Best regards,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-04 10:38    Marco Wahl
From: Marco Wahl @ 2019-10-04 10:38 UTC (permalink / raw)
To: emacs-orgmode

> Gustav Wikström <gustav@whil.se> writes:
>
>> I'd argue that precedence already works that way. One has to take
>> inheritance into account. With inheritance turned on, tell me which
>> value for Property1 is used for the nodes in the following example:
>>
>> #+begin_src org
>>   ,* Node 1
>>   ,* Node 2
>>   :PROPERTIES:
>>   :Property1: Value1
>>   :END:
>>
>>   ,#+PROPERTY: Property1 Value2
>> #+end_src
>>
>> As you'll see line number already isn't the deciding factor.
>>
>> With two ways to define properties it makes sense to first think of
>> which syntax to promote as "more important" and then to think of
>> precedence rules for duplicates within each syntax.
>>
>> Having the same syntax for node level 0 as for regular nodes makes the
>> property functionality easy to understand and congruent. Something I
>> think is worth promoting by saying that property blocks on file-level
>> has precedence over the keyword syntax.
>
> I think this example illustrates the issue better.  This is how Org
> currently works:
>
> #+BEGIN_SRC org
>   # Category here is "Alpha"
>
>   ,* Node 1
>
>   # Category here is "Alpha"
>
>   ,* Node 2
>   :PROPERTIES:
>   :CATEGORY: Beta
>   :END:
>
>   # Category here is "Beta"
>
>   ,#+CATEGORY: Alpha
> #+END_SRC
>
>
> IIUC, your proposal would work like this:
>
> #+BEGIN_SRC org
>   :PROPERTIES:
>   :CATEGORY: Gamma
>   :END:
>
>   # Category here is "Gamma"
>
>   ,* Node 1
>
>   # Category here is "Gamma"
>
>   ,* Node 2
>   :PROPERTIES:
>   :CATEGORY: Beta
>   :END:
>
>   # Category here is "Beta"
>
>   ,#+CATEGORY: Alpha
> #+END_SRC
>
> So the #+CATEGORY: line has no effect because of the first-line property
> drawer.
>
> In Org, some keywords are special, like #+CATEGORY.  For many years,
> such keywords have had file-wide effects regardless of their placement
> in the file.  IIUC, your proposal would change that, and that would
> still be a major, breaking change.

IIUC Org files not using a file level property drawer would not be
affected from the change at all.  With the proposition the user gets a
further option to define a file wide property.

>> If you think of the document as an outline, something Org mode is all
>> about, it makes sense to also think of things before the first
>> headline as "node level 0". And with that way of conceptually thinking
>> of the document it makes perfect sense to have a property drawer fixed
>> at the top - in the same way as it is required for all other node
>> levels.
>
> What you're proposing is actually a fundamental change to the way Org
> documents are interpreted.  Org documents are not currently an outline,
> just a series of elements which may include an outline.  Text and
> elements before a first heading are not part of a node, they're just
> text and elements in the document.
>
> If Org were a new project, I think your proposal might be very
> suitable.  But at this point, it would be a significant, breaking
> change, even without the org-element parser changes.
>
> Consider as well that the Org format has recently been seeing wider use,
> with more implementations becoming available in several languages and on
> several platforms.  Fundamental changes like this would affect more than
> just the official Org software, and the costs of breaking software in
> the wider Org community should be carefully considered.

The proposal is an extension leaving all operations and tools intact for
Org files not using the file wide property drawer AFAICS.  If a tool
depends on a file wide property then it needs to be adapted.  Possibly
this could be called "breaking" but I think this should not hold back
the proposal.

definition syntax or at least think about a good place within a file or
a subtree for those definitions.  (There is at least Sebastian Miele who
wants to keep that syntax as he stated in another thread AFAIR.)

Personally I think it's a good idea to work for an Org mode where an Org
file behaves very much like an Org subtree.

Ciao,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-30 22:09 Gustav Wikström
@ 2019-10-03 18:31  Adam Porter
2019-10-04 10:38    Marco Wahl
To: emacs-orgmode

Hi Gustav,

Gustav Wikström <gustav@whil.se> writes:

> I'd argue that precedence already works that way. One has to take
> inheritance into account. With inheritance turned on, tell me which
> value for Property1 is used for the nodes in the following example:
>
> #+begin_src org
>   ,* Node 1
>   ,* Node 2
>   :PROPERTIES:
>   :Property1: Value1
>   :END:
>
>   ,#+PROPERTY: Property1 Value2
> #+end_src
>
> As you'll see line number already isn't the deciding factor.
>
> With two ways to define properties it makes sense to first think of
> which syntax to promote as "more important" and then to think of
> precedence rules for duplicates within each syntax.
>
> Having the same syntax for node level 0 as for regular nodes makes the
> property functionality easy to understand and congruent. Something I
> think is worth promoting by saying that property blocks on file-level
> has precedence over the keyword syntax.

I think this example illustrates the issue better.  This is how Org
currently works:

#+BEGIN_SRC org
# Category here is "Alpha"

,* Node 1

# Category here is "Alpha"

,* Node 2
:PROPERTIES:
:CATEGORY: Beta
:END:

# Category here is "Beta"

,#+CATEGORY: Alpha
#+END_SRC

IIUC, your proposal would work like this:

#+BEGIN_SRC org
:PROPERTIES:
:CATEGORY: Gamma
:END:

# Category here is "Gamma"

,* Node 1

# Category here is "Gamma"

,* Node 2
:PROPERTIES:
:CATEGORY: Beta
:END:

# Category here is "Beta"

,#+CATEGORY: Alpha
#+END_SRC

So the #+CATEGORY: line has no effect because of the first-line property
drawer.

In Org, some keywords are special, like #+CATEGORY.  For many years,
such keywords have had file-wide effects regardless of their placement
in the file.  IIUC, your proposal would change that, and that would
still be a major, breaking change.

> If you think of the document as an outline, something Org mode is all
> about, it makes sense to also think of things before the first
> headline as "node level 0". And with that way of conceptually thinking
> of the document it makes perfect sense to have a property drawer fixed
> at the top - in the same way as it is required for all other node
> levels.

What you're proposing is actually a fundamental change to the way Org
documents are interpreted.  Org documents are not currently an outline,
just a series of elements which may include an outline.  Text and
elements before a first heading are not part of a node, they're just
text and elements in the document.

If Org were a new project, I think your proposal might be very
suitable.  But at this point, it would be a significant, breaking
change, even without the org-element parser changes.

Consider as well that the Org format has recently been seeing wider use,
with more implementations becoming available in several languages and on
several platforms.  Fundamental changes like this would affect more than
just the official Org software, and the costs of breaking software in
the wider Org community should be carefully considered.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-10-02 10:29        Marco Wahl
2019-10-04 11:05            Marco Wahl
To: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

> You say the visibility is better for the #+-property keywords.  I say
> they can occur _anywhere_ in the file and even in some drawers.  See
> above "#+CATEGORY:  cat-doc-prop-keyword-2".
>
> Further you say
>
>>>> - However, it seems to me that the simplest, most natural protocol would
>>>>   be for later declarations to override earlier ones.
>
> This means that cat-doc-prop-keyword-2 from the example defines the
> CATEGORY property which at least I find not so natural.  And I already
> stated what I find natural.

Hi Marco,

Org may allow #+KEYWORD: lines to appear anywhere in a file, including
in arbitrary drawers, but that's up to the user.  If the user chooses to
hide them in drawers, it's his responsibility.

AFAICT that's not a common or generally recommended thing to do.  Most
Org files have such lines at the top of the file, and some under a
heading at the bottom of the file with other settings.  Such lines don't
need to be in drawers, and this proposal wouldn't change that.

So I think it would be confusing if settings in a drawer at the top of
the file were to absolutely override settings outside of drawers (which
would mean that hidden settings could override plainly visible ones).
The most natural protocol would be like written language: later
declarations override earlier ones.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-02 20:29 Gustav Wikström
0 siblings, 0 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-10-02 20:29 UTC (permalink / raw)
To: sebastian.miele; +Cc: emacs-orgmode

Hi Sebastian,

> From:	Sebastian Miele
> Subject:	Re: [O] [RFC] Document level property drawer
> Date:	Tue, 01 Oct 2019 12:38:12 +0000

> ...

> I would like to be able to make a clear distinction between properties
> that are visible by default and properties that are not. Maybe it would
> be possible to allow some #+.. syntax following headings for subtree
> properties that are visible by default. A requirement could be made that
> such property specifications always have to be followed by a property
> drawer, even if that is empty. Then everything #+.. that is before the
> property drawer would belong to the heading/subtree, and everything #+..
> that follows the drawer would be treated as it is until now.

That maps quite well to what I also had in mind initially. What I
called "Document property keywords" in [fn:1]:

#+begin_quote
I propose to allow properties to be defined also as document
property keywords. All keywords in the top of a buffer, before any
non-comment line, are document-level keywords. In effect, they are
properties that apply in exactly the same way as properties defined
in the property drawer. The only reason for using a document keyword
instead of defining it inside the property drawer is to make it more
visible. One example would be the title-keyword (#+TITLE: ...).
#+end_quote

Although I didn't think of generalizing it to also work for the
outline nodes. Something that makes sense to do though, given the use
case you describe!

[fn:1] https://lists.gnu.org/archive/html/emacs-orgmode/2019-06/msg00000.html

FWIW
Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-10-02 10:29        Marco Wahl
From: Marco Wahl @ 2019-10-02 10:29 UTC (permalink / raw)
To: emacs-orgmode

> Marco Wahl <marcowahlsoft@gmail.com> writes:
>
>>
>>> Gustav Wikström <gustav@whil.se> writes:
>>>
>>>> 3) Properties defined in a property drawer will have precedence over
>>>>    properties defined as a property keyword, if the same property is
>>>>    defined using both conventions.
>>>
>>> That protocol seems unnatural and confusing to me:
>>>
>>> - If precedence were to be defined by something other than file-order,
>>>   it seems to me that those defined with #+ keywords should have
>>>   precedence, because they are more visible, while those in drawers are
>>>   hidden.
>>> - However, it seems to me that the simplest, most natural protocol would
>>>   be for later declarations to override earlier ones.
>>
>> I think it would be quite natural to use the tree structure of Org.  A
>> property setting in a subtree overrides the setting in a parent (which
>> could be the document(= the whole file.))
>
> Hi Marco,
>
> I think you misunderstood his point #3 and my objection to it.  :)

that's possible but I don't think so.  But I'm willing to learn if
I didn't get it. :)

Possibly a concrete example can help.  Let's take Org property CATEGORY
for illustration.

First to Gustav's statement 3):

Let the file be this:

--8<---------------cut here---------------start------------->8---
#+title: file
:PROPERTIES:
:CATEGORY: cat-doc-prop-drawer
:END:

* foo
SCHEDULED: <2019-10-02 Wed>

#+CATEGORY:  cat-doc-prop-keyword-1

** bar

:somedrawer:
#+CATEGORY:  cat-doc-prop-keyword-2
:END:
--8<---------------cut here---------------end--------------->8---

With Gustav's proposition the CATEGORY of task foo is
cat-doc-prop-drawer.

You say the visibility is better for the #+-property keywords.  I say
they can occur _anywhere_ in the file and even in some drawers.  See
above "#+CATEGORY:  cat-doc-prop-keyword-2".

Further you say

>>> - However, it seems to me that the simplest, most natural protocol would
>>>   be for later declarations to override earlier ones.

This means that cat-doc-prop-keyword-2 from the example defines the
CATEGORY property which at least I find not so natural.  And I already
stated what I find natural.

Best regards,  Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-30 20:46    Marco Wahl
2019-10-01 12:38      Sebastian Miele
@ 2019-10-01 13:55      Adam Porter
2019-10-02 10:29        Marco Wahl
To: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

>
>> Gustav Wikström <gustav@whil.se> writes:
>>
>>> 3) Properties defined in a property drawer will have precedence over
>>>    properties defined as a property keyword, if the same property is
>>>    defined using both conventions.
>>
>> That protocol seems unnatural and confusing to me:
>>
>> - If precedence were to be defined by something other than file-order,
>>   it seems to me that those defined with #+ keywords should have
>>   precedence, because they are more visible, while those in drawers are
>>   hidden.
>> - However, it seems to me that the simplest, most natural protocol would
>>   be for later declarations to override earlier ones.
>
> I think it would be quite natural to use the tree structure of Org.  A
> property setting in a subtree overrides the setting in a parent (which
> could be the document(= the whole file.))

Hi Marco,

I think you misunderstood his point #3 and my objection to it.  :)

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-30 20:46    Marco Wahl
@ 2019-10-01 12:38      Sebastian Miele
2020-01-13 21:52        Marco Wahl
From: Sebastian Miele @ 2019-10-01 12:38 UTC (permalink / raw)
To: emacs-orgmode

Marco Wahl <marcowahlsoft@gmail.com> writes:

> [..]
>
> I think the distinction between Org file and Org subtree should be kept
> to a minimum.  Wouldn't it be nice if Org files can be considered as Org
> subtrees?

Yes, this would be very nice.

I have a related question or proposal.

Up until now, I basically do not use property drawers except absolutely
necessary, because properties are invisible by default. Properties "need
to be inserted into a [..] drawer", and "in order to look inside the
drawer, you need to move point to the drawer line and press ‘<TAB>’
there."

A place that comes to mind where I really would like to use properties
is the header-args property in order to specify parameters related to
tangling for all src blocks in certain subtrees.

But for such properties to satisfactorily work for me, they would have
to be visible by default. E.g. I would want the header-args to be
immediately visible just like they are when they are written after
#+BEGIN_SRC or #+HEADER. Otherwise I would find myself constantly
wondering whether this or that property drawer contains something
essential and every TAB on a collapsed headline would have be followed
by an accompanying move to the property drawer and a TAB there.

On the other hand, there are properties that are very good candidates
for remaining hidden by default, like ID.

I would like to be able to make a clear distinction between properties
that are visible by default and properties that are not. Maybe it would
be possible to allow some #+.. syntax following headings for subtree
properties that are visible by default. A requirement could be made that
such property specifications always have to be followed by a property
drawer, even if that is empty. Then everything #+.. that is before the
property drawer would belong to the heading/subtree, and everything #+..
that follows the drawer would be treated as it is until now.

Please tell me if I missed something and Org is already capable of
something like that. If not, are there others who would like
visible-by-default property specifications for headings/subtrees in
addition to invisible-by-default property specifications in drawers,
too?

Finally, I would like to state an opinion: If there is
visible-by-default (by #+..) and invisible-by-default (by drawers)
syntax for headings/subtrees, including level 0, it may be viable to
require them to be disjoint for each heading/subtree. Most probably it
would be good practice, anyway. And the precedence question raised
previously in this thread would be eliminated.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-09-30 22:09 Gustav Wikström
2019-10-03 18:31  Adam Porter
From: Gustav Wikström @ 2019-09-30 22:09 UTC (permalink / raw)

> How does it differ from what was previously proposed?

It differs by not introducing the document concept in Org element.
Removing that means there is no reason to wait for another major
version of Org mode.

> What exactly does "will (shall)" mean?

You can ignore the inside of the parentheses. It carries no important
meaning.

> > 3) Properties defined in a property drawer will have precedence over
> >    properties defined as a property keyword, if the same property is
> >    defined using both conventions.
>
> That protocol seems unnatural and confusing to me:
>
> - If precedence were to be defined by something other than file-order,
>   it seems to me that those defined with #+ keywords should have
>   precedence, because they are more visible, while those in drawers are
>   hidden.
> - However, it seems to me that the simplest, most natural protocol would
>   be for later declarations to override earlier ones.

I'd argue that precedence already works that way. One has to take
inheritance into account. With inheritance turned on, tell me which
value for Property1 is used for the nodes in the following example:

#+begin_src org
,* Node 1
,* Node 2
:PROPERTIES:
:Property1: Value1
:END:

,#+PROPERTY: Property1 Value2
#+end_src

As you'll see line number already isn't the deciding factor.

With two ways to define properties it makes sense to first think of
which syntax to promote as "more important" and then to think of
precedence rules for duplicates within each syntax.

Having the same syntax for node level 0 as for regular nodes makes the
property functionality easy to understand and congruent. Something I
think is worth promoting by saying that property blocks on file-level
has precedence over the keyword syntax.

> > 4) The position for the document level property drawer is:
> >    - At the first line in a file that is not a comment or a keyword.
> >
> >      I.e. the following will work:
> >
> >      #+begin_src org
> >        # -*- mode: org -*-
> >        ,#+TITLE: Test
> >        :PROPERTIES:
> >        :CATEGORY: Test
> >        :END:
> >
> >        Preamble
> >
> >        Some content
> >      #+end_src
> >
> >
> >      but not this:
> >
> >      #+begin_src org
> >        Some comment and/or empty line
> >
> >        :PROPERTIES:
> >        :CATEGORY: Test
> >        :END:
> >
> >        Some content
> >      #+end_src
>
> That feels unintuitive to me.  Document-level property keywords may
> appear anywhere in a file, so it seems inconsistent for document-level
> property drawers to be limited in this way, as if there were an implied
> headline at the top of the file.  If it were so, I would expect to see
> many mailing list posts by users asking why the properties defined in
> their document-level property drawers aren't working.  Given that there
> is no enforcement in Org's UI to keep such drawers in certain places, I
> think the implementation should be tolerant of users' preferences and
> mistakes (cf. Postel's Law).

If you think of the document as an outline, something Org mode is all
about, it makes sense to also think of things before the first
headline as "node level 0". And with that way of conceptually thinking
of the document it makes perfect sense to have a property drawer fixed
at the top - in the same way as it is required for all other node
levels.

Regarding the placement of drawers, if you apply my patch on your end
to test it out you'll see that the built in functionality to define
properties creates the drawer for you. That's easy to do since it's
positional rule is easy to derive by the system. Try for example
org-set-property (C-c C-x p) and you'll get the drawer defined for
you. In exactly the same way as it already works when you're inside a

The lack of posts asking why properties defined on their outline nodes
doesn't work tells me that positional requirements for property

Kind regards
Gustav

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
@ 2019-09-30 20:46    Marco Wahl
2019-10-01 12:38      Sebastian Miele
2019-10-01 13:55      Adam Porter
0 siblings, 2 replies; 35+ messages in thread
From: Marco Wahl @ 2019-09-30 20:46 UTC (permalink / raw)
To: emacs-orgmode

> Gustav Wikström <gustav@whil.se> writes:
>
>> 3) Properties defined in a property drawer will have precedence over
>>    properties defined as a property keyword, if the same property is
>>    defined using both conventions.
>
> That protocol seems unnatural and confusing to me:
>
> - If precedence were to be defined by something other than file-order,
>   it seems to me that those defined with #+ keywords should have
>   precedence, because they are more visible, while those in drawers are
>   hidden.
> - However, it seems to me that the simplest, most natural protocol would
>   be for later declarations to override earlier ones.

I think it would be quite natural to use the tree structure of Org.  A
property setting in a subtree overrides the setting in a parent (which
could be the document(= the whole file.))

>> 4) The position for the document level property drawer is:
>>    - At the first line in a file that is not a comment or a keyword.
>>
>>      I.e. the following will work:
>>
>>      #+begin_src org
>>        # -*- mode: org -*-
>>        ,#+TITLE: Test
>>        :PROPERTIES:
>>        :CATEGORY: Test
>>        :END:
>>
>>        Preamble
>>
>>        Some content
>>      #+end_src

[...]

> That feels unintuitive to me.  Document-level property keywords may
> appear anywhere in a file, so it seems inconsistent for document-level
> property drawers to be limited in this way, as if there were an implied
> headline at the top of the file.  If it were so, I would expect to see
> many mailing list posts by users asking why the properties defined in
> their document-level property drawers aren't working.  Given that there
> is no enforcement in Org's UI to keep such drawers in certain places, I
> think the implementation should be tolerant of users' preferences and
> mistakes (cf. Postel's Law).

TBH allowing document-level properties anywhere in an Org file looks
rather messy to me.  When a user is interested in all the document-level
properties she needs to scan the whole file.  Also the spread out
document-level properties introduce a distinction between a whole Org
file and an Org subtree.

I think the distinction between Org file and Org subtree should be kept
to a minimum.  Wouldn't it be nice if Org files can be considered as Org
subtrees?  In this sense a property drawer for the document is a step in
the right direction.

Ciao,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-29 10:27 Gustav Wikström
2019-09-29 19:13  Marco Wahl
@ 2019-09-30 16:01  Adam Porter
2019-09-30 20:46    Marco Wahl
2019-10-15 17:49  Gustav Wikström
To: emacs-orgmode

Gustav Wikström <gustav@whil.se> writes:

> Hi,
>
> This patch introduces a document level property drawer.
>
> This has been discussed previously in a larger context:
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-06/msg00000.html
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-08/msg00339.html
> - https://lists.gnu.org/archive/html/emacs-orgmode/2019-09/msg00010.html
>
> The patch is a somewhat modified version of what was included in the third

How does it differ from what was previously proposed?

> The following will be true for document level property drawers:
> 1) In the same way that one can have a property drawer for a heading, one
>    can have a property drawer for a whole document.
> 2) All existing commands that can work with property drawers will
>    (shall) work also on property drawers before the first heading.

What exactly does "will (shall)" mean?

> 3) Properties defined in a property drawer will have precedence over
>    properties defined as a property keyword, if the same property is
>    defined using both conventions.

That protocol seems unnatural and confusing to me:

- If precedence were to be defined by something other than file-order,
it seems to me that those defined with #+ keywords should have
precedence, because they are more visible, while those in drawers are
hidden.
- However, it seems to me that the simplest, most natural protocol would
be for later declarations to override earlier ones.

> 4) The position for the document level property drawer is:
>    - At the first line in a file that is not a comment or a keyword.
>
>      I.e. the following will work:
>
>      #+begin_src org
>        # -*- mode: org -*-
>        ,#+TITLE: Test
>        :PROPERTIES:
>        :CATEGORY: Test
>        :END:
>
>        Preamble
>
>        Some content
>      #+end_src
>
>
>      but not this:
>
>      #+begin_src org
>        Some comment and/or empty line
>
>        :PROPERTIES:
>        :CATEGORY: Test
>        :END:
>
>        Some content
>      #+end_src

That feels unintuitive to me.  Document-level property keywords may
appear anywhere in a file, so it seems inconsistent for document-level
property drawers to be limited in this way, as if there were an implied
headline at the top of the file.  If it were so, I would expect to see
many mailing list posts by users asking why the properties defined in
their document-level property drawers aren't working.  Given that there
is no enforcement in Org's UI to keep such drawers in certain places, I
think the implementation should be tolerant of users' preferences and
mistakes (cf. Postel's Law).

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [RFC] Document level property drawer
2019-09-29 10:27 Gustav Wikström
@ 2019-09-29 19:13  Marco Wahl
2019-09-30 16:01  Adam Porter
2019-10-15 17:49  Gustav Wikström
2 siblings, 0 replies; 35+ messages in thread
From: Marco Wahl @ 2019-09-29 19:13 UTC (permalink / raw)
To: emacs-orgmode

Hi,

> This patch introduces a document level property drawer.

[...]

> What do you say?

I'll install the patch and have a look how it feels in my little
personal Org universe.

Thanks,
--
Marco

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [RFC] Document level property drawer
@ 2019-09-29 10:27 Gustav Wikström
2019-09-29 19:13  Marco Wahl
(2 more replies)
0 siblings, 3 replies; 35+ messages in thread
From: Gustav Wikström @ 2019-09-29 10:27 UTC (permalink / raw)
To: emacs-orgmode; +Cc: Nicolas Goaziou

[-- Attachment #1: Type: text/plain, Size: 1584 bytes --]

Hi,

This patch introduces a document level property drawer.

This has been discussed previously in a larger context:
- https://lists.gnu.org/archive/html/emacs-orgmode/2019-06/msg00000.html
- https://lists.gnu.org/archive/html/emacs-orgmode/2019-08/msg00339.html
- https://lists.gnu.org/archive/html/emacs-orgmode/2019-09/msg00010.html

The patch is a somewhat modified version of what was included in the third

The following will be true for document level property drawers:
1) In the same way that one can have a property drawer for a heading, one
can have a property drawer for a whole document.
2) All existing commands that can work with property drawers will
(shall) work also on property drawers before the first heading.
3) Properties defined in a property drawer will have precedence over
properties defined as a property keyword, if the same property is
defined using both conventions.
4) The position for the document level property drawer is:
- At the first line in a file that is not a comment or a keyword.

I.e. the following will work:
#+begin_src org
# -*- mode: org -*-
,#+TITLE: Test
:PROPERTIES:
:CATEGORY: Test
:END:

Preamble

Some content
#+end_src

but not this:
#+begin_src org
Some comment and/or empty line

:PROPERTIES:
:CATEGORY: Test
:END:

Some content
#+end_src

What do you say?

Regards
Gustav Wikström

[-- Attachment #2: 0001-Org-document-property-drawers.patch --]
[-- Type: application/octet-stream, Size: 45416 bytes --]

From 91dad61268b0c2a6efe9c9fa5cee868434d33b76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gustav=20Wikstr=C3=B6m?= <gustav@whil.se>
Date: Sun, 26 May 2019 22:13:09 +0200
Subject: [PATCH] Org document property-drawers

Add functionality to define property-blocks on document level, in

* doc/org-manual.org:
* etc/ORG-NEWS: Document new functionality.

* lisp/org.el (org-keyword-regexp): Define constant instead of
hardcoding.
(org-file-properties): Renamed, see next line.
(org-keyword-properties): Renamed from above.  Due to the fact that
properties can be defined for the whole document using property
drawers this local variable needs a rename to make its name less
ambigous.
(org-refresh-properties, org-refresh-property, org-entry-properties)
(org-refresh-category-properties, org-get-property-block)
(org-entry-get-with-inheritance, org-entry-put)
(org-insert-property-drawer, org-end-of-subtree): Made to work before
(org-at-property-block-p): New function to validate if point is at the
start of a property block.
(org-property-global-value): Renamed, see next line.
(org-property-global-or-keyword-value): Renamed from above to match
its functionality better.
(org-back-to-heading-or-point-min): New function to make a document
work as a level 0 node in the outline.
(org-at-keyword-p): Predicate function to answer to if we're currently
at a keyword line or not.
(org-up-heading-or-point-min): New function to make a document work as
a level 0 node in the outline.

* lisp/org-element.el (org-element--current-element): Can now detect
property-blocks before first headline according to it's positional
rules.

* lisp/org-attach.el (org-attach): Make it possible to call the
attachment dispatcher also before the first headline, since document
property drawers make attachments possible for the whole document
now.

* lisp/org-capture.el: Modified only due to rename of function in
org.el.

* lisp/org-compat.el (org-file-properties)
(org-property-global-value): Renamed functions declared obsolete.

* testing/lisp/test-org.el (org/insert-property-drawer)
(org/set-property, org/delete-property, org/delete-property-globally):
(org/at-property-p, org/at-property-block-p, org/get-property-block)
(org/entry-get, org/refresh-properties): New tests

* testing/examples/property-inheritance.org: Switch from
property-keywords to a property-drawer in the testfile.
Functionality should be the same, but now using a document drawer

Reason for switching is that I'd like us to slowly depricate
property-keywords.

* testing/lisp/test-org-element.el:

* contrib/lisp/ox-taskjuggler.el: A comment is modified only due to
rename of function in org.el.
---
doc/org-manual.org                        |  27 +-
etc/ORG-NEWS                              |  10 +-
lisp/org-attach.el                        |   2 +-
lisp/org-capture.el                       |   4 +-
lisp/org-compat.el                        |   6 +
lisp/org-element.el                       |   5 +-
lisp/org.el                               | 268 ++++++++++++-------
testing/examples/property-inheritance.org |   6 +-
testing/lisp/test-org-element.el          |  21 ++
testing/lisp/test-org.el                  | 305 +++++++++++++++++++++-
11 files changed, 539 insertions(+), 117 deletions(-)

index 16a6a3a74..bc90b93a4 100644
@@ -137,7 +137,7 @@
;;   :END:
;;
;;;; * TODO
-;;   - Look at org-file-properties, org-global-properties and
+;;   - Look at org-keyword-properties, org-global-properties and
;;     org-global-properties-fixed
;;   - What about property inheritance and org-property-inherit-p?
;;   - Use TYPE_TODO as an way to assign resources
diff --git a/doc/org-manual.org b/doc/org-manual.org
index f2f059e77..8358620ca 100644
--- a/doc/org-manual.org
+++ b/doc/org-manual.org
@@ -4951,7 +4951,7 @@ with many examples, see [[*Matching tags and properties]].

A property is a key-value pair associated with an entry.  Properties
can be set so they are associated with a single entry, with every
-entry in a tree, or with every entry in an Org file.
+entry in a tree, or with the whole buffer.

There are two main applications for properties in Org mode.  First,
properties are like tags, but with a value.  Imagine maintaining
@@ -5015,8 +5015,13 @@ disks in a box like this:
:END:
#+end_example

-If you want to set properties that can be inherited by any entry in
-a file, use a line like:
+Properties can be inserted on buffer level.  That means they apply
+before the first headline and can be inherited by all entries in a
+file.  Property blocks defined before first headline needs to be
+located at the top of the buffer, allowing only comments and keywords
+above.
+
+Properties can also be defined using lines like:

#+cindex: @samp{_ALL} suffix, in properties
#+cindex: @samp{PROPERTY}, keyword
@@ -5081,7 +5086,9 @@ The following commands help to work with properties:
#+findex: org-insert-drawer
Insert a property drawer into the current entry.  The drawer is
inserted early in the entry, but after the lines with planning
+  inserted at the top of the drawer after any potential comments or
+  keywords.

- {{{kbd(C-c C-c)}}} (~org-property-action~) ::

@@ -5304,11 +5311,6 @@ done by defining a column format line.
:DESCRIPTION: Where defined, where valid?
:END:

-To define a column format for an entire file, use a line like:
-
-#+cindex: @samp{COLUMNS}, keyword
-: #+COLUMNS: %25ITEM %TAGS %PRIORITY %TODO
-
To specify a format that only applies to a specific tree, add
a =COLUMNS= property to the top node of that tree, for example:

@@ -5319,6 +5321,13 @@ a =COLUMNS= property to the top node of that tree, for example:
:END:
#+end_example

+A =COLUMNS= property within a property drawer before first headline
+will apply to the entire file.  As an addition to property drawers,
+keywords can also be defined for an entire file using a line like:
+
+#+cindex: @samp{COLUMNS}, keyword
+: #+COLUMNS: %25ITEM %TAGS %PRIORITY %TODO
+
If a =COLUMNS= property is present in an entry, it defines columns for
the entry itself, and for the entire subtree below it.  Since the
column definition is part of the hierarchical structure of the
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -130,6 +130,14 @@ Export ignore done tasks with a deadline when
Likewise, scheduled done tasks are also ignored when
~org-icalendar-use-scheduled~ contains the same symbol.

+*** Property drawers before first headline, outline  level 0
+Property drawers will now work before first headline and Org mode is
+moving more towards making things before the first headline behave
+just as if it was at outline level 0.  Inheritance for properties will
+work also for this level.  In other words; defining things in a
+property drawer before the first headline will make them "inheritable"
+
*** Add split-window-right option for src block edit window placement
Given the increasing popularity of wide screen monitors, splitting
horizontally may make more sense than splitting vertically.  An
@@ -2165,7 +2173,7 @@ without changing the headline.

*** Hierarchies of tags

-The functionality of nesting tags in hierarchies is added to org-mode.
+The functionality of nesting tags in hierarchies is added to Org mode.
This is the generalization of what was previously called "Tag groups"
in the manual.  That term is now changed to "Tag hierarchy".

diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 2138a2807..b2f948c2e 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -244,7 +244,7 @@ Shows a list of commands and prompts for another key to execute a command."
(when marker
(set-buffer (marker-buffer marker))
(goto-char marker))
(save-excursion
(save-window-excursion
(unless org-attach-expert
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 4f97e17ea..67343e02a 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1736,11 +1736,11 @@ The template may still contain \"%?\" for cursor positioning."
(_ (error "Invalid org-capture--clipboards' value: %S"
org-capture--clipboards)))))
("p"
-		     ;; We remove file properties inherited from
+		     ;; We remove keyword properties inherited from
;; target buffer so org-read-property-value' has
;; a chance to find allowed values in sub-trees
;; from the target buffer.
-		     (setq-local org-file-properties nil)
+		     (setq-local org-keyword-properties nil)
(let* ((origin (set-marker (make-marker)
(org-capture-get :pos)
(org-capture-get :buffer)))
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 4446a169d..c167ba908 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -556,6 +556,12 @@ use of this function is for the stuck project list."

+(define-obsolete-function-alias 'org-file-properties
+  'org-keyword-properties "Org 9.3")
+
+(define-obsolete-function-alias 'org-property-global-value
+  'org-property-global-or-keyword-value "Org 9.3")
+

diff --git a/lisp/org-element.el b/lisp/org-element.el
index 56b3cc413..110ff5624 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -3910,7 +3910,10 @@ element it has to parse."
;; LaTeX Environment.
((looking-at org-element--latex-begin-environment)
(org-element-latex-environment-parser limit affiliated))
-	     ;; Drawer and Property Drawer.
+	     ;; Property drawer (before first headline, else it's catched above).
+	     ((org-at-property-block-p)
+	      (org-element-property-drawer-parser limit))
+	     ;; Drawer.
((looking-at org-drawer-regexp)
(org-element-drawer-parser limit affiliated))
;; Fixed Width
diff --git a/lisp/org.el b/lisp/org.el
index cb83bef3b..cbc476644 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -350,6 +350,9 @@ FULL is given."

\f
;;; Syntax Constants
+;;;; Keyword
+(defconst org-keyword-regexp "^[ \t]*#\\+\$$\\S-+?\$$:[ \t]*\$$.*\$$\$"
+  "Regular expression for keyword-lines")

;;;; Block

@@ -3182,8 +3185,13 @@ This list will be combined with the constant org-global-properties-fixed'.
The entries in this list are cons cells where the car is a property
name and cdr is a string with the value.

-You can set buffer-local values for the same purpose in the variable
-org-file-properties' this by adding lines like
+Buffer local properties are added either by a document property drawer
+
+:PROPERTIES:
+:NAME: VALUE
+:END:
+

#+PROPERTY: NAME VALUE"
:group 'org-properties
@@ -3191,10 +3199,14 @@ You can set buffer-local values for the same purpose in the variable
(cons (string :tag "Property")
(string :tag "Value"))))

-(defvar-local org-file-properties nil
+(defvar-local org-keyword-properties nil
"List of property/value pairs that can be inherited by any entry.
-Valid for the current buffer.
-This variable is populated from #+PROPERTY lines.")
+Valid for the current buffer.  This variable is populated from
+#+PROPERTY lines.
+
+Note that properties are defined also in property drawers.
+Properties defined there will take precedence over properties
+defined as keywords.")

(defgroup org-agenda nil
"Options concerning agenda views in Org mode."
@@ -3203,11 +3215,18 @@ This variable is populated from #+PROPERTY lines.")

(defvar-local org-category nil
"Variable used by Org files to set a category for agenda display.
-Such files should use a file variable to set it, for example
+There are multiple ways to set the category.  One way is to set
+it in the document property drawer.  For example:
+
+:PROPERTIES:
+:CATEGORY: ELisp
+:END:
+
+Other ways to define it is as an emacs file variable, for example

#   -*- mode: org; org-category: \"ELisp\"

-or contain a special line
+or for the file to contain a special line:

#+CATEGORY: ELisp

@@ -4340,8 +4359,8 @@ related expressions."
(setq org-tag-groups-alist
(org-tag-alist-to-groups org-current-tag-alist))
(unless tags-only
-	;; File properties.
-	(setq-local org-file-properties (cdr (assq 'property alist)))
+	;; Properties.
+	(setq-local org-keyword-properties (cdr (assq 'property alist)))
;; Archive location.
(let ((archive (cdr (assq 'archive alist))))
(when archive (setq-local org-archive-location archive)))
@@ -4349,9 +4368,9 @@ related expressions."
(let ((cat (org-string-nw-p (cdr (assq 'category alist)))))
(when cat
(setq-local org-category (intern cat))
-	    (setq-local org-file-properties
+	    (setq-local org-keyword-properties
(org--update-property-plist
-			 "CATEGORY" cat org-file-properties))))
+			 "CATEGORY" cat org-keyword-properties))))
;; Columns.
(let ((column (cdr (assq 'columns alist))))
(when column (setq-local org-columns-default-format column)))
@@ -8269,13 +8288,14 @@ the value of the drawer property."
(inherit? (org-property-inherit-p dprop))
(property-re (org-re-property (concat (regexp-quote dprop) "\\+?") t))
-	 (global (and inherit? (org--property-global-value dprop nil))))
+	 (global-or-keyword (and inherit?
+				 (org--property-global-or-keyword-value dprop nil))))
(with-silent-modifications
(org-with-point-at 1
-	;; Set global values (e.g., values defined through
-	;; "#+PROPERTY:" keywords) to the whole buffer.
-	(when global (put-text-property (point-min) (point-max) tprop global))
-	;; Set local values.
+	;; Set global and keyword based values to the whole buffer.
+	(when global-or-keyword
+	  (put-text-property (point-min) (point-max) tprop global-or-keyword))
+	;; Set values based on property-drawers throughout the document.
(while (re-search-forward property-re nil t)
(when (org-at-property-p)
(org-refresh-property tprop (org-entry-get (point) dprop) inherit?))
@@ -8283,21 +8303,29 @@ the value of the drawer property."

(defun org-refresh-property (tprop p &optional inherit)
"Refresh the buffer text property TPROP from the drawer property P.
-The refresh happens only for the current headline, or the whole
-sub-tree if optional argument INHERIT is non-nil."
-    (save-excursion
-      (let ((start (point))
-	    (end (save-excursion
-		   (if inherit (org-end-of-subtree t t)
-	(if (symbolp tprop)
-	    ;; TPROP is a text property symbol.
-	    (put-text-property start end tprop p)
-	  ;; TPROP is an alist with (property . function) elements.
-	  (pcase-dolist ((,prop . ,f) tprop)
-	    (put-text-property start end prop (funcall f p))))))))
+The refresh happens only for the current entry, or the whole
+sub-tree if optional argument INHERIT is non-nil.
+
+If point is before first headline, the function applies to the
+part before the first headline.  In that particular case, when
+optional argument INHERIT is non-nil, it refreshes properties for
+the whole buffer."
+  (save-excursion
+    (let ((start (point))
+	  (end (save-excursion
+			(point-max))
+		       (inherit
+			(org-end-of-subtree t t))
+		       ((point-max))))))
+      (if (symbolp tprop)
+	  ;; TPROP is a text property symbol.
+	  (put-text-property start end tprop p)
+	;; TPROP is an alist with (property . function) elements.
+	(pcase-dolist ((,prop . ,f) tprop)
+	  (put-text-property start end prop (funcall f p)))))))

(defun org-refresh-category-properties ()
"Refresh category text properties in the buffer."
@@ -8313,9 +8341,9 @@ sub-tree if optional argument INHERIT is non-nil."
(t org-category))))
(with-silent-modifications
(org-with-wide-buffer
-       ;; Set buffer-wide category.  Search last #+CATEGORY keyword.
-       ;; This is the default category for the buffer.  If none is
-       ;; found, fall-back to org-category' or buffer file name.
+       ;; Set buffer-wide property from keyword.  Search last #+CATEGORY
+       ;; keyword.  If none is found, fall-back to org-category' or
+       ;; buffer file name, or set it by the document property drawer.
(put-text-property
(point-min) (point-max)
'org-category
@@ -8327,15 +8355,20 @@ sub-tree if optional argument INHERIT is non-nil."
(throw 'buffer-category
(org-element-property :value element)))))
default-category))
-       ;; Set sub-tree specific categories.
+       ;; Set categories from the document property drawer or
+       ;; property drawers in the outline.  If category is found in
+       ;; the property drawer for the whole buffer that value
+       ;; overrides the keyword-based value set above.
(goto-char (point-min))
(let ((regexp (org-re-property "CATEGORY")))
(while (re-search-forward regexp nil t)
(let ((value (match-string-no-properties 3)))
(when (org-at-property-p)
(put-text-property
-		(save-excursion (org-end-of-subtree t t) (point))
+				    (point-max)
+				  (org-end-of-subtree t t)))
'org-category
value)))))))))

@@ -12921,30 +12954,45 @@ Modifications are made by side-effect.  Return new alist."

(defun org-get-property-block (&optional beg force)
"Return the (beg . end) range of the body of the property drawer.
-BEG is the beginning of the current subtree, or of the part
-before the first headline.  If it is not given, it will be found.
-If the drawer does not exist, create it if FORCE is non-nil, or
-return nil."
+BEG is the beginning of the current subtree or the beginning of
+the document if before the first headline.  If it is not given,
+it will be found.  If the drawer does not exist, create it if
+FORCE is non-nil, or return nil."
(org-with-wide-buffer
-   (when beg (goto-char beg))
-     (let ((beg (cond (beg)
+   (let ((beg (cond (beg (goto-char beg))
-       (forward-line)
-       (when (looking-at-p org-planning-line-re) (forward-line))
-       (cond ((looking-at org-property-drawer-re)
-	      (forward-line)
-	      (cons (point) (progn (goto-char (match-end 0))
-				   (line-beginning-position))))
-	     (force
-	      (goto-char beg)
-	      (org-insert-property-drawer)
-	      (let ((pos (save-excursion (search-forward ":END:")
-					 (line-beginning-position))))
-		(cons pos pos))))))))
+		      (t (org-with-limited-levels
+			 (point)))))
+     ;; Move point to its position according to its positional rules.
+	    (while (and (bolp) (or (org-at-keyword-p) (org-at-comment-p))) (forward-line)))
+	   (t (forward-line)
+	      (when (looking-at-p org-planning-line-re) (forward-line))))
+     (cond ((looking-at org-property-drawer-re)
+	    (forward-line)
+	    (cons (point) (progn (goto-char (match-end 0))
+				 (line-beginning-position))))
+	   (force
+	    (goto-char beg)
+	    (org-insert-property-drawer)
+	    (let ((pos (save-excursion (re-search-forward org-property-drawer-re)
+				       (line-beginning-position))))
+	      (cons pos pos)))))))
+
+(defun org-at-property-block-p ()
+  "Return t when point is at the first line of a property drawer.
+The property drawer is validated according to its positional
+rules using org-get-property-block'."
+  (save-excursion
+    (beginning-of-line)
+    (and (looking-at org-property-start-re)
+	 (forward-line)
+	 (let ((property-drawer (org-get-property-block)))
+	   (and property-drawer
+		(= (point) (car property-drawer)))))))

(defun org-at-property-p ()
"Non-nil when point is inside a property drawer.
@@ -13029,7 +13077,7 @@ Return value is an alist.  Keys are properties, as upcased
strings."
(org-with-point-at pom
(when (and (derived-mode-p 'org-mode)
(catch 'exit
(let* ((beg (point))
(specific (and (stringp which) (upcase which)))
@@ -13238,13 +13286,13 @@ unless LITERAL-NIL is non-nil."
;; Return final values.
(and (not (equal value '(nil))) (nreverse value))))))

-(defun org--property-global-value (property literal-nil)
-  "Return value for PROPERTY in current buffer.
+(defun org--property-global-or-keyword-value (property literal-nil)
+  "Return value for PROPERTY as defined by global properties or by keyword.
Return value is a string.  Return nil if property is not set
-globally.  Also return nil when PROPERTY is set to \"nil\",
-unless LITERAL-NIL is non-nil."
+globally or by keyword.  Also return nil when PROPERTY is set to
+\"nil\", unless LITERAL-NIL is non-nil."
(let ((global
-	 (cdr (or (assoc-string property org-file-properties t)
+	 (cdr (or (assoc-string property org-keyword-properties t)
(assoc-string property org-global-properties t)
(assoc-string property org-global-properties-fixed t)))))
(if literal-nil global (org-not-nil global))))
@@ -13393,12 +13441,12 @@ However, if LITERAL-NIL is set, return the string value \"nil\" instead."
value)))
(cond
((car v)
(move-marker org-entry-property-inherited-from (point))
(throw 'exit nil))
(t
-	     (let ((global (org--property-global-value property literal-nil)))
+	     (let ((global (org--property-global-or-keyword-value property literal-nil)))
(cond ((not global))
(value (setq value (concat global " " value)))
(t (setq value global))))
@@ -13430,8 +13478,8 @@ decreases scheduled or deadline date by one day."
(user-error "Invalid property name: \"%s\"" property)))
(org-with-point-at pom
(let ((beg (point)))
(cond
((equal property "TODO")
@@ -13567,19 +13615,26 @@ COLUMN formats in the current buffer."
Do nothing if the drawer already exists.  The newly created
drawer is immediately hidden."
(org-with-wide-buffer
+   ;; Set point to the position where the drawer should be inserted.
-   (forward-line)
-   (when (looking-at-p org-planning-line-re) (forward-line))
+       (while (and (bolp) (or (org-at-keyword-p) (org-at-comment-p))) (forward-line))
+     (progn
+       (forward-line)
+       (when (looking-at-p org-planning-line-re) (forward-line))))
(unless (looking-at-p org-property-drawer-re)
;; Make sure we start editing a line from current entry, not from
;; next one.  It prevents extending text properties or overlays
;; belonging to the latter.
-     (when (bolp) (backward-char))
-     (let ((begin (1+ (point)))
+     (when (and (bolp) (> (point) (point-min))) (backward-char))
+     (let ((begin (if (= (point) (point-min))
+		      (point)
+		    (1+ (point))))
-       (insert "\n:PROPERTIES:\n:END:")
+       (unless (= begin (point-min)) (insert "\n"))
+       (insert ":PROPERTIES:\n:END:")
(org-flag-drawer t nil (line-end-position 0) (point))
(when (eobp) (insert "\n"))
(org-indent-region begin (point))))))
@@ -20484,6 +20539,15 @@ interactive command with similar behavior."
(error (error "Before first headline at position %d in buffer %s"
(point) (current-buffer)))))

+  "Go back to heading or first point in buffer.
+If point is before first heading go to first point in buffer
+  (condition-case nil
+    (error
+     (goto-char (point-min)))))
+
(org-with-limited-levels
@@ -20517,6 +20581,12 @@ unless optional argument NO-INHERITANCE is non-nil."
(beginning-of-line)
(looking-at "^[ \t]*# "))))

+(defun org-at-keyword-p nil
+  "Return t if cursor is at a keyword-line."
+  (save-excursion
+    (move-beginning-of-line 1)
+    (looking-at org-keyword-regexp)))
+
(defun org-at-drawer-p nil
"Return t if cursor is at a drawer keyword."
(save-excursion
@@ -20564,6 +20634,17 @@ make a significant difference in outlines with very many siblings."
(re-search-backward (format "^\\*\\{1,%d\\} " level-up) nil t)
(funcall outline-level)))))

+  "Move to the heading line of which the present is a subheading, or point-min.
+This version is needed to make point-min behave like a virtual
+heading of level 0 for property-inheritance.  It will return the
+level of the headline found (down to 0) or nil if already at a
+point before the first headline or at point-min."
+    (if (< 1 (funcall outline-level))
+      (unless (= (point) (point-min)) (goto-char (point-min))))))
+
(defun org-first-sibling-p ()
"Is this heading the first child of its parents?"
(interactive)
@@ -20664,28 +20745,31 @@ If there is no such heading, return nil."
"Goto to the end of a subtree."
;; This contains an exact copy of the original function, but it uses
-  ;; org-back-to-heading', to make it work also in invisible
-  ;; trees.  And is uses an invisible-ok argument.
+  ;; org-back-to-heading-or-point-min', to make it work also in invisible
+  ;; trees and before first headline.  And is uses an invisible-ok argument.
;; Under Emacs this is not needed, but the old outline.el needs this fix.
;; Furthermore, when used inside Org, finding the end of a large subtree
;; with many children and grandchildren etc, this can be much faster
;; than the outline version.
(let ((first t)
(level (funcall outline-level)))
-    (if (and (derived-mode-p 'org-mode) (< level 1000))
-	;; A true heading (not a plain list item), in Org
-	;; This means we can easily find the end by looking
-	;; only for the right number of stars.  Using a regexp to do
-	;; this is so much faster than using a Lisp loop.
-	(let ((re (concat "^\\*\\{1," (int-to-string level) "\\} ")))
-	  (forward-char 1)
-	  (and (re-search-forward re nil 'move) (beginning-of-line 1)))
-      ;; something else, do it the slow way
-      (while (and (not (eobp))
-		  (or first (> (funcall outline-level) level)))
-	(setq first nil)
+    (cond ((= level 0)
+	   (goto-char (point-max)))
+	  ((and (derived-mode-p 'org-mode) (< level 1000))
+	   ;; A true heading (not a plain list item), in Org
+	   ;; This means we can easily find the end by looking
+	   ;; only for the right number of stars.  Using a regexp to do
+	   ;; this is so much faster than using a Lisp loop.
+	   (let ((re (concat "^\\*\\{1," (int-to-string level) "\\} ")))
+	     (forward-char 1)
+	     (and (re-search-forward re nil 'move) (beginning-of-line 1))))
+	  (t
+	   ;; something else, do it the slow way
+	   (while (and (not (eobp))
+		       (or first (> (funcall outline-level) level)))
+	     (setq first nil)
(when (memq (preceding-char) '(?\n ?\^M))
;; Go to end of line before heading
diff --git a/testing/examples/property-inheritance.org b/testing/examples/property-inheritance.org
index 6979de595..9c0b7e662 100644
--- a/testing/examples/property-inheritance.org
+++ b/testing/examples/property-inheritance.org
@@ -1,5 +1,7 @@
+:PROPERTIES:
+:END:

#+begin_src emacs-lisp
(+ foo bar)
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index f2ab38031..1408e6be5 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -1925,6 +1925,15 @@ e^{i\\pi}+1=0
(let ((element (org-element-at-point)))
(list (org-element-property :key element)
(org-element-property :value element))))))
+  ;; The insides of property blocks on document level are parsed the
+  ;; same way as headline property blocks.  I.e. the concept of
+  ;; node-property' apply also for properties in those blocks.
+  (should
+   (equal '("abc" "value")
+	  (org-test-with-temp-text ":PROPERTIES:\n<point>:abc: value\n:END:"
+	    (let ((element (org-element-at-point)))
+	      (list (org-element-property :key element)
+		    (org-element-property :value element))))))
;; Value should be trimmed.
(should
(equal "value"
@@ -2111,6 +2120,18 @@ Outside list"
(org-test-with-temp-text
(org-element-type (org-element-at-point)))))
+  (should
+   (eq 'property-drawer
+       (org-test-with-temp-text "<point>:PROPERTIES:\n:prop: value\n:END:"
+	 (org-element-type (org-element-at-point)))))
+  (should
+   (eq 'property-drawer
+       (org-test-with-temp-text "# C\n#+Key: V\n# C\n<point>:PROPERTIES:\n:prop: value\n:END:"
+	 (org-element-type (org-element-at-point)))))
+  (should-not
+   (eq 'property-drawer
+       (org-test-with-temp-text "\n<point>:PROPERTIES:\n:prop: value\n:END:"
+	 (org-element-type (org-element-at-point)))))
;; Allow properties without value and no property at all.
(should
(eq 'property-drawer
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 215d8fdb0..1b3fb48bb 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -386,10 +386,116 @@
\f
;;; Drawers

+(ert-deftest test-org/at-property-p ()
+  "Test org-at-property-p' specifications."
+  (should
+   (equal 't
+	  (org-test-with-temp-text "* H\n:PROPERTIES:\n<point>:PROP: t\n:END:\n"
+	    (org-at-property-p))))
+  (should
+   (equal 't
+	  (org-test-with-temp-text ":PROPERTIES:\n<point>:PROP: t\n:END:\n"
+	    (org-at-property-p)))))
+
+(ert-deftest test-org/at-property-block-p ()
+  "Test org-at-property-block-p' specifications."
+  (should
+   (equal 't
+	  (org-test-with-temp-text "* H\n<point>:PROPERTIES:\n:PROP: t\n:END:\n"
+	    (org-at-property-block-p))))
+  (should
+   (equal 't
+	  (org-test-with-temp-text ":PROPERTIES:\n:PROP: t\n:END:\n"
+	    (org-at-property-block-p))))
+  ;; The function only returns t if point is at the first line of a
+  ;; property block.
+  (should-not
+   (equal 't
+	  (org-test-with-temp-text ":PROPERTIES:\n<point>:PROP: t\n:END:\n"
+	    (org-at-property-block-p)))))
+
+(ert-deftest test-org/get-property-block ()
+  "Test org-get-property-block' specifications."
+  (should
+   (equal '(14 . 14)
+	  (org-test-with-temp-text ":PROPERTIES:\n:END:\n* H\n"
+	    (org-get-property-block))))
+  (should
+   (equal '(14 . 14)
+	  (org-test-with-temp-text ":PROPERTIES:\n:END:\n"
+	    (org-get-property-block))))
+  ;; Comments above a document property block is ok.
+  (should
+   (equal '(18 . 18)
+	  (org-test-with-temp-text "# C\n:PROPERTIES:\n:END:\n"
+	    (org-get-property-block))))
+  ;; Keywords above a document property block is ok.
+  (should
+   (equal '(23 . 23)
+	  (org-test-with-temp-text "#+Key: v\n:PROPERTIES:\n:END:\n"
+	    (org-get-property-block))))
+  ;; Comments and keywords are allowed before a document property block.
+  (should
+   (equal '(27 . 36)
+	  (org-test-with-temp-text "# C\n#+key: v\n:PROPERTIES:\n:KEY: V:\n:END:\n"
+	    (org-get-property-block))))
+  (should
+   (equal '(36 . 45)
+	  (org-test-with-temp-text "#+Key: v\n# C\n#+Key: v\n:PROPERTIES:\n:KEY: V:\n:END:\n"
+	    (org-get-property-block))))
+  ;; A document property block will not be valid if there are lines
+  ;; with whitespace above it
+  (should-not
+   (org-test-with-temp-text "\n:PROPERTIES:\n:END:\n"
+     (org-get-property-block)))
+  (should
+   (equal '(18 . 18)
+	  (org-test-with-temp-text "* H\n:PROPERTIES:\n:END:\n<point>"
+	    (org-get-property-block))))
+  (should
+   (equal "* H\n:PROPERTIES:\n:END:\n"
+	  (org-test-with-temp-text "* H"
+	      (org-get-property-block nil 'force))
+	    (buffer-string))))
+  (should
+   (equal ":PROPERTIES:\n:END:\n"
+	  (org-test-with-temp-text ""
+	    (org-get-property-block nil 'force)
+	    (buffer-string))))
+  (should
+   (equal "* H1\n  :PROPERTIES:\n  :END:\n* H2"
+	  (org-test-with-temp-text "* H1\n* H2"
+	      (org-get-property-block nil 'force))
+	    (buffer-string)))))
+
(ert-deftest test-org/insert-property-drawer ()
"Test org-insert-property-drawer' specifications."
-  ;; Error before first headline.
-  (should-error (org-test-with-temp-text "" (org-insert-property-drawer)))
+  ;; Insert drawer in empty buffer
+  (should
+   (equal ":PROPERTIES:\n:END:\n"
+	  (org-test-with-temp-text ""
+	    (buffer-string))))
+  ;; Insert drawer in document header with existing comment and
+  ;; keyword.
+  (should
+   (equal "# C\n#+TITLE: T\n:PROPERTIES:\n:END:\n"
+	  (org-test-with-temp-text "# C\n#+TITLE: T"
+	    (buffer-string))))
+  (should
+   (equal ":PROPERTIES:\n:END:"
+	  (org-test-with-temp-text ":PROPERTIES:\n:END:"
+	    (buffer-string))))
+  ;; Insert drawer in document header with one existing heading in buffer.
+  (should
+   (equal ":PROPERTIES:\n:END:\n* T\n"
+	  (org-test-with-temp-text "<point>\n* T\n"
+	    (buffer-string))))
;; Insert drawer right after headline if there is no planning line,
;; or after it otherwise.
(should
@@ -2178,19 +2284,19 @@ SCHEDULED: <2014-03-04 tue.>"
(equal "foo=1"
(org-test-with-temp-text "#+PROPERTY: var foo=1"
(org-mode-restart)
-	    (cdr (assoc "var" org-file-properties)))))
+	    (cdr (assoc "var" org-keyword-properties)))))
(should
(equal
"foo=1 bar=2"
(org-test-with-temp-text "#+PROPERTY: var foo=1\n#+PROPERTY: var+ bar=2"
(org-mode-restart)
-      (cdr (assoc "var" org-file-properties)))))
+      (cdr (assoc "var" org-keyword-properties)))))
(should
(equal
"foo=1 bar=2"
(org-test-with-temp-text "#+PROPERTY: var foo=1\n#+PROPERTY: VAR+ bar=2"
(org-mode-restart)
-      (cdr (assoc "var" org-file-properties)))))
+      (cdr (assoc "var" org-keyword-properties)))))
;; ARCHIVE keyword.
(should
(equal "%s_done::"
@@ -2207,7 +2313,7 @@ SCHEDULED: <2014-03-04 tue.>"
(equal "test"
(org-test-with-temp-text "#+CATEGORY: test"
(org-mode-restart)
-	    (cdr (assoc "CATEGORY" org-file-properties)))))
+	    (cdr (assoc "CATEGORY" org-keyword-properties)))))
;; COLUMNS keyword.
(should
(equal "%25ITEM %TAGS %PRIORITY %TODO"
@@ -2291,7 +2397,7 @@ SCHEDULED: <2014-03-04 tue.>"
(org-test-with-temp-text
(format "#+SETUPFILE: \"%s/examples/setupfile.org\"" org-test-dir)
(org-mode-restart)
-	    (cdr (assoc "a" org-file-properties))))))
+	    (cdr (assoc "a" org-keyword-properties))))))

\f
@@ -4941,6 +5047,66 @@ Paragraph<point>"
(org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A+: 2\n:END:"
(org-property-values "A")))))

+(ert-deftest test-org/set-property ()
+  "Test org-set-property' specifications."
+  (should
+   (equal
+    ":PROPERTIES:\n:TEST: t\n:END:\n"
+    (org-test-with-temp-text ""
+      (let ((org-property-format "%s %s"))
+	(org-set-property "TEST" "t"))
+      (buffer-string))))
+  (should
+   (equal
+    "* H\n:PROPERTIES:\n:TEST: t\n:END:\n"
+    (org-test-with-temp-text "* H"
+	    (org-property-format "%s %s"))
+	(org-set-property "TEST" "t"))
+      (buffer-string)))))
+
+(ert-deftest test-org/delete-property ()
+  "Test org-delete-property' specifications."
+  (should
+   (equal
+    ""
+    (org-test-with-temp-text ":PROPERTIES:\n:TEST: t\n:END:\n"
+      (org-delete-property "TEST")
+      (buffer-string))))
+  (should
+   (equal
+    ":PROPERTIES:\n:TEST1: t\n:END:\n"
+    (org-test-with-temp-text ":PROPERTIES:\n:TEST1: t\n:TEST2: t\n:END:\n"
+      (org-delete-property "TEST2")
+      (buffer-string))))
+  (should
+   (equal
+    "* H\n"
+    (org-test-with-temp-text "* H\n:PROPERTIES:\n:TEST: t\n:END:\n"
+      (org-delete-property "TEST")
+      (buffer-string))))
+  (should
+   (equal
+    "* H\n:PROPERTIES:\n:TEST1: t\n:END:\n"
+    (org-test-with-temp-text "* H\n:PROPERTIES:\n:TEST1: t\n:TEST2: t\n:END:\n"
+      (org-delete-property "TEST2")
+      (buffer-string)))))
+
+(ert-deftest test-org/delete-property-globally ()
+  "Test org-delete-property-global' specifications."
+  (should
+   (equal
+    ""
+    (org-test-with-temp-text ":PROPERTIES:\n:TEST: t\n:END:\n"
+      (org-delete-property-globally "TEST")
+      (buffer-string))))
+  (should
+   (equal
+    "* H\n"
+    (org-test-with-temp-text ":PROPERTIES:\n:TEST: t\n:END:\n* H\n:PROPERTIES:\n:TEST: nil\n:END:"
+      (org-delete-property-globally "TEST")
+      (buffer-string)))))
+
(ert-deftest test-org/find-property ()
"Test org-find-property' specifications."
;; Regular test.
@@ -5022,6 +5188,10 @@ Paragraph<point>"
(ert-deftest test-org/entry-get ()
"Test org-entry-get' specifications."
;; Regular test.
+  (should
+   (equal "1"
+	  (org-test-with-temp-text ":PROPERTIES:\n:A: 1\n:END:"
+	    (org-entry-get (point) "A"))))
(should
(equal "1"
(org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
@@ -5061,6 +5231,11 @@ Paragraph<point>"
(org-entry-get (point) "B" nil t)))
;; Handle inheritance, when allowed.  Include extended values and
;; possibly global values.
+  (should
+   (equal
+    "1"
+    (org-test-with-temp-text ":PROPERTIES:\n:A: 1\n:END:\n* H"
+      (org-entry-get (point-max) "A" t))))
(should
(equal
"1"
@@ -5076,12 +5251,30 @@ Paragraph<point>"
(org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2"
(let ((org-use-property-inheritance nil))
(org-entry-get (point-max) "A" 'selective))))
+  (should
+   (equal
+    "1 2"
+    (org-test-with-temp-text
+	":PROPERTIES:\n:A: 1\n:END:\n* H\n:PROPERTIES:\n:A+: 2\n:END:"
+      (org-entry-get (point-max) "A" t))))
(should
(equal
"1 2"
(org-test-with-temp-text
"* H\n:PROPERTIES:\n:A: 1\n:END:\n** H2\n:PROPERTIES:\n:A+: 2\n:END:"
(org-entry-get (point-max) "A" t))))
+  (should
+   (equal
+    "1 2"
+    (org-test-with-temp-text
+	":PROPERTIES:\n:A: 1\n:END:\n* H1\n* H2\n:PROPERTIES:\n:A+: 2\n:END:"
+      (org-entry-get (point-max) "A" t))))
+  (should
+   (equal
+    "1 2"
+    (org-test-with-temp-text
+	"* H1\n:PROPERTIES:\n:A: 1\n:END:\n* H2.1\n* H2.2\n:PROPERTIES:\n:A+: 2\n:END:"
+      (org-entry-get (point-max) "A" t))))
(should
(equal "1"
(org-test-with-temp-text
@@ -5093,6 +5286,14 @@ Paragraph<point>"
(org-test-with-temp-text
"#+PROPERTY: A 0\n* H\n:PROPERTIES:\n:A+: 1\n:END:"
(org-mode-restart)
+	    (org-entry-get (point-max) "A" t))))
+  ;; document level property-drawer has precedance over
+  ;; global-property by PROPERTY-keyword.
+  (should
+   (equal "0 2"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 0\n:END:\n#+PROPERTY: A 1\n* H\n:PROPERTIES:\n:A+: 2\n:END:"
+	    (org-mode-restart)
(org-entry-get (point-max) "A" t)))))

(ert-deftest test-org/entry-properties ()
@@ -5416,8 +5617,44 @@ Paragraph<point>"
(let ((org-use-property-inheritance t))
(org-refresh-properties "A" 'org-test))
(get-text-property (point) 'org-test))))
+  ;; When a document level property-drawer is used, those properties
+  ;; should work exactly like headline-properties as if at a
+  (should
+   (equal "1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 1\n:END:\n"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-properties "A" 'org-test))
+	    (get-text-property (point) 'org-test))))
+  (should-not
+   (equal "1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 1\n:END:\n<point>* H1"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance nil))
+	      (org-refresh-properties "A" 'org-test))
+	    (get-text-property (point) 'org-test))))
+  (should
+   (equal "1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 1\n:END:\n<point>* H1"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-properties "A" 'org-test))
+	    (get-text-property (point) 'org-test))))
+  (should
+   (equal "2"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 1\n:END:\n<point>* H1\n:PROPERTIES:\n:A: 2\n:END:"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-properties "A" 'org-test))
+	    (get-text-property (point) 'org-test))))
;; When property is inherited, use global value across the whole
-  ;; buffer.  However local values have precedence.
+  ;; buffer.  However local values have precedence, as well as the
+  ;; document level property-drawer.
(should-not
(equal "1"
(org-test-with-temp-text "#+PROPERTY: A 1\n<point>* H1"
@@ -5437,10 +5674,62 @@ Paragraph<point>"
(org-test-with-temp-text
"#+PROPERTY: A 1\n<point>* H\n:PROPERTIES:\n:A: 2\n:END:"
(org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-properties "A" 'org-test))
+	    (get-text-property (point) 'org-test))))
+  ;; When both keyword-property and document-level property-block is
+  ;; defined, the property-block has precedance.
+  (should
+   (equal "1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:A: 1\n:END:\n#+PROPERTY: A 2\n<point>* H1"
+	    (org-mode-restart)
(let ((org-use-property-inheritance t))
(org-refresh-properties "A" 'org-test))
(get-text-property (point) 'org-test)))))

+(ert-deftest test-org/refresh-category-properties ()
+  "Test org-refresh-category-properties' specifications"
+  (should
+   (equal "cat1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:CATEGORY: cat1\n:END:"
+	    (org-refresh-category-properties)
+	    (get-text-property (point) 'org-category))))
+  (should
+   (equal "cat1"
+	  (org-test-with-temp-text
+	      "* H\n:PROPERTIES:\n:CATEGORY: cat1\n:END:"
+	    (org-refresh-category-properties)
+	    (get-text-property (point) 'org-category))))
+  ;; Even though property-inheritance is deactivated, category
+  ;; property should be inherited.  As described in
+  ;; org-use-property-inheritance'.
+  (should
+   (equal "cat1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:CATEGORY: cat1\n:END:\n<point>* H"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance nil))
+	      (org-refresh-category-properties))
+	    (get-text-property (point) 'org-category))))
+  (should
+   (equal "cat1"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:CATEGORY: cat1\n:END:\n<point>* H"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-category-properties))
+	    (get-text-property (point) 'org-category))))
+  (should
+   (equal "cat2"
+	  (org-test-with-temp-text
+	      ":PROPERTIES:\n:CATEGORY: cat1\n:END:\n<point>* H\n:PROPERTIES:\n:CATEGORY: cat2\n:END:\n"
+	    (org-mode-restart)
+	    (let ((org-use-property-inheritance t))
+	      (org-refresh-category-properties))
+	    (get-text-property (point) 'org-category)))))
+
\f
;;; Refile

--
2.17.1

^ permalink raw reply related	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2020-02-01 19:59 UTC | newest]

2019-10-20  2:28 [RFC] Document level property drawer Gustav Wikström
2019-10-22 21:24  Marco Wahl
2019-10-23  8:43  Marco Wahl
2019-10-23  8:59    Gustav Wikström
2019-10-24 21:01    Gustav Wikström
2019-10-25 12:58      Marco Wahl
2019-10-23 16:08  Adam Porter
-- strict thread matches above, loose matches on Subject: below --
2019-10-24 22:29 Gustav Wikström
2019-10-06  6:02 Gustav Wikström
2019-10-06  5:35 Gustav Wikström
2019-10-05 18:20 Gustav Wikström
2019-10-02 20:29 Gustav Wikström
2019-09-30 22:09 Gustav Wikström
2019-10-03 18:31  Adam Porter
2019-10-04 10:38    Marco Wahl
2019-10-06  1:01      Adam Porter
2019-10-07  7:46        Marco Wahl
2019-09-29 10:27 Gustav Wikström
2019-09-29 19:13  Marco Wahl
2019-09-30 20:46    Marco Wahl
2019-10-01 12:38      Sebastian Miele
2020-01-13 21:52        Marco Wahl
2020-01-15  8:18          Sebastian Miele
2020-02-01 19:59            Marco Wahl
2019-10-02 10:29        Marco Wahl
2019-10-04 11:05            Marco Wahl
2019-10-06  5:10                Matt Price
2019-10-16  0:48    Adam Porter

Code repositories for project(s) associated with this public inbox
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).`