notesy::links

Opening a web page in the browser, or a mail address in the mail app, which takes links.open; and naming links to the plugin's own sites after their pages, which takes nothing more than naming those sites in its [net].

rustuse notesy::{commands, links};

pub fn ready() {
    commands::add("help", "Tasks help", |command| links::open("https://example.com/tasks/help"));
}
Function What it does Takes
links::open(url) Opens url: an https:// or http:// page, or a mailto: address. Anything else (a file, another app's own scheme) is an error. links.open
links::on_title(handler) handler(id, url) when a link to one of its sites is to be named after its page. [net]
links::title(id, name) Names the link asked about as id: name's first line, at most 200 characters. [net]
links::no_title(id) It has no name for that link: notesy fetches the page's title itself. [net]

#Opening pages

Opening a page is the user's browser going there, not the plugin: a script reaches the network only through notesy::net, and only to the sites in its [net]. notesy checks the plugin's permission again for each call.

A page's address can carry what the plugin read, though, so links.open is shown in red, and the prompt warns when the plugin can also read what's yours. In a preview, links are held back unless it's run with --trust.

A web address pasted on its own into a note becomes a link named after its page, [title](address), when "Titles for pasted links" is on; so does one picked with "Add the page's title", and every bare one in a note with "Name links after their pages". notesy fetches a page's title itself, but only a public page's: one behind a sign-in gives the sign-in page's. A plugin can name links to its own sites instead, from what it knows of them or asks of their API, with its accounts:

rustuse notesy::{json, links, net};

pub fn ready() {
    links::on_title(|id, url| {
        if !url.contains("/browse/") {
            links::no_title(id);
            return;
        }
        net::fetch(#{ url: issue_api(url), account: "tracker" }, |response| {
            match response {
                Ok(r) if r.ok => links::title(id, summary_of(r.text)),
                _ => links::no_title(id),
            }
        });
    });
}

/// The tracker's API address for an issue's page.
fn issue_api(url) {
    url.replace("/browse/", "/rest/api/2/issue/")
}

/// "PROJ-1: Fix the login", from the issue as JSON; nothing when it isn't.
fn summary_of(text) {
    match json::parse(text) {
        Ok(issue) => `${issue.key}: ${issue.fields.summary}`,
        Err(_) => "",
    }
}
  • A plugin is asked only about links to the sites in its [net], never shown any other address. When more than one names a site, the first to start is asked.
  • It answers with links::title or links::no_title, at once or once it knows, within 10 seconds. After that, or with no_title, notesy fetches the page's title itself, and a late answer is let go.
  • The name is written as the link's text, its brackets escaped; the address is kept as it was. An empty name is no name, as no_title.

Every page