Starfinder Playlist
  1. #1

    Formatted Text field, links, DB.findNode()

    This situation can be encountered if you are pulling information from a formatted text field and using the data in a link.

    I've noticed while using DB.findNode() that if the source has any XML escape characters it causes problems because it doesn't match the module name. My guess is that previously FGC did not require escape versions of specific XML characters in formatted text links. It looks like DB.findNode() doesn't resolve XML escapes such as "&".

    For example if you have a link from the module named "AD&D Dungeonmaster Guide" the & character will be escaped to "&amp;". I image this same situation will occur when you have '/<> and various other XML control characters. When trying to DB.findNode() the image from the link with the escape chars in it, will return null.

    Is it currently possible to pull decoded text values from formatted text field? If not are there any plans to add a XML decode/encode? (While you're at it, please add a JSON encode/decode since I know libraries for both must be in Unity already).

    Is there another way around this currently I'm not thinking of?
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  2. #2
    DB.findNode does not resolve escaped XML characters in either FGC or FGU. Do you have an example of the code that is having an issue?

    Regards,
    JPG

  3. #3
    Quote Originally Posted by Moon Wizard View Post
    DB.findNode does not resolve escaped XML characters in either FGC or FGU. Do you have an example of the code that is having an issue?

    Regards,
    JPG

    The context is I am parsing the formatted text field of a story entry in createBlocks() looking for "links" that match my requirements (imagewindow type) and then trying to DB.findNode() on the record listed there in createBlockImage().

    Code:
    function createBlocks(nodeRefPage,nodeStory,sFrameText)
      local sFrameImage = "picture";
      local dBlocks = DB.createChild(nodeRefPage,"blocks");
      local sNoteText = DB.getValue(nodeStory,"text","");
      local aTextBlocks = {};
      local bLoop = true;
      while (bLoop) do
    -- <linklist>
      -- <link class="imagewindow" recordname="image.id-00003">Map7#100x100#</link>
    -- </linklist>
    
    -- <linklist>
    -- 	<link class="imagewindow" recordname="image.id-00002@AD&amp;D 2E Players Handbook">Door Smashed Open</link>
    -- </linklist>
        --local nStart, nEnd = string.find(sNoteText,'<linklist>[^<]+<link class="imagewindow" recordname="[%w%-%p]+">[^<]+</link>[^<]+</linklist>',1);
        local sPatternMatchFGU = '<linklist><link class="imagewindow" recordname="[^\"]+">[^<]+</link></linklist>';
        local sPatternMatchFGC = '<linklist>[^<]+<link class="imagewindow" recordname="[^\"]+">[^<]+</link>[^<]+</linklist>';
        local sPatternMatch = sPatternMatchFGC;
        
        if UtilityManager.isClientFGU() then
          sPatternMatch = sPatternMatchFGU;
        end
        local nStart, nEnd = string.find(sNoteText,sPatternMatch,1);
        if (nStart and nEnd) then
          local sThisBlock = string.sub(sNoteText,1,nStart-1);
          if validateStringForBlock(sThisBlock) then
            createBlockText(dBlocks,sThisBlock,sFrameText);
          end
          
          local sImageBlock = string.sub(sNoteText,nStart,nEnd);
          if validateStringForBlock(sImageBlock) then
            createBlockImage(dBlocks,sImageBlock,sFrameImage);
          end
          -- now trim out the above text from sNoteText
          sNoteText = string.sub(sNoteText,nEnd+1);
        else
          bLoop = false;
          if validateStringForBlock(sNoteText) then
            createBlockText(dBlocks,sNoteText,sFrameText);
          end
        end
      end -- end while
    end
    Code:
    -- create a block for an inline image
    function createBlockImage(dBlocks,sText,sFrame)
    Debug.console("manager_author_adnd.lua","createBlockImage","sText",sText);
    -- should we split this up by $ or \r and parse it that way for better match?
    -- <linklist>
      -- <link class="imagewindow" recordname="image.id-00001">Cavern1 room 2</link>
    -- </linklist>
    --   local sImageNode = sText:match("recordname=\"([%w%p%-]+)\"");
      -- local sImageCaption = sText:match("<link class=\"imagewindow\" recordname=\"[%w%p%-]+\">([%w%p%s]+)</link>");
      local sImageNode = sText:match("recordname=\"([^\"]+)\"");
      local sImageCaption = sText:match("<link class=\"imagewindow\" recordname=\"[^\"]+\">([^<]+)</link>");
      
      Debug.console("manager_author_adnd.lua","createBlockImage","sImageNode",sImageNode);
      -- prototyping code that I might use later...
      -- sImageNode, sImageCaption imageBlockRecord(sText);
      
      local nodeImage = DB.findNode(sImageNode);
      Debug.console("manager_author_adnd.lua","createBlockImage","nodeImage",nodeImage);    
      if (nodeImage) then
        local nodeBlock = DB.createChild(dBlocks);
        -- <blocktype type="string">image</blocktype>
        DB.setValue(nodeBlock,"blocktype","string","image");
        
        --<frame type="string">castle</frame>
        -- FRAMES DONT WORK ON IMAGES DOH!!!! --celestian
        -- if (sFrame and sFrame ~= "") then
          -- DB.setValue(nodeBlock,"frame","string",sFrame);
        -- end
        
        -- <align type="string">center</align>
        DB.setValue(nodeBlock,"align","string","center");
        local nX,nY = 0,0; 
        --local nXOriginal, nYOriginal = 0,0;
        Debug.console("manager_author_adnd.lua","createBlockImage","nodeImage",nodeImage);          
        
        local w = Interface.openWindow("imagewindow",nodeImage);
        if w then 
          if not UtilityManager.isClientFGU() then
            local ctrl = w.createControl("image_refblock", "image");
            --nXOriginal, nYOriginal = ctrl.getImageSize();
            local nXX,nYY = ctrl.getImageSize();
            nX, nY = getAdjustedImageSize(nXX,nYY);
            --nX, nY = getAdjustedImageSize(ctrl);
          else
            local sAsset = DB.getText(w.getDatabaseNode(), "image", "");
    
            Debug.console("manager_author_adnd.lua","createBlockImage","sAsset",sAsset);             
            Debug.console("manager_author_adnd.lua","createBlockImage","Interface.getAssetSize(sAsset)",Interface.getAssetSize(sAsset));   
            local nAssetX, nAssetY = Interface.getAssetSize(sAsset);
            nX, nY = getAdjustedImageSize(nAssetX,nAssetY);
          end
          w.close();
        end
    
        if (nX > 0) and (nY > 0) then 
          Debug.console("manager_author_adnd.lua","createBlockImage","---------->nX",nX,"nY",nY);
          -- <size type="string">nX,nY</size>
          local sSize = nX .. "," .. nY;
          DB.setValue(nodeBlock,"size","string",sSize);
          -- <caption type="string" />
          if (not sImageCaption or sImageCaption == "") then
            sImageCaption = DB.getValue(nodeImage,"name","");
          end
          -- removed the size of image caption --celestian
          -- if the size changed, tag it with full size image pixels
          --if (nXOriginal ~= nX or nYOriginal ~= nY) then
            --sImageCaption = sImageCaption .. " (" .. nXOriginal .. "x" .. nYOriginal .. ")";
          --end
          DB.setValue(nodeBlock,"caption","string",sImageCaption);
          -- <image type="image">
            -- <bitmap>Cavern1 room 2.jpg</bitmap>
          -- </image>
          DB.setValue(nodeBlock,"image","image",DB.getValue(nodeImage,"image",""));
          -- <imagelink type="windowreference">
            -- <class>imagewindow</class>
            -- <recordname>image.id-00001</recordname>
          -- </imagelink>
          DB.setValue(nodeBlock,"imagelink","windowreference","imagewindow",sImageNode);
        else
          Debug.console("manager_author_adnd.lua","createBlockImage","SIZE INVALID");
          createBlockText(dBlocks,sText,sFrame);
        end
    
      else
        Debug.console("manager_author_adnd.lua","createBlockImage","nodeImage INVALID");
        createBlockText(dBlocks,sText,sFrame);
      end
    end
    It does work in FGC tho I've not run tests on why yet. In FGU when running DB.findNode() is returns null because of escape sequences. Just hoping I don't have to write something to decode XML for the DB.findNode().
    Last edited by celestian; November 12th, 2020 at 18:29.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  4. #4
    I modified a copy of CoreRPG to output the text of any reference manual text block using DB.getValue; and the 5E LMoP module to contain links with ampersands. I've included the data I put in and got back. The ampersands were both encoded by FGC and FGU when using DB.getValue. I'm going to need more information; or an example.

    Regards,
    JPG

    Module XML
    Code:
    <text type="formattedtext"><p>The Cragmaw tribe of goblins has established a hideout from which it can easily harass and plunder traffic moving along the Triboar Trail or the path to Phandalin. The Cragmaw tribe is so named because each member of the tribe sharpens its teeth so they appear fierce and jagged.</p><p>The leader of the Cragmaw bandits lairing here is a bugbear named Klarg, who has orders from the chief of the Cragmaws to plunder any poorly defended caravans or travelers that come this way. A few days ago, a messenger from Cragmaw Castle brought new instructions: Waylay the dwarf Gundren Rockseeker and anyone traveling with him.</p><link type="windowreference" class="imagewindow" recordname="image.img_cragmawhideout_jpg@D&amp;D Lost Mine of Phandelver"><b>DM Map:</b> Cragmaw Hideout</link><link type="windowreference" class="imagewindow" recordname="image.img_cragmawhideout_player__jpg@D&amp;D Lost Mine of Phandelver"><b>Battlemap:</b> Cragmaw Hideout</link></text>
    FGC
    Code:
    <p>The Cragmaw tribe of goblins has established a hideout from which it can easily harass and plunder traffic moving along the Triboar Trail or the path to Phandalin. The Cragmaw tribe is so named because each member of the tribe sharpens its teeth so they appear fierce and jagged.</p>
    <p>The leader of the Cragmaw bandits lairing here is a bugbear named Klarg, who has orders from the chief of the Cragmaws to plunder any poorly defended caravans or travelers that come this way. A few days ago, a messenger from Cragmaw Castle brought new instructions: Waylay the dwarf Gundren Rockseeker and anyone traveling with him.</p>
    <linklist>
    	<link class="imagewindow" recordname="image.img_cragmawhideout_jpg@D&amp;D Lost Mine of Phandelver"><b>DM Map: </b>Cragmaw Hideout</link>
    	<link class="imagewindow" recordname="image.img_cragmawhideout_player__jpg@D&amp;D Lost Mine of Phandelver"><b>Battlemap: </b>Cragmaw Hideout</link>
    </linklist>
    FGU
    Code:
    <p>The Cragmaw tribe of goblins has established a hideout from which it can easily harass and plunder traffic moving along the Triboar Trail or the path to Phandalin. The Cragmaw tribe is so named because each member of the tribe sharpens its teeth so they appear fierce and jagged.</p><p>The leader of the Cragmaw bandits lairing here is a bugbear named Klarg, who has orders from the chief of the Cragmaws to plunder any poorly defended caravans or travelers that come this way. A few days ago, a messenger from Cragmaw Castle brought new instructions: Waylay the dwarf Gundren Rockseeker and anyone traveling with him.</p><linklist><link class="imagewindow" recordname="image.img_cragmawhideout_jpg@D&amp;D Lost Mine of Phandelver"><b>DM Map:</b> Cragmaw Hideout</link><link class="imagewindow" recordname="image.img_cragmawhideout_player__jpg@D&amp;D Lost Mine of Phandelver"><b>Battlemap:</b> Cragmaw Hideout</link></linklist>
    Regards,
    JPG

  5. #5
    Quote Originally Posted by Moon Wizard View Post
    I modified a copy of CoreRPG to output the text of any reference manual text block using DB.getValue; and the 5E LMoP module to contain links with ampersands. I've included the data I put in and got back. The ampersands were both encoded by FGC and FGU when using DB.getValue. I'm going to need more information; or an example.
    Regards,
    JPG
    local nodeImage = DB.findNode(sImageNode);

    That's the part that breaks (returns null in FGU) when you try and get a sImageNode that has escaped characters in it.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  6. #6
    Quote Originally Posted by celestian View Post
    local nodeImage = DB.findNode(sImageNode);

    That's the part that breaks (returns null in FGU) when you try and get a sImageNode that has escaped characters in it.
    Actually, you know what. This doesn't matter. The only time you'll be using (or should) inline images for module export is when the images are local, not shared. I just never noticed this before for the same reason I just gave

    I did notice that the DB.getValue(nodeImage,"image","") was returning differing values than I got on FGC.

    FGC:
    Code:
    s'manager_author_adnd.lua' | s'createBlockImage' | s'getValue(nodeimage)' | { s'viewlock' = bFALSE, s'orientationcount' = bTRUE, s'mask' = s'', s'gridoffsety' = #0, s'orientationmode' = bFALSE, s'gridsize' = #0, s'image' = s'images/umberhulk_Avatar.jpg', s'gridsnap' = #3, s'gridtype' = #0, s'drawing' = s'', s'gridoffsetx' = #0, s'tokenlock' = bFALSE }
    But in FGU the same thing shows:
    Code:
    s'manager_author_adnd.lua' | s'createBlockImage' | s'getValue(nodeimage)' | { s'gridsizey' = #50, s'orientationcount' = #8, s'distancesuffix' = s''', s'gridvisible' = bFALSE, s'gridoffsety' = #0, s'gridsize' = #50, s'distanceunit' = #5, s'orientationmode' = #0, s'distancediagmult' = #1, s'gridsizex' = #50, s'gridoffsetx' = #0, s'gridtype' = #0 }
    That causes problems with you set the node DB.setValue(nodeBlock,"image","image",DB.getValue( nodeImage,"image","")); because with FGU value it doesn't contain the image so just appears as a blank space in the ref-manual (but clicking on the space loads it).
    Last edited by celestian; November 13th, 2020 at 06:07.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  7. #7
    I can modify the getValue to return the same information as getText in the Lua table returned. However, it will be limited just like getText, in that a non-empty string value will only be returned if there is a single image layer with an asset (i.e. can be distilled to a single string). You're probably better off using DB.copyNode to get a full copy.

    For your original report, FGC and FGU are returning the same information; and failing the DB.findNode check exactly the same. (see image)

    Regards,
    JPG
    Attached Images Attached Images

  8. #8
    Quote Originally Posted by Moon Wizard View Post
    I can modify the getValue to return the same information as getText in the Lua table returned. However, it will be limited just like getText, in that a non-empty string value will only be returned if there is a single image layer with an asset (i.e. can be distilled to a single string). You're probably better off using DB.copyNode to get a full copy.

    For your original report, FGC and FGU are returning the same information; and failing the DB.findNode check exactly the same. (see image)

    Regards,
    JPG
    Yes, my mistake was trying to link to a image from a module which would not be proper procedure for creating a product to export. It would need to be "local" in the campaign so the & wouldn't matter...

    I think there might be some confusion on what im trying to do, which I understand due to the pivot towards a different response in FGC/FGU.

    The DB.getValue(nodeImage,"image","") is what is different. The data from FGU doesn't contain the same relevant data as the FGC version to populate a image block in a ref-manual properly.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

  9. #9
    Well, I'm going to add the additional piece of info in the next build of FGU; but with the caveats I laid out already.

    Regards,
    JPG

  10. #10
    Quote Originally Posted by Moon Wizard View Post
    Well, I'm going to add the additional piece of info in the next build of FGU; but with the caveats I laid out already.

    Regards,
    JPG
    Understood, I'll give it a look when the update comes through. This isn't anything that is critical. Right now we can't really use FGU to produce modules outside of personal use.
    ---
    Fantasy Grounds AD&D Reference Bundle, AD&D Adventure Bundle 1, AD&D Adventure Bundle 2
    Documentation for AD&D 2E ruleset.
    Custom Maps (I2, S4, T1-4, Barrowmaze,Lost City of Barakus)
    Note: Please do not message me directly on this site, post in the forums or ping me in FG's discord.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
STAR TREK 2d20

Log in

Log in