DocServer Lookup

// DocServer Lookup
  This Drumkit makes it easier to look up verbs in DocServer.
  Created by Gary Teter
  This is the third version, updated with a note, in case anyone opens this file.
  // Please note, extremely important
    I do not believe that opening someone's opml file and copy-pasting stuff into your menu bar or icon bar is something which is safe to do.
    Do not do this thing. I suspect, but am not sure, that it is probably possible to sneak bad stuff into your Drummer environment this way.
    The main vector I am thinking is, weird stuff in opml attributes or some such.
    I assure you, I am not doing this with this file. I haven't inspected all the nodes, but whatever is there is from Drummer.
    I have no idea if this is even remotely possible, I have no insight into Drummer's internals. But I think, if Dave thought he had a good way figured out for people to distribute Drumkit scripts, we'd know about it.
    So the instructions are mostly for myself, these are personal utilities for my own use for now. And I like pretending this is a real thing, it is literally like cosplay, it relaxes me. I also put together my own stereo equipment, from kits. Someday I will write up their instruction manuals, as if they were from a real company.
    I am leaving this file public, with this edit, because it is referenced in some issues on GitHub, and taking it down would be rude.
    I may update this file as I make new versions of this script, but please do not confuse this with anything resembling any sort of a software release process. You can't tell if I've changed it when you weren't looking. When I update this file with version three, version two will be gone. There will be no history. This is no way to release code, of course. I am just trying to state the obvious, so everybody knows it is obvious. I am pretty sure that particular formulation is from an editorial Ted Nelson wrote back when he was editor of Creative Computing.
    For my own use, I will be make some tools that let me whitelist attributes by node type and whatnot. This is something I want to apply to any updates I put into this node, just to ensure I don't accidentally put stupid shit into someone else's Drummer environment. This is different from how I'd approach this if I were writing an opml-aware application. In that case, you absolutely want to just ignore what you don't understand. This is basic Postel stuff. What I'm talking about is something the user (me) applies, by choice, not because I'm trying enforce my will on other companies, as we've seen people like Microsoft do time and again. This is just the way organizations get in those situations, it is basic stupidy theory.
  // How to use this
    Select some text, and click the icon.
    If you don't select any text, we will look at the current node for anything that looks like it might be a Drumkit verb.
    If we can't find anything, you can type the verb into a dialog box.
    If we think we've found a Drumkit verb, we'll open DocServer.
  // How to install this
    Select this entire outline, i.e., the above "// DocServer Lookup" node that contains all this
    Copy it (cmd-C)
    File → Special Files... → Iconbar...
    Add a new node called question
    Paste this outline under that node (cmd-V)
    There should be a new question mark in your icon bar
  // Here is the code
    EnsureDrumkitVerbCache()
    const selection = GetSelectedText()
    const cleaned = CleanText( selection )
    var verb = ExtractDrumkitVerb( cleaned )
    ScrollLog() // just for the iPad console
    if ( verb == undefined ) {
      verb = dialog.ask( "DocServer Lookup", verb, "string.multipleReplaceAll" )
      }
    if ( verb != "" && verb != undefined) {
      webBrowser.openUrl ("http://docserver.scripting.com/?verb=" + verb)
        currently broken on the ipad
        I think the URL is ok but docserver just shows empty contents
      tab.openInstantOutline( "http://drummer.scripting.com/davewiner/verbDocs.opml", "Drumkit Verbs" )
        This doesn't work as I'd hoped, ideally we could switch to the tab, find the right heading and expand it
        But I don't think the op verbs refer to the newly-opened tab
      }
    // Functions
      // Ensure Drumkit verb cache
        // Ensure caches
          function EnsureDrumkitVerbCache() {
            if (root.temp == undefined) { root.temp = new Object() }
            if (root.temp.drumkit == undefined) { root.temp.drumkit = new Object() }
            if (root.temp.drumkit.verbs == undefined) {
              root.temp.drumkit.verbs = []
              ensureDrumkitVerbs()
              }
            }
        // Ensure Drumkit verbs
          function ensureDrumkitVerbs() {
            add( base64, "base64" )
            add( clock, "clock" )
            add( date, "date" )
            add( dialog, "dialog" )
            add( dns, "dns" )
            add( drummer, "drummer" )
            add( file, "file" )
            add( github, "github" )
            add( http, "http" )
            add( oldSchool, "oldSchool" )
            add( op, "op" )
            add( opml, "opml" )
            add( rss, "rss " )
            add( speaker, "speaker" )
            add( string, "string" )
            add( tab, "tab" )
            add( twitter, "twitter" )
            add( webBrowser, "webBrowser" )
            }
        // Add verbs for Drumkit category
          function add( category, name ) {
            for (verb in category) {
              const v = string.replaceAll(name + "." + verb, " ", "")
              root.temp.drumkit.verbs.push( v )
              }
            }
      // Input and validation
        // Get the selected text
          function GetSelectedText() {
            var term = op.getSelectedText()
            if ( term == "" ) {
              term = op.getLineText()
              }
            return term
            }
        // Clean up the selection
          function CleanText( term ) {
            if (term != "") {
              term = string.stripMarkup( term )
              term = string.multipleReplaceAll( term, {
                "(" : " ",
                ")" : " ",
                ";" : " ",
                "{" : " ",
                "}" : " ",
                "+" : " ",
                "-" : " ",
                "?" : " ",
                "/" : " ",
                "\"" : " ",
                "=" : " ",
                })
              term = string.multipleReplaceAll( term, {
                " " : " ",
                " " : " ",
                })
              term = string.trimWhitespace( term )
              }
            return term
            }
        // Ensure it's a known Drumkit verb
          function ExtractDrumkitVerb( term ) {
            const num_fields = string.countFields(term, " ")
              for ( var i = num_fields; i > 0; i-- ) {
                const s = string.nthField(term, " ", i)
                for ( var j in root.temp.drumkit.verbs ) {
                const verb = root.temp.drumkit.verbs[ j ]
                if ( s == verb || string.upper(s) == string.upper(verb) ) {
                return verb
                }
                }
                }
            return null
            }
      // Utility
        // Scroll console log so we can see it on the iPad
          function ScrollLog() {
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            console.log( "log" )
            }