DITA and XMetaL Discussion

XMetaL Community Forum DITA and XMetaL Discussion Sort topicrefs alphabetically by topic title

  • Susan_C_1

    Sort topicrefs alphabetically by topic title

    Participants 1
    Replies 2
    Last Activity 9 years, 3 months ago


    Is there a way to sort topics alphabetically by title? We'd like to create a map that has all of our procedures in alphabetical order by title. Is there a macro or script to do this? We could do it manually, but it seems like it could be done programmatically. Any recommendations? Has anyone else done something like this?



    Derek Read

    Reply to: Sort topicrefs alphabetically by topic title

    There is no built-in functionality that will do this for you for a DITA map. In XMetaL Author 8.0 (Enterprise and Essential) we've added sorting for HTML and CALS tables as well as elements that have been customized for a particular DTD to be treated as a list, but that won't help here.

    You are correct that this should be possible to do programmatically. I can add it to my to-do list as it sounds like an interesting challenge, but maybe someone else would want to give it a try as I really don't know if I have time for this at the moment.

    If the portion of your map that you wish to sort is anything more than just a series of elements, without nesting, that would probably make things a lot harder. If it is then I think we'd want to see a sample and a description of what you expect the behaviour to be (especially for the nested parts).


    Derek Read

    Reply to: Sort topicrefs alphabetically by topic title

    I've come up with the following script (based on something I originally created for [url=http://forums.xmetal.com/index.php/topic,458]sorting tables[/url] that is now obsolete).

    It has not been coded to be very robust (at least I did not think about it much while coding) but it handles the two basic test cases I've tried:
     a) Sort a selection of elements that are all siblings.
     b) Sort a selection of sibling
    elements with child elements. I believe it sorts as one would expect in this case: elements at the same “nesting level” are sorted against each other and not against their children (or parents).

    You need to create a selection containing elements before you run the script.
    Sorting is performed on the value of the @navtitle for each
    so that attribute must be set. You may wish to try running “Refresh References (F11)” to have the @navtitle set if you see some elements being sorted out of order.

    There are bound to be some cases where it might fail for more complex structures than the two listed above.

    Use this at your own risk and only with test content until you are satisfied it works for you.

    I have only done absolute minimum testing on this and there are probably lots of potential use cases I have not thought of, which is why I'm providing the plain script code and not an MCR file. You will need to know enough about implementing an XMetaL macro to use this (a Startup macro would be good enough for most cases).

    This example could easily be altered to enable sorting for other types of elements than requested by the OP (Susan_C_1). It could also be made more foolproof or more automated depending on your exact needs. I leave it up to you to decide the macro name, whether it gets a shortcut key, whether you wish to allow users to run it from the context menu, etc.

    I've also left in a bunch of Alerts to show the state of the unsorted vs sorted XML so you'd want to comment those out for a distributed version.

    [code]//XMetaL Script Language JScript:
    function derekread_DemoExtension_sortTopicrefs() {
    var rng = ActiveDocument.Range;
    if(!rng.IsInsertionPoint) {
    //wrap string with a root element (need a single root node) for MSXML
    var selectionStr = “” + rng.TextWithRM + ““;

    //Build XSLT ——————————————————— START
    var xsltStr = 'n';
    xsltStr += 'n';
    xsltStr += 'n';

    xsltStr += 'n';
    xsltStr += ' n';
    xsltStr += ' n';
    xsltStr += '
    xsltStr += '

    xsltStr += 'n';
    xsltStr += ' n';
    xsltStr += ' n';
    xsltStr += ' n';
    xsltStr += '
    xsltStr += '
    xsltStr += '

    xsltStr += 'n';
    //Build XSLT ———————————————————– END

    // Load the XML string into MSXML
    try {
    xmlDoc = new ActiveXObject(“Msxml2.DOMDocument.4.0”);
    xmlDoc.async = false;

    // Load XSL file into MSXML
    xslDoc = new ActiveXObject(“Msxml2.FreeThreadedDOMDocument.4.0”);
    xslDoc.async = false;
    if (xslDoc.parseError.errorCode != 0) {
    var xsltErr = xslDoc.parseError;
      Application.Alert(“XSLT load error during table sort: ” + xsltErr.reason);
    else {
    // Set up for the XSLTransform
    xslTpl = new ActiveXObject(“Msxml2.XSLTemplate.4.0”);
    xslTpl.stylesheet = xslDoc;
    xslProc = xslTpl.createProcessor();
    xslProc.input = xmlDoc;

    //Run the transform

    //Get the output after the transform
    var sortedStr = xslProc.output;
    //remove “derektemp” root node wrapper element
    sortedStr = sortedStr.substring(11,sortedStr.length – 12);
    xmlDoc = null;
    catch(e) {
    var msg = “An error with this script has occurred. It might “;
    msg += “have something to do with MSXML or the MSXML version but it “;
    msg += “could also easily have something to do with the selection. “;
    msg += “No checking is done in that regard.nnScript Error: ” + e.description;


  • You must be logged in to reply to this topic.

Lost Your Password?