Action

New draft from selection/line with back-link

Posted by @jsamlarose, Last update 4 months ago

WHAT

This action creates a new draft from selected text with appropriate back links in the new and source drafts. You can specify a title to be used for the new draft and corresponding back-link by placing ((double brackets)) around an appropriate title within the selected text. If no title is specified within the block of text, the action prompts for a title.

If you have selected text, that selected text will be replaced with a back-link. If you don’t select any text, the text of the current line will be used to create a new draft, and the back-link will be appended to that line in the source draft (rather than replacing it).

WHY

“If your notes are too broad, you might not notice when you encounter some new idea about one of the notions contained within, and links to that note will be muddied. If your notes are too fragmented, you’ll also fragment your link network, which may make it harder to see certain connections.”
—Andy Matuschak, Evergreen notes should be atomic
https://notes.andymatuschak.org/Evergreen_notes_should_be_atomic

I can see the wisdom of atomic notes, but I don’t think in atoms. For me, atomic notes emerge from free-flow thought (or other note-making). This action allows me to write expansively as ideas occur and extract emerging ideas after the fact, while retaining some sense of how those ideas emerged and where they came from.

Steps

  • script

    // save a version to protect against errors
    
      draft.saveVersion()
    
    // note on grammar: I'm thinking of new drafts as "blocks" (with Roam's block referencing in mind...), hence 
      
      let blockID = new Date().toString("yyyyMMdd-HHmmss")
      let backlink = "[[" + draft.displayTitle + "]]"
      let blockTitle
      let block
    
      if (editor.getSelectedText().length>1) { // set block to selected text
        block = editor.getSelectedText() 
        shim = ""
      
      } else { // set block to line
       
        var lr = editor.getSelectedLineRange()
        editor.setSelectedRange(lr[0],lr[1])
        block = editor.getTextInRange(lr[0],lr[1])
        shim = "\n"
      }
            
      if (block.includes("((")) { // use double bracketed text to capture title
        
        var myRegexp = /\(\((.*)\)\)/g;
        var match = myRegexp.exec(editor.getSelectedText());
        blockTitle = blockID + " | " + match[1]
    
    // uncomment the following if you want to remove your ((titles)) from your blocks
        
        // block = block.replace(match[0],"")
        
      } else { // prompt for a title where one hasn't been set
      
        var p = Prompt.create();
        p.title = "Add a title for this block";
        p.addTextField("noteTitle", "title:", "");
        p.addButton("continue");
        var didSelect = p.show();
        var noteTitle = p.fieldValues["noteTitle"];
        if (p.buttonPressed == "continue") {
           blockTitle = blockID + " | " + noteTitle
        }
      }
    
    // replace block with link...
      
      editor.setSelectedText(" [[" + blockTitle + "]]" + shim)
    
    // note: to protect the above link definition against the possibility of editing block titles at a later date, we could form this back-link as "(title)[[blockID]]"— i.e. the "title" in brackets with a wiki-link based on a timestamp beside it. In the new draft, as long as no other draft contains that timestamp in the title, it'll match. However, if you want to be compatible with Obsidian/Logseq/Foam or Roam-likes you might export these notes to, match your titles strictly— set blockTitle = blockID, place noteTitle as second line of new draft. Of course, this will also have an impact if you expect to be able to search for text strings in titles, but as Andy says: "There’s no clear litmus test or correct answer here—just a bunch of tradeoffs."  
    
    // next, create new draft from block
    
      let d = Draft.create();
      d.content = "# " + blockTitle + "\n" + backlink + "\n\n"
      if (typeof block !== 'undefined') { d.content = d.content + block}
      d.update();
      editor.load(d);
    

Options

  • After Success Default
    Notification Error
    Log Level Error
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.