General XMetaL Discussion

  • mlatzig

    Styling custom PI’s

    Participants 2
    Replies 3
    Last Activity 12 years, 10 months ago

    Hi,
    Our company is a partner of JustSystems. For a customization on our side using XMAX I am analyzing the rendering features of the XMAX control.

    I played a little bit around with custom PIs and styling them with the CSS selector: $procins, regarding:

    [url=http://forums.xmetal.com/index.php/topic,24.0.html]http://forums.xmetal.com/index.php/topic,24.0.html[/url]

    I'm not so familar with CSS, but it is possible to show also a specific part of the data of a custom PI by such selector?
    If I have a PI like:

    • Is it possible to show only the content of msg=”…” inside the data of the PI?
    • Is it possible to hide the name of the target of such PI then?
    • Is it possible to show escpaped XML-code instead “this is a sample text”, like “<para>test123</para>” (our goal is to have a rendered PI, which is similar to a change-tracking PI )?

    Mario Latzig
    KGU-Consulting
    Germany

    Reply

    Derek Read

    Reply to: Styling custom PI’s

    I don't think you can do what you want to do using just CSS. Also, the Change Tracking PIs XMetaL supports are not really connected to CSS (you can't style every aspect of them like you can with other things) so there is no hope of hooking into that somehow.

    The closest to what you are asking for might be to try to use CSS:before or CSS:after pseudo-selectors, plus some generated content (using the CSS property “content”) — I suspect that is what you might be hoping for (ie: some magic CSS settings). Something like the following:

    $procins[xm-pi-target="mytarget"]:before {
    color: red;
    content: "test";
    }

    However, that isn't going to let you grab the DATA portion of the PI, nor will it allow you to suppress just the TARGET.

    What I think you might try is a script like the following that uses the SetRenderedContent API. This API has not been extensively tested for PI nodes (typical usage is to replace PCDATA). So, please test thoroughly before rolling out any solution based on this idea.

    This will not give you identical behavior to the Change Tracking PIs, but I think it might be as close as you can get. The most notable difference is that you cannot select content rendered this way merely by clicking on it, as you can with the Change Tracking PIs and there is no way to make the opening and closing PI tags go away using this technique.

    Steps:
    1. Create a macro containing code below.
    2. Open any document containing your own custom PI.
    3. Place your cursor (insertion point) anywhere inside the PI.
    4. Run the macro.

    [code]//XMetaL Script Language JSCRIPT:
    /*
    Create a Range object to work with the user's current selection,
    which is assumed to be inside a PI
    In your final version of this script you would probably skip this step
    and obtain a list of your PIs as nodes using other APIs, DOM, etc…
    */
    var rng = ActiveDocument.Range;

    //Change the selection to grab the entire PI…
    rng.SelectContainerContents();

    //Store the current node, which should equal the PI…
    var curNode = rng.ContainerNode;

    //Only continue if we're inside a PI, otherwise display an error…
    if (curNode.NodeType == 7) {
    //Store the text for the PI…
    var piAll = rng.Text;

    //Display current value of our string…
    Application.Alert(“Here's the entire PI, Target + Data:r” + piAll);

    //Store just the DATA portion from our string
    if (piAll.indexOf(” “) == -1) {
    /*oops, didn't find a space,
    so there cannot be a Data portion,
    insert something anyway…
    */
    var piData = “— NO PI DATA —“;
    }
    else {
    //DATA in a PI is everything after the first space…
    var piData = piAll.substr(piAll.indexOf(” “) + 1);
    }
    //Display the altered string, this equals the DATA portion…
    Application.Alert(“Here's just the Data from the PI:r” + piData);

    //Replace the text being rendered for the PI's node with the new string…
    ActiveDocument.SetRenderedContent(curNode,piData);
    }
    else {
    //User wasn't inside a PI, display error…
    Application.Alert(“To run this demo first put your cursor inside a PI.”);
    }[/code]

    You will need to create a number of scripts that walk your document to find your PIs and render new content for them during various events in order to make sure the rendered content is always replaced with what you want it to be. Most likely a document open event, an event for view switching (this rendered content will be lost when you move to PlainText view and back to TagsOn / Normal) and probably insertion of new PIs, possibly also including pasting.

    Reply

    Derek Read

    Reply to: Styling custom PI’s

    Another note about my code.

    A smarter way to grab PI data and target is to use DOM in this case (rather than rng.Text and then JScript text manipulation using substr). So, in the code for my previous posting the properties curNode.data and curNode.target will return the corresponding PI Data and Target values.

    Reply

    Derek Read

    Reply to: Styling custom PI’s

    Not exactly sure if this is useful but the following could be placed in an On_Click event macro to force the selection to be an entire “mytarget” PI when the user clicks inside one.

    [code]//XMetaL Script Language JSCRIPT:
    //create a Range object to work with the document
    var rng = ActiveDocument.Range;
    //store the current node, which should equal the PI
    var curNode = rng.ContainerNode;
    //only continue if we're in a “mytarget” PI, otherwise do nothing
    if ((curNode.NodeType == 7) && (curNode.target == “mytarget”)) {
    //change the user's selection to grab the entire PI
    rng.SelectElement();
    rng.Select();
    }[/code]

    Reply

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

Lost Your Password?

Products
Downloads
Support