$NewFile script {new file types - create, and inline-edit title}

Example usage

Label: "Tsl source (.tsl) &File\tCtrl-N,Ctrl-T"
Tip: "Create a new, empty tsl source (.tsl) file"
Hotkey: Ctrl + N, Ctrl + T
Function: $NewFile FILENAME=Untitled.tsl

Note: I've been meaning to start pulling things from my libraries and contribute to the community (too busy). I love DOpus, it's the "bomb". In any case here is a basic, but useful, script sample I built a few years ago which I use all the time.

$NewFile.AddIn.DOpus.zip (3.0 KB)

p.s., I wish I could just click "explore xml-conf" at any point in the DOpus edit-mode to copy buttons etc from %AppData%\GPSoftware\Directory Opus.

///////////////////////////////////
//  DOpus AddIn Script "$NewFile"
//  (c) Smallscript, 2015
///////////////////////////////////
var ScriptFileName = '$NewFile';

//{ Start Script Compilation
function OnScriptRecompiling() {
    //{ `$` support services
    if (typeof this.$ === 'undefined') {
        this.$ = {
            globals: this,

            //{ JS Polyfills
            'Function.prototype.bind': Function.prototype.bind = function () {
                var boundFn = this;
                var boundThis = arguments[0];
                var boundArgs = Array.prototype.slice.call(arguments, 1, arguments.length);
                return function () {
                    var newArgs = (boundArgs.length > 0)
                        ? ((arguments.length) ? boundArgs.slice(0, boundArgs.length).concat(arguments) : boundArgs)
                        : arguments;
                    return boundFn.apply(boundThis, newArgs);
                }
            },
            'Function.prototype.get_name': Function.prototype.get_name = function () {
                var source = this.toString(),
                    pre = 'function ',
                    preLen = pre.length,
                    preIndex = source.indexOf(pre),
                    nameEndIndex = source.indexOf('('),
                    nameStartIndex = preIndex + preLen,
                    nameLen = nameEndIndex - nameStartIndex
                ;
                return source.substr(nameStartIndex, nameLen);
            },
            //}

            //{ `console` support
            clear: function() {
                DOpus.ClearOutput();
            },
            log: function () {
                this.writeln.apply(this, arguments);
            },
            writeln: function () {
                for (var s = '', p = '', n = arguments.length, i = n, a; i ? (a = arguments[n - i], true) : false; --i)
                    s += p + a, p = ' ';
                return DOpus.Output(s);
            },
            //}

            //{ `JScript` support
            Version: function () {              // https://msdn.microsoft.com/en-us/library/s4esdbwz(v=vs.84).aspx
                return ScriptEngine() + ' ' + ScriptEngineMajorVersion() + '.' + ScriptEngineMinorVersion() + '.' + ScriptEngineBuildVersion();
            },
            GetObject: this.GetObject,          // https://msdn.microsoft.com/en-us/library/7tf9xwsc(v=vs.84).aspx
            ActiveXObject: this.ActiveXObject,  // https://msdn.microsoft.com/en-us/library/7sw4ddf8(v=vs.84).aspx
            Enumerator: this.Enumerator,        // https://msdn.microsoft.com/en-us/library/6ch9zb09(v=vs.84).aspx
            //}
        };
        if (typeof this.console === 'undefined')
            this.console = this.$;
        if (typeof this.$g === 'undefined')
            this.$g = this;

        if(typeof this.DOpusFactory === 'undefined')
            this.DOpusFactory = DOpus.Create;
        if (typeof this.Map === 'undefined')
            this.Map = function () { return DOpusFactory.Map.apply(DOpusFactory, arguments); };
    }
    //}

    //  Log entry/exit status for debugging
    console.clear();
    console.log('** Script "'+ScriptFileName+'" Compile Entered **');
}
function OnRestoreScriptVariables(args, initData) {
    console.log(' * ' + args.callee.get_name() + '() Entry *');
    if (typeof this.$script === 'undefined') {
        //console.log('Script type:', typeof this.Script);
        if (typeof this.Script === 'unknown' || typeof this.Script === 'undefined') {
            if (!initData) return;
            this.$script = {
                vars: initData.vars,
                config: initData.config,
                file: initData.file,
                InitColumns: function() {},
                InitCommands: function() {},
                RefreshColumn: function() {},
            };
        } else {
            this.$script = this.Script;
        }
    }
    if (typeof $script.file !== 'undefined') {
        $.scriptFilePathName = $script.file;
        $.scriptName = $.scriptFilePathName.split('\\').pop();
        //console.log('   >Script Filename: ' + $.scriptName);
        //console.log('   >Script Filename: ' + $.scriptFilePathName);
    }

    //{ Restore or initialize the configuration and its map
    var Config = $script.config;
    if (typeof Config !== 'undefined' && initData) {
        var ConfigMap = initData.config_desc;
        if (ConfigMap === undefined)
            initData.config_desc = ConfigMap = DOpusFactory.Map();

        console.log(' ^ Updating Config and ConfigMap');
        Config.EnableGlobalVariableTracking = true;
        ConfigMap.merge(DOpusFactory.Map('EnableGlobalVariableTracking', 'Use this to control whether the script logs available globals as it runs.'));
        Config.EnableDebugOutput = true;
        ConfigMap.merge(DOpusFactory.Map('EnableDebugOutput', 'Use this to control whether the script logs output about its run state.'));
        if (false) {
            //  This is not `legal` javascript!! (no l-value)
            ConfigMap('set') = function set(a, b) { this(a) = b; }.bind(ConfigMap);
            ConfigMap('set')('EnableGlobalVariableTracking', 'Use this to control whether the script logs available globals as it runs.');
        }
    }
    //}
}
OnScriptRecompiling();
//}

//{ DOpus Event Handlers
function OnInit(initData) {
    OnRestoreScriptVariables(arguments, initData);

    //{ Configure the AddIn based on its recorded state
    initData.name = ScriptFileName + '.AddIn.DOpus';
    initData.version = '1.0';
    initData.desc = 'A library of functions supporting $NewFile, ... in DOpus.';
    initData.copyright = 'Copyright Smallscript (c) 2015';
    initData.log_prefix = initData.name;
    //
    initData.default_enable = true;
    //}
}
function OnAboutScript() {
    OnRestoreScriptVariables(arguments);

    var dlg = DOpus.Dlg;
    dlg.window = DOpus.Listers(0);
    dlg.icon = 'Info';
    dlg.title = 'Script: "' + $.scriptName + '"';
    dlg.message = $.scriptFilePathName;
    dlg.buttons = 'Ok';
    var ret = dlg.Show();
}
function OnAddCommands(addCmdData) {
    OnRestoreScriptVariables(arguments);

    var cmdName = '$NewFile';
    if (!DOpus.Create.Command.CommandList().Exists(cmdName)) {
        var cmd = addCmdData.AddCommand();
        cmd.name = cmdName;
        cmd.method = 'On' + cmdName;
        cmd.desc = 'A function to support `New File` creation in DOpus';
        cmd.label = 'Create New File';
        cmd.template = 'FileName/OR';
    }
}
function OnScriptConfigChange(configChangeData) {
    OnRestoreScriptVariables(arguments);
    /* 
        Added Script.RefreshColumn method that a script can use to cause any instances of one of its columns to be regenerated (e.g. in response to an OnScriptConfigChange notification). 
    */
}
//}

//{ Custom Event Handlers
function On$NewFile(scriptCmdData) {    // Reference > Scripting Reference > Scripting Objects > `ScriptCmdData`, `Func`
    OnRestoreScriptVariables(arguments);
    var args = scriptCmdData.func.args;
    var command = scriptCmdData.func.command;
    var sourcePath = command.source;

    // { Log Arguments
    if (false) {
        console.log('scriptCmdData.cmdline =', scriptCmdData.cmdline);
        console.log('scriptCmdData.func =', typeof scriptCmdData.func);
        console.log('scriptCmdData.func.args =', typeof scriptCmdData.func.args);       //  `Args`
        console.log('scriptCmdData.func.command =', typeof scriptCmdData.func.command); //  `Command`
        console.log('scriptCmdData.func.fromDrop =', scriptCmdData.func.fromDrop);
        console.log('scriptCmdData.func.fromKey =', scriptCmdData.func.fromKey);
        console.log('scriptCmdData.func.qualifiers =', scriptCmdData.func.qualifiers);
        console.log('scriptCmdData.func.sourcetab =', scriptCmdData.func.sourcetab);
        console.log('scriptCmdData.func.desttab =', scriptCmdData.func.desttab);
        var Dlg = scriptCmdData.func.Dlg; // Dialog function
        if (args.got_arg["filename"]) console.log('args["filename"] =', args["filename"]);
    }
    // }

    //{ Prepare local variables for operations
    //  Programming the FileSystemObject - https://msdn.microsoft.com/en-us/library/2z9ffy99(v=vs.84).aspx
    var fso = new ActiveXObject('Scripting.FileSystemObject'),
        filename = ((args.got_arg['filename']) ? args['filename'] : 'untitled'),
        ext = '.' + fso.GetExtensionName(filename),
        name = filename.substr(0, filename.length - ext.length),
        index = null,
        suffix = '',
        success = true,
        filepath,
        result;
    //}

    //{ Search for an unused filename
    do {
        filename = name + suffix + ext;
        filepath = fso.BuildPath(sourcePath, filename);
        if (fso.FileExists(filepath)) {
            index = (index === null) ? 0 : index + 1;
            suffix = '-' + index;
        } else {
            break;
        }
    } while (true);
    //}

    //{ Attempt to create it
    try {
        fso.CreateTextFile(filepath, false);
        result = 'Success: File "' + filename + '" created = ' + fso.FileExists(filepath);
    } catch (error) {
        success = false;
        result = error;
    }
    console.log(result);
    //}

    //{ Attempt to select it now and set up for inline rename
    if (success) {
        command.Clear();
        command.AddLine('SELECT "' + filename + '" EXACT SETFOCUS');
        command.AddLine('RENAME INLINE=NAME');
        command.Run();
        console.log('Command.results:', command.results.result);
    }
    //}

    return result;
}
//}

//{ End Script Compilation
console.log('** Script "' + ScriptFileName + '" Compile Exit **');
//}
1 Like

Does the script do more than what a built-in command like this does?

FileType NEW=.txt NEWNAME="Untitled.tsl"

That will create a new empty file called "Untitled.tsl" and let you type a new name for it.

If the script does more, it might be worth detailing some of what it does and reasons to use it instead of the more simple built-in command.

(For the built-in command, there's more detail at How to Create New/Empty Files.)

When in Customize mode, you can drag buttons or menus to a folder to create XML versions of them for sharing as files, or right-click them and use Copy to create XML versions of them in the clipboard for sharing as text. Both can be dragged or pasted back to the toolbars in a similar way.

Ahh, yes.

It was written in 2015 when the first scripting capabilities for DOpus were released and not much was available on how to write scripts and debug them, or use Javascript capabilities more generally.

What it does is provide a template with a lot of the mechanics included for debugging and writing a general plug-in, while illustrating some (at that time) difficult approaches to controlling the DOpus DOM to accomplish and control features like file-creation and name-editing in one sequence. It also, because it is a script, gives full control over runtime-customizing the default-name chosen.

I kept that contribution simple as possible. I actually use this to do more complex things like automatically generate a default knowledge base name and assign custom attributes to the file from within the script and register it with a database. Which, while not illustrated here, is what a script allows that the CLI does not quite as flexibly allow.

I am totally fine if you feel it is more of a developer category item, and want to move the topic to that section.

David

p.s., DOpus is "so" very rich - omg. Thank you for the tip on dragging to get the XML!
p.p.s., I am surprised that there is not a O'Reilly type of book for using DOpus!

1 Like