Navigate Workspace Headers

Goal: Make editing multi-draft documents or even novels simple by creating an outline based on headers. It would be like creating the Scrivener binder on-the-fly. And being able to jump to a header in any draft.

I’m currently at the point where all drafts within a workspace are searched and the headers added to a prompt.

Problem: How to include the draft object, to which the selected header belongs, inside the prompt?

The script needs to switch to the draft the selected header is located in, and then go to the header within that draft.

EDIT: The only thing I can think of is to store the UUID and header text, then set an index on the prompt button to look up the stored UUID. But maybe someone with more experience can think of a simpler way to do this?

// original script by Tim Nahumck

//present lines in prompt
var p = Prompt.create();
p.title = "Choose Header";
p.addButton("Home");

let ws = Workspace.find("My Workspace");
app.applyWorkspace(ws);

var draftArray = ws.query("all");

for (j = 0; j < draftArray.length; j++) {

// Get the draft content
var d = draftArray[j].content;
var selRange = editor.getSelectedRange();

//grab lines that start with # in any number
var headers = d.match(/#+?\s.*/gi)

if (headers.length > 0) {
 for (i = 0; i < headers.length; i++) {
 p.addButton(headers[i]);
 }
}

} // end workspace loop

p.addButton("End");
var con = p.show();


if (con) {
  if (p.buttonPressed == "Home") {
    editor.setSelectedRange(0,0);
  }
  else {
    if (p.buttonPressed == "End") {
      editor.setSelectedRange(d.length,0);
    }
    else {
      var header = p.buttonPressed;
      var position = d.search(header);
      editor.setSelectedRange(position+header.length,0)
    }
  }
  editor.focus();
}
else {
  context.cancel();
}

Can you say more about what the term “header” refers to?

(I’m not familiar with it as a Drafts term.)

Thanks!

I mean markdown headers. There is an existing action called navigate draft which creates a list of links inside a prompt. You can jump to each markdown header, plus the top and bottom (home/end) of the draft.

If we can expand this to an entire workspace, we are creating an outline across multiple drafts similar to apps like Ulysses and Scrivener. This makes it possible to work on long articles and books using Drafts.

Set workspace sorting for Inbox/All to “text”, ascending. Then use a chapter number as the first word in your title.

I can explain more about how I think it can all work together once the action is working. It’s quite exciting imagining the possibilities. Drafts would keep things as simple as Ulysses, but also give you a huge amount of flexibility with its actions.

1 Like

You’ll need to store the keyed data outside of your prompt(s), but you could the build a prompt from that.

You could certainly use a pair of arrays where the index in each is synchronised, which I think is the gist of your edit in the original post.

While you could use a JSON structure to hold it all, I suspect things are the wrong way around for that as the headers may not be unique and the UUID is probably the value you want.

1 Like

I figured it out. Of course there were a few more tricky bits along the way.

Is there a way to get the current workspace, or does the workspace need to be named? I’m currently doing it like this:

let ws = Workspace.find("My Workspace");

app.applyWorkspace(ws);

That keeps coming up…

You need to manually specify it currently :frowning:

Thanks for that. I’ll add this action as a use case in the other thread.

Did you publish this action in the directory? I went looking and my searches did not find anything.

That would only work as an action if you happened to have a workspace named “My Workspace”. What is it you want to do?


As an aside, it is now possible to determine the current workspace:

alert("You currently have this workspace loaded: " + app.currentWorkspace.name);