From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id GM6DDjlq62MucgEAbAwnHQ (envelope-from ) for ; Tue, 14 Feb 2023 12:02:17 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id MMIxDjlq62NYIwEAauVa8A (envelope-from ) for ; Tue, 14 Feb 2023 12:02:17 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 17D43FC1D for ; Tue, 14 Feb 2023 12:02:15 +0100 (CET) Authentication-Results: aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1676372536; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=wqbM315hLcaK+hoBVtT8h5hKpxk58hXkbB8MH1RXkmo=; b=NwSsrIvDZT8NwP3CHC3m3W/FbIFY6umkmkdjWNHx/GlXXmZnOxnwVeIzwUWtfqCSJ/fP0z ZynKyJ853j6nvBuTqSsyanVIvNFa2GXw1SvhR4mzr1oGXGdTxZ3sRzuztQT/9rOMbjG29Q es08xzphS3ytAKaZReiFsU2K2EqNgg3fgUjReIU8L61QtsGJ57ogkE4yiX5DlwRVD64jn0 G45eg475N0rNrnQC2u6dgf+j8wnRaLbOoC8zdHUIf4QnXFPsX5mWpaPxNrvFyCLe9bkLMw jM8qS9I9UuoswuIYgEOO7+Z5W6igG1KydQRrfzvo/m107e3t4hU6adtsIUBcjw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Seal: i=1; s=key1; d=yhetil.org; t=1676372536; a=rsa-sha256; cv=none; b=qjKATHrpKZomrliF9rHm6MEp+Z4pwpIawWnwCnumcOxZT6AxYGdW+dg3zy22gDHq4/hbFZ BtNjvXiz3Dzo9OVdVMAGo6xYbnbcfwXX58GLYevLVnZAkeUuKl5Gg++/DTGTOTBGhlupMo Oa6vCzbDBNc4MqFsx1qrylYpi4hSJ0qPZbp/DiG+G2HKSDHBsDzd0VLLQobg00aRmDTLku SWcHBgi2RaHJdAcWwob+huxrZ0lf6h7Tc+nKD4rnrNeuRP4WFcVWWBXOdVYvH1+RMU2Fqg QzyN6yGujabsbh5b83klLsAb6g9q31/LH03lsIe8uDvPAGaF75oahNpXG3o2BQ== Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pRt49-0006aA-OP; Tue, 14 Feb 2023 06:01:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pRt48-0006Zx-0C for emacs-orgmode@gnu.org; Tue, 14 Feb 2023 06:01:40 -0500 Received: from stw1.rcdrun.com ([217.170.207.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pRt44-0005pA-1X for emacs-orgmode@gnu.org; Tue, 14 Feb 2023 06:01:39 -0500 Received: from localhost ([::ffff:102.85.204.48]) (AUTH: PLAIN admin, TLS: TLS1.3,256bits,ECDHE_RSA_AES_256_GCM_SHA384) by stw1.rcdrun.com with ESMTPSA id 0000000000103840.0000000063EB6A0F.00007E0F; Tue, 14 Feb 2023 04:01:35 -0700 Date: Tue, 14 Feb 2023 13:41:28 +0300 From: Jean Louis To: Cletip Cletip Cc: Org Mode List Subject: Re: Link type in org-mode, but with org-roam ? Message-ID: Mail-Followup-To: Cletip Cletip , Org Mode List References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/2.2.9+54 (af2080d) (2022-11-21) Received-SPF: pass client-ip=217.170.207.13; envelope-from=bugs@gnu.support; helo=stw1.rcdrun.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, TRACKER_ID=0.1 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: X-Migadu-Queue-Id: 17D43FC1D X-Spam-Score: -2.42 X-Migadu-Spam-Score: -2.42 X-Migadu-Scanner: scn0.migadu.com List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Country: US X-Migadu-Flow: FLOW_IN X-TUID: vf6nTW8hifi0 * Cletip Cletip [2023-02-13 19:08]: > I'm going to get straight to the point and try to be as concise as > possible, just for context: I've been using org-mode every day for at least > 2 years. I want to make it my personal knowledge/information manager. I > understand code relatively quickly, I understand less when it comes to > writing it. I've done a lot of research on note-taking methods... well, you > can see my profile I think. Where is the profile? I like note-taking researcher profiles. 🤓 > So, my goal: to make a concise system with org-mode, org-roam, org-attach, > org-agenda etc... a "classic" goal for some of us :). Good that I have given up on that puzzle of making Org database, rather using PostgreSQL database straight, and deriving Org out of it. > The problem: need to make "queryable" notes to do more or less complex > operations. For example, run the code of all headings/notes that have the > tag "ubuntu", to allow me to reinstall my computer for example. This > problem is trivial to solve with tags (a simple "dolist" is enough), but > tags will not always be enough... So you need to be able to store > "value-key" data, in order to make "select me all the people with a phone > number starting with 06" queries. This works perfectly well with this: > https://github.com/d12frosted/vulpea#metadata. I have seen that link, and I understand the attempt. > This gives things of the following conceptual form: > note1(where the metadata is stored) -> relationship -> > note2/OrValue. Okay, it is good concept. > What is stored in the database must be only the IDs (not the titles > of the note for example), but the description is there for the > user. This allows not to have a controlled vocabulary: when > searching, we look for a note id, and not a string. On the other > hand, what is displayed to the user in the notes is the description, > which is very practical. Yes. Very handy. > note1 is therefore the id of a note (in the org-roam sense). Why not call it "Note ID" then? > Relation is the id of the "metadata"/type of the desired relation. Yes, sure understandable. > And note2/Value is the value of the relationship, which may be an id of > another note or just a value. Yes, sure understandable, though complicated without reason. > In practice, it is therefore in this form: > - [[id:20230112135328669948][Name you want, but respect the idea of the > concept behind the id]] :: [[id:20220617105453042719][Another note]] > - [[id:20230112135328669948][a metadata only with a value]] :: just > a value Who knows what it means... I like to understand your thoughts. > The concept is close to the "In-Buffer Settings", with a "#+": it's > a key-value. Except that In-Buffer Settings, org-mode can't > understand that there is a link or something else, org-mode > understands just a string, which will be parsed to modify org-mode's > behaviour on that file, or for a export, etc. Something similar but not same is here. This is generated Org snippet: * http://dantorop.info/project/emacs-animation/lisp1.html [0/0] [0%] :Emacs:WWW-bookmark: :PROPERTIES: :UUID: 38484E86-CBCB-46B8-907F-CEBA90DA9F4D :END: WWW: [[http://dantorop.info/project/emacs-animation/lisp1.html]] There are many properties on the above snippet, which one cannot see directly. They are held in the database. It all goes in momentum. The UUID is the hyperlink, I press M-TAB on it and get straight to object, to edit properties of all kinds, and what you see below is not all, there are tags, timestamps, related people, related other objects, etc. Anything is possible ID 31724 Date created "2020-11-10 02:29:52.72204+03" Date modified "2023-02-14 11:29:47.202234+03" User created "maddox" User modified "maddox" Time zone "1" Start Date and Time nil End Date and Time nil Markup Type "Default (Text)" Elementary object type "WWW" Elementary object subtype "Default" Name "http://dantorop.info/project/emacs-animation/lisp1.html" Hyperlink "http://dantorop.info/project/emacs-animation/lisp1.html" Arguments nil Description nil Text nil Internal information "" Parent ID "GNU Emacs" Author nil Permission "Default" Revision nil Number of pages nil Language nil File size nil Time length nil Width nil Height nil Hash nil GPG Signature nil Pages nil Related people list nil Related person nil Related business nil Search status "Default" Set Priority 100 Author Name nil Properties nil Emacs Lisp Hash nil Publisher nil Time nil Assigned to people list nil Assigned to contact nil Global Rank 1 Active t Action status "" Global priority 100000 Related URIs nil Template nil WRS Area nil Publishing type nil Slug nil License nil File type nil Report nil Tokens "'/project/emacs-animation/lisp1.html':3,7 '31724':4 'bookmark':11 'dantorop.info':2,6 'dantorop.info/project/emacs-animation/lisp1.html':1,5 'emac':8 'www':10 'www-bookmark':9" Temporary Document nil Override Major Mode nil Minor Modes nil Related country nil Report to nil Physical location nil Lead Source nil Currency nil Sales Flow Stage nil WRS Category nil WRS Menu nil WRS Keywords nil WRS Priority 10 WRS Not in Menu nil WRS Main Page nil WRS OG Image nil Curator nil Comm Line nil Location nil AVAILABLE (was Assigned to people list) nil SKU nil Value or Price nil Introduced by nil UUID "38484e86-cbcb-46b8-907f-ceba90da9f4d" Admin Scale nil Admin Scale Type nil Admin Scale Parent nil Admin Scale Priority 0 Programming Language nil > Concrete example: if I want to store all my music (eache music = a note > with an attached file), I have two choices: > - I put the tag "music", in the org-roam sense (i.e. "#+filetag: #music") > for each note. > - But, this amounts to writing: aMusic relation(here, "tagged with" for > example) note2 or in practice: - [[idOfTaggedwith][tag]]: > [[idOfTheConceptOfMusic][music]]. So we can make the following request: > give me the notes with the metadata "idOfTaggedwith" with the value > "idOfTheConceptOfMusic" (because, I remind you, only ids are stored. Just > make a convenient interface for the user, and he won't even need to think > about ids). Any writing should be swift and integrated. User should not have problems connecting objects and their properties or other objects. You are right, thinking of IDs is redundant I would not store only tags, as tags are only floating types. I would define types, subtypes, maybe subsubtypes, and then define what is to be done for each combination of types and subtypes. Using tags is always possible to define types, but then it becomes non-rigid, and thus vague system. I do think that using only UUID is and should be enough, and such UUID should have properties defined elsewhere: * My music name :PROPERTIES: :UUID: e477da5d-2c51-460e-a13e-3faba74d2aa0 :END: But we can also think of this case: * My music name :PROPERTIES: :UUID: e477da5d-2c51-460e-a13e-3faba74d2aa0 :TYPE: Audio :SUBTYPE: Music :END: or something like this: * My music name :PROPERTIES: :UUID: e477da5d-2c51-460e-a13e-3faba74d2aa0 :TYPE: Music :SUBTYPE: Country :END: Then you can define what you wish for combination: "Music, Country" as you could have some other combination "Music, My favorite" for which you could define something else, some other action, some other intersection list or play list. > Furthermore, I think this problem is part of a more global problem: they > are "typed links". They can be called by many names: link tags > https://org-roam.discourse.group/t/add-link-tags-feature/171, link types, > relational links, etc. If someone has the "right" name to describe this... Which is alright. That is how it should be. Elementary Objects: https://www.dougengelbart.org/content/view/110/460/#2a1a I think of "link" as one of possible elementary objects. When there is feature to "tag" them or assign properties, that means we get intersection feature to query them and make more decisions how to handle such objects > And therein lies my real problem: I haven't found a single good > solution to achieve this. This problem is mostly related to > org-roam, but org-roam is based on org-mode, that's why I'm writing > here. I do not use it, but what you say is quite understandable, that is what I use daily in my work. Org is not a relationship database, it is not designed for relationships, though there are good attempts to it. It is very easy to create a relationship table in any kind of database and use it with Org. 1. Create a single table with Org UUID, ID, referencing other UUID, ID ---------------------------------------------------------------------- -- ------------------------------------------ -- ------------ Table orgrels -- ------------------------------------------ DROP SEQUENCE orgrels_id_seq; CREATE TABLE orgrels ( orgrels_id SERIAL NOT NULL PRIMARY KEY, orgrels_uuid UUID NOT NULL DEFAULT gen_random_uuid() UNIQUE, orgrels_fromuuid UUID NOT NULL, orgrels_touuid UUID NOT NULL, orgrels_datecreated TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, orgrels_datemodified TIMESTAMP, orgrels_usercreated TEXT NOT NULL DEFAULT current_user, orgrels_usermodified TEXT NOT NULL DEFAULT current_user, orgrels_name TEXT, orgrels_description TEXT ); GRANT ALL ON orgrels TO PUBLIC; DROP VIEW orgrels_combo; CREATE OR REPLACE VIEW orgrels_combo AS SELECT orgrels_id AS id, orgrels_name AS TEXT FROM orgrels; GRANT SELECT ON orgrels_combo TO PUBLIC; COMMENT ON TABLE orgrels IS 'Org Relationships; COMMENT ON COLUMN orgrels.orgrels_id IS 'ID'; COMMENT ON COLUMN orgrels.orgrels_uuid IS 'From UUID'; COMMENT ON COLUMN orgrels.orgrels_touuid IS 'To UUID'; COMMENT ON COLUMN orgrels.orgrels_datecreated IS 'Date created'; COMMENT ON COLUMN orgrels.orgrels_datemodified IS 'Date modified'; COMMENT ON COLUMN orgrels.orgrels_usercreated IS 'User created'; COMMENT ON COLUMN orgrels.orgrels_usermodified IS 'User modified'; COMMENT ON COLUMN orgrels.orgrels_name IS 'Name'; COMMENT ON COLUMN orgrels.orgrels_description IS 'Description'; -- Triggers -- For Date Modified CREATE TRIGGER orgrels_moddatetime BEFORE UPDATE ON orgrels FOR EACH ROW EXECUTE PROCEDURE moddatetime(orgrels_datemodified); -- For User Modified CREATE TRIGGER insert_username_orgrels BEFORE INSERT OR UPDATE ON orgrels FOR EACH ROW EXECUTE PROCEDURE insert_username(orgrels_usermodified); ------------- Once above table is created it becomes ~very~ possible to see all of the related other Org UUID headings. But why go there in that direction of mixing Org and database at all, when it can all be done easier with databases anyway. Org Roam (which I do not use) demonstrates good design of relations between objects. > As you know, external links can be of the form "X:path", where X equals id, > file, gnus etc. Note: Org-roam stores all types of links. > So we can make the following type of links: > [[A:B][description]] > where > - A is the id of a note known by org-roam > - B is the id of a note, or string, or numeric value, etc > - description is a description (what a precision) That is very nice, that demonstrates relationship ID, though I see it as single relationship. I use that in my Hyperscope system and represent it as following: ID 1 Hyperdocument 1 "Ideas on how to use Hyperscope dynamic knowledge repository" Hyperdocument 2 "Principles of HyperScope File Sorting System" Description nil Relation type "Default" Date created "2022-09-10 08:22:01.090606+03" Date modified "2022-09-10 08:23:43.113135+03" User created "maddox" User modified "maddox" UUID "694267c9-6d2c-4bc0-a736-cd1b5e69058a" So I can use that UUID and Description to make that link: [[uuid:694267c9-6d2c-4bc0-a736-cd1b5e69058a][description]] Then based on UUID, I can go to that above relationship. One click and I see relationship. (defun hyperscope-see-relationship (id) "Jump to Hyperdocument relationship by UUID." (rcd-db-tabulated-edit-entry "relatedhyperdocuments" id)) (defcustom rcd-db-uuid-action-alist '(("people" . cf-people-by-id) ("hyobjects" . hyperscope) ("sobjects" . ignore) ("predicates" . ignore) ("uuid2uuid" . ignore) ("relatedhyperdocuments" . hyperscope-see-relationship) ("properties" . rcd-notes-properties-list-by-referenced-uuid) ("statsdefinitions" . rcd-r-statistics-view) ("transactions" . rcd-accounts-transaction-edit) ("messages" . rcd-message-edit-by-id)) "Database UUID action alist." :group 'rcd :type '(alist)) And I fully agree with your thinking, even though my example is not fully aligned with your idea. > This allows org-roam to store the type of the relationship, A, and the > value of the relationship, B. So we can make queries like: "all notes where > idOfTaggedwith = idOfTheConceptOfMusic". That is good, that is how it should be. > Implementation (functional on my side. It took me a lot of time, because I > didn't know the org-mode code. But it's done without too much difficulty I > think, as it's a link addition). : Think of implementing it in SQLite or PostgreSQL even better for future collaborative purposes. All becomes easier. Database handles many things for you. Programming is minimized. Implementation becomes rapid. > Some problems arise like : > - org-mode "fits" org-roam, and not the other way around. On the other > hand, if there is a real use for this kind of link, then org-roam would be > the one to adapt. (Because a relationship is defined here by a note... > which is an org-roam note. But that could be a simple id generated by > org-mode... I don't know. Relationship are perhaps not so > necessarily id...) Your thinking is right. One thing missing, you speak of single relationship. In my database documents may be related to other documents, but also to other people, multiple times. Think: - do you wish to see single relationship between one object and other? I have demonstrated how I do it. In fact I get it visually, I press "' r" to list relationships for Hyperdocument (object), or in your case Org heading, or anything. Relationship names I have defined as following: 1 Default 2 COPY OF 3 RELATED 4 PARENT 5 CHILD 6 SIBLING 7 FOLLOWS 8 DEPENDENT And I can keep defining relationships between objects. - But for relationships between objects and people, I have it little different: 1 RELATED 2 INFORMED BY EMAIL 3 SUPPLIER 4 INTRODUCED BY 5 MAYBE RELATED 6 WAS ASSIGNED TO 7 ASSISTED 8 ATTENDED MEETING 9 INFORMED BY SMS 10 REQ-PARTICIPANT 11 COMES FROM 12 HOST 13 BORN THERE 14 NON-PARTICIPANT 15 CHAIR 16 OPT-PARTICIPANT 17 INFORMED THROUGH THEIR WEBSITE 18 DELIVERED TO 19 INFORMED BY XMPP 20 INFORMED BY PHONE 21 VISITING > - My implementation requires a modification of org-mode, which I think is > not normal. I think it's better add a layer of code with another > package. Exactly! Just add the package and connect the dots. Everything I have explained can also be stored as Emcas Lisp data. No need to use database, but I recommend it strongly. You can define a hash: - key is UUID of Org object - value is UUID of Org related object with description (setq my-hash (let ((hash (make-hash-table :test #'equal))) (puthash "2a1d54b6-314f-4209-a096-cdbb1e71663c" (list "5c5d8f53-8f0b-4221-92a5-53f908df557b" "My description") hash) (puthash "06b1bd6a-c891-4fc8-9214-08586876f969" (list "5796dfd7-6369-45c1-868a-126d563a219c" "My description") hash) hash)) ➜ #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("2a1d54b6-314f-4209-a096-cdbb1e71663c" ("5c5d8f53-8f0b-4221-92a5-53f908df557b" "My description") "06b1bd6a-c891-4fc8-9214-08586876f969" ("5796dfd7-6369-45c1-868a-126d563a219c" "My description"))) Verify: my-hash ➜ #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("2a1d54b6-314f-4209-a096-cdbb1e71663c" ("5c5d8f53-8f0b-4221-92a5-53f908df557b" "My description") "06b1bd6a-c891-4fc8-9214-08586876f969" ("5796dfd7-6369-45c1-868a-126d563a219c" "My description"))) Store hash: (defun data-to-file (data file) "PRIN1 Emacs Lisp DATA to FILE" (string-to-file-force (prin1-to-string data) file)) (data-to-file my-hash "~/my.hash") ➜ "~/my.hash" Load hash next time: (defun data-from-file (file) "Reads and returns Emacs Lisp data from FILE" (condition-case nil (car (read-from-string (file-to-string file))) (error nil))) (setq my-hash (data-from-file "~/my.hash")) ➜ #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("2a1d54b6-314f-4209-a096-cdbb1e71663c" ("5c5d8f53-8f0b-4221-92a5-53f908df557b" "My description") "06b1bd6a-c891-4fc8-9214-08586876f969" ("5796dfd7-6369-45c1-868a-126d563a219c" "My description"))) Verify: my-hash ➜ #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("2a1d54b6-314f-4209-a096-cdbb1e71663c" ("5c5d8f53-8f0b-4221-92a5-53f908df557b" "My description") "06b1bd6a-c891-4fc8-9214-08586876f969" ("5796dfd7-6369-45c1-868a-126d563a219c" "My description"))) Continue using the hash for relationships between objects. Query hash keys to find all relationships. > In summary, I have several questions: > - is my idea bad? If yes, why ? Excellent idea. That is how it should be. Org author did not go that deep at time of authoring it, it is obvious that it is useful. Fact is that objects are related to other objects and people as objects. Org does not have built-ins for that and I would not do ask for it. It is good making external package. > - I'm sure some people have already thought about what I've done. Is > there an implementation already done ? In my RCD Notes & Hyperscope for Emacs yes, but that is not Org. It is meta level system, and Dynamic Knowledge Repository. About Dynamic Knowledge Repositories (DKR): https://www.dougengelbart.org/content/view/190/163/ > - How to make this implementation without modifying org-mode, but only > org-roam? Overwritten functions with modified functions? Like with this > example: (org-link-set-parameters "id" :follow #'org-roam-id-open), where > org-roam-id-open is defined in org-roam. If you need that in Org Roam, then you have to add to Org Roam. But if you need that function separately from Org Roam then implementing it by using database or hash stored as file is really not much work. I suggest using the built-in SQLite for start. > - is there another solution to my main problem: making my notes > - queryable? My "notes" are just one type of the elementary object. Not everything is really a "note" by definition. Some objects are "documents", there are subtypes, etc. Too many intersections. The more intersections there are defined, the better! Implement and forget about it. You will thank yourself later. All my "notes", which I call Hyperdocuments I can query or find by various means. The time shows what is most useful. It would depend on users' needs and habits. hyperscope-by-action-status-list hyperscope-by-author Above is clear. hyperscope-by-column (C-c h C) Above is interesting, it searches by some of allowed columns in database. 12 possible completions: hyobjects_arguments hyobjects_authorname hyobjects_description hyobjects_internal hyobjects_keywords hyobjects_link hyobjects_name hyobjects_report hyobjects_slug hyobjects_text hyobjects_tmpdoc hyobjects_wrsogimage hyperscope-by-date-created hyperscope-by-hyperdocument-type Types could be defined by user. There are many, depends of the need. Look here at the combination of types, subtypes and markups: https://gnu.support/files/tmp/2023-02-14/hyperscope-types-subtypes-markups.html hyperscope-by-internal (C-c h I) The above search by using internal report, something not for public. hyperscope-by-language (C-c h G) Finally, links and objects can be in any language, there is one "Contact us in German" and "Contact us in English", it is not same, right? hyperscope-by-markup Searching by markup is not necessary in Org, but Org does not have expressive markup. There are many issues to it. How about this one, which can be converted to anything by using pandoc: jgm/djot: A light markup language: https://github.com/jgm/djot I can mix markups in single document, this is for reason that I use the: TECHNOLOGY TEMPLATE PROJECT OHS Framework : https://www.dougengelbart.org/content/view/110/460/ My objects are separate from single document, and yet I can move them to Org in blaze, and come back to them. hyperscope-by-name (C-c h n) That is maybe what you need. I have also principle of a "Set": - I can enter into Set, that is equivalent to subtree in Org - An Hyperdocument can have "Hyperscope ID" type, this means it is just pointer or symbolic link to other type, let us say 123 - This means in a subtree I can have new or usually same name for the other Hyperdocument. - That means I can sort in a Set or subtree any kind of Hyperdocuments that already exists, or new ones. - as long as I keep making that order, I can edit single object, and such will be propagages automatically to other sets. Change one heading in project ABC, and it will be changed in project XYZ automatically. I think this principle of using sets you could use too to get the types, or subtypes of objects you need. I do not know if one can "mark" headings in Org, but that would be great. I am using marking of objects, I can search for example by tags, or somehow, then I mark, let us say music: C-h n blues brothers RET I get this list: 76601 Blues Brothers List ID List Media Play List 74823 Think by Blues Brothers Audio Music 74830 Gimme Some Lovin' by Blues Brothers Audio Music 74824 Theme From Rawhide by Blues Brothers Audio Music 74828 Peter Gunn Theme by Blues Brothers Audio Music 74825 Sweet Home Chicago by Blues Brothers Audio Music 74829 Shake A Tail Feather by Blues Brothers Audio Music 74826 Jailhouse Rock by Blues Brothers Audio Music 74821 She Caught The Katy by Blues Brothers Audio Music 74827 Minnie The Moocher by Blues Brothers Audio Music 74822 Everybody Needs Somebody To Love by Blues Brothers Audio Music 74831 The Old Landmark by Blues Brothers Audio Music 76267 The Blues Brothers: 11 Behind-The-Scenes Facts About The John Belushi Movie | Cinemablend WWW Default 76453 The Blues Brothers (1980) 📁 Directory Default But then I do not need that directory, maybe I want only three songs, so I mark them: ⇉74823 Think by Blues Brothers Audio Music ⇉74828 Peter Gunn Theme by Blues Brothers Audio Music ⇉74826 Jailhouse Rock by Blues Brothers Audio Music And invoke creation of new Hyperdocument by using those marked items: M-x hyperscope-add-new-id-list-hyperdocument RET Then I get something similar to this: 76601 Blues Brothers List ID List Media Play List I can then "run" or activate it by "l" (left like in Vim, action forward), and I would hear those 3 songs. While that music is playing, I can show how simple is that function: (defun hyperscope-id-list-action (id) (cond ((= (hyperscope-type id) 4) (cond ((= (hyperscope-subtype id) 69) (hyperscope-id-list-play-media id)) (t (rcd-warning-message "Did not find action for subtype `%s'" )))) (t (rcd-warning-message "Hyperdocument is no ID list.")))) (defun hyperscope-id-list-play-media (id) (let* ((id-list (hyperscope-global-marked-items-from-hyperdocument-1 id)) (id-list (mapcar (lambda (id) (let ((file (hyperscope-link-value id))) (cond ((file-exists-p file) (hyperscope-increase-rank id) file) (t nil)))) id-list)) (media (delq nil id-list))) (mapc (lambda (file) (call-process "vlc" nil nil nil file)) media))) So how are you going to relate hyperdocuments to each other? By using hand? Manually? I would prefer by telling to Org by speaking: - Relate this heading to "My other heading" but Org does not understand human voice. What a pity. I would put cursor in a heading and make function to select one among other headings, each having UUID, if not, I would place it there. Then I would store relationship of present UUID for present heading where cursors is, to the selected one, and I would automatically name it, or with prefix C-u I would ask user to name it. hyperscope-by-people-list There are people, we are people, isn't that what matters? We make notes for people. "People list" is not individual, it is multiple of people, or company, government department, etc. Searching Headings by people lists is useful hyperscope-by-related-contact Any contacts can be related, why not search for it? hyperscope-by-report Object can be task, task is assigned to person Joe, by author Hans, and has to be reported to Jimmy, there is description, text and report, and chunked reports. Searching by report is very important. hyperscope-by-slug (C-c h J) Those things for Internet. I use it more often. Why not search for "scribd.com" when I need it. By the way, I made the scribd.com type of links to be opened by "Scribd Downloadere" if user wants. hyperscope-by-tag (C-c h t) This I use often. hyperscope-by-text That is clear. hyperscope-by-type-and-column For example, you want Music by author, directory by name, or Gnumeric spreadsheet by report. Combinations in searching will help user to get better intersection results. hyperscope-by-type-with-action How about "Task COMPLETED", or "Music PENDING" hyperscope-hyperdocuments-by-action hyperscope-hyperdocuments-by-size hyperscope-hyperdocuments-by-timestamp Timestamps are other sub-objects, each can have description, activity, etc. 10 possible completions: ACTION [5] ACTION-REMOVED [7] CLOCK-IN [3] CLOCK-OUT [4] COMPLETED [6] DEADLINE [2] FOLLOW-UP [11] MEANWHILE [12] RE-ASSIGNED [13] SCHEDULED [1] hyperscope-list-by-contact All objects by contact hyperscope-tags-by-type There are different tag types, one is for industry, other is for skills, is not same all in one. hyperscope-by-argument Arguments I use flexibly as they depend on the type, subtype. Imagine those search engines, like the first one most important one: 78835 The Pirate Bay Web Server Query Default 78669 Duck Duck Go! Web Server Query Default 78675 Reasonator Web Server Query Default 78673 Wikipedia (English) Web Server Query Default 78674 Wikinews (English) Web Server Query Default Then there is argument: https://thepiratebay.org/search.php?q=%s&all=on&search=Pirate+Search&page=0&orderby= which is in this case Emacs Lisp format which will be replaced with the query. In fact when I place that link in Org, when I wish to click on it, I am asked for query, search engine opens automatically on it. But in "Hyperscope ID" type, there will be just integer like 123 pointing to other Hyperdocument. hyperscope-by-author-name Clear. hyperscope-by-country Yes, objects are related to countries, very necessary. hyperscope-by-description (C-c h D) Description is just one part of text properties of object. hyperscope-by-hyperdocument-subtype hyperscope-by-hyperlink-type hyperscope-by-keywords That is for Website Revision System keywords, for HTML pages mostly. hyperscope-by-link (C-c h k) Very often used to find by link. Implement yourself. hyperscope-by-markup-and-column You want maybe Asciidoctor by name, or Org markup by description? hyperscope-by-people-id Searching by ID of people. hyperscope-by-rank Show those most activated documents first. hyperscope-by-relation-type hyperscope-by-set (C-c h E) Sets have their names, that is like subtree heading, easier to find those who are true heading of subtrees, not all are. hyperscope-by-subtype (C-c h B) hyperscope-by-temporary-document There are "temporary" documents, like PDF file can have extract of text in that property, and why not search for text from PDF file? It is logical. But temporary document may look ugly. However, searching through PDF files would be more difficult directly. hyperscope-by-type (C-c h T) hyperscope-by-type-and-subtype Combine types and subtypes, that is probably what you need. hyperscope-by-wrsogimage HTML pages on Internet have schema, so those images that appear as preview are there. hyperscope-follow-ups-by-persons-country You are to see list of objects related to people, in different countries. hyperscope-hyperdocuments-by-query-but-not-in-set General search, just exclude the set! hyperscope-hyperdocuments-by-template Objects may use templates for their representations, find those using ABC template. hyperscope-hyperdocuments-pending-by-assignee Too many tasks pending by assignee, so find those pending. I hope that gave you ideas for implementation of new package of Org relationships. > - Some people often have subjects related to this type of question > (I think in particular of a certain "Jean Louis"): have you found > better solutions? I did not read that until I came to it, but thanks. I need relationships between documents. That is a must: - if page is published, and related hyperdocuments are also "publishable" they are shown in export on the HTML page or PDF page, etc. No thinking about it. - if page is duplicated from previous Hyperdocument, that new one automatically become "CHILD", thus related to previous one. It also includes relationships to various other "properties" or "attributes". The more, the better. Doing that in Org directly is overkill. But using UUID and putting relationships on that UUID may be practically implemented within minutes. If user is Org centric, and needs various properties not otherwise implemented in Org, then using UUID can provide such feature easy, and then you can also search between documents. You can for example, update Org heading, and later just have function updating all names of headings to their corresponding UUID in the database. I would stick to only this: * My heading :PROPERTIES: :UUID: 282f7242-a3b1-4bd6-94b6-7283303ae7ed :END: And I was exploring option to make it invisible. That way, user can edit that heading, and because of relationship to database or stored hash database or other type, any kind of properties can be stored. The more various types of properties are there, the easier will be the query in future. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/