<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>idea Python and/or Arcade built-in to handle reserved label characters in ArcGIS Pro Ideas</title>
    <link>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idi-p/1588790</link>
    <description>&lt;P&gt;&lt;STRONG&gt;NOTE:&lt;/STRONG&gt; I'm deliberately posting this in ArcGIS Pro Ideas because it's fundamentally an issue with the label &amp;amp; text engines, but there's a strong overlap with both the Python and Arcade boards, as well.&amp;nbsp; I'd be happy to move it if the moderators think it would be better in one/both of those.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Background:&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;&lt;P&gt;As many likely know, the ampersand (&lt;STRONG&gt;&amp;amp;&lt;/STRONG&gt;) and left angle bracket (&lt;STRONG&gt;&amp;lt;&lt;/STRONG&gt;) are both reserved characters for labels and similar text outputs in ArcGIS Pro.&amp;nbsp; Let's say I have a feature class that has a comments field that I'd like displayed in either a label or a text box on a map series.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Feature 1 Comment: "Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;Feature 2 Comment: "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Let's also say for argument that I want to print the Asset ID in bold, while the comments are in regular text.&amp;nbsp; Below is an abbreviated portion of some Python and Arcade code that will handle adding the text formatting strings to do the bold.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = [Comments]
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = $feature.Comments
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Only, we have a problem, here.&amp;nbsp; One of my comment strings has a less-than sign, which is a reserved character.&amp;nbsp; The first feature would display correctly, but the second one breaks:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&amp;nbsp;&lt;/STRONG&gt;"Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;&amp;lt;BOL&amp;gt;[Asset 2]&amp;lt;/BOL&amp;gt; "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Okay, so you add some code to handle the character replacement, and all is well:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = [Comments]
    commo = commo.replace('&amp;amp;','&amp;amp;amp;').replace('&amp;lt;','&amp;amp;lt;')
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = Replace(Replace($feature.Comments,'&amp;amp;','&amp;amp;amp;'),'&amp;lt;','&amp;amp;lt;')
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`​&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Results:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&lt;/STRONG&gt; "Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 2]&lt;/STRONG&gt; "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Problem:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;But what if I wanted to emphasize the word "both" in Asset 1?&amp;nbsp; Maybe it's not normal for the person looking at this text to reference both DEM and contours at the same time, but for this case I need them to do so.&amp;nbsp; In normal cases, I could just embed the necessary tags in the underlying comment:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Feature 1 Raw Comment: "Reference &amp;lt;BOL&amp;gt;&amp;lt;UND&amp;gt;both&amp;lt;/UND&amp;gt;&amp;lt;/BOL&amp;gt; DEM and Contours"&lt;/LI&gt;&lt;LI&gt;Feature 1 Intended Result:&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&amp;nbsp;&lt;/STRONG&gt;"Reference&amp;nbsp;&lt;U&gt;&lt;STRONG&gt;both&lt;/STRONG&gt;&lt;/U&gt; DEM and Contours"&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;Feature 1 Actual Result:&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&lt;/STRONG&gt; "Reference &amp;amp;lt;BOL&amp;gt;&amp;amp;lt;UND&amp;gt;both&amp;amp;lt;/UND&amp;gt;&amp;amp;lt;/BOL&amp;gt; DEM and Contours"&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;As you can see, because I wrote code to bypass the escape characters, these tags aren't going to work properly.&amp;nbsp; It's an either/or decision, unless you want to&amp;nbsp;&lt;STRONG&gt;&lt;EM&gt;manually&lt;/EM&gt;&lt;/STRONG&gt; go through every Comment and make sure you don't have any unescaped reserved characters.&amp;nbsp; No bueno.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Idea:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;I'd love to see a built-in command for arcpy and/or Arcade that would handle the replacement of reserved characters on the fly&amp;nbsp;&lt;EM&gt;without&lt;/EM&gt; replacing those characters when they're a part of a valid tag or escape string.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = arcpy.EscapeChar([Comments])
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = EscapeChar($feature.Comments)
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`​&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Added bonus:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Currently, if you're going to escape both ampersand and left-angle-bracket, you have to do it&amp;nbsp;&lt;EM&gt;in that order&lt;/EM&gt;, or you'll break your own character escapes (because you'll end up changing that left-angle-bracket to "&amp;amp;amp;lt;").&amp;nbsp; And if someone happened to put the correct escape text in the underlying text, you'd break that, too, for the same reasons.&lt;/P&gt;&lt;P&gt;If instead, you could just call something like "&lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;EscapeChar($feature.comments)&lt;/FONT&gt;&lt;/STRONG&gt;" in Arcade or "&lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;arcpy.EscapeChar(commo)&lt;/FONT&gt;&lt;/STRONG&gt;" in arcpy, all these edge cases could be handled in the back end—probably much more efficiently than any ad-hoc function I bake into my label &amp;amp; text scripts.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 27 Feb 2025 14:07:45 GMT</pubDate>
    <dc:creator>MErikReedAugusta</dc:creator>
    <dc:date>2025-02-27T14:07:45Z</dc:date>
    <item>
      <title>Labeling: Automatically escape HTML characters when using Formatting Tags</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idc-p/1308024#M33946</link>
      <description>&lt;P&gt;Whey you use &lt;A href="https://pro.arcgis.com/en/pro-app/latest/help/mapping/text/text-formatting-tags.htm" target="_blank" rel="noopener"&gt;Formatting Tags&lt;/A&gt; in your label expression, the expression breaks for features that have special characters like "&amp;lt;", "&amp;gt;", or "&amp;amp;" in their label fields. &lt;A href="https://community.esri.com/t5/arcgis-pro-questions/arcade-text-formatting-in-labels-does-not-work/m-p/1308011" target="_blank" rel="noopener"&gt;See this question for examples&lt;/A&gt;.&lt;/P&gt;&lt;P&gt;This is because these characters are reserved in HTML: they make up the syntax. To solve this, you have to replace those characters with their HTML entity, eg&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;var txt = $feature.TextField
txt = Replace("&amp;amp;", "&amp;amp;amp;")
txt = Replace(txt, "&amp;lt;", "&amp;amp;lt;")
txt = Replace(txt, "&amp;gt;", "&amp;amp;gt;")
return "&amp;lt;COL red='255'&amp;gt;" + txt + "&amp;lt;/COL&amp;gt;"&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is a lot of work, you can really easily forget to do this, you have to remember or look up the HTML entities, and users inexperienced with HTML (and probably many experienced ones, too) don't have a clue why their expression breaks for some features.&lt;/P&gt;&lt;P&gt;Solution: Just do those replacements behind the scenes.&lt;/P&gt;</description>
      <pubDate>Thu, 13 Jul 2023 18:23:58 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idc-p/1308024#M33946</guid>
      <dc:creator>JohannesLindner</dc:creator>
      <dc:date>2023-07-13T18:23:58Z</dc:date>
    </item>
    <item>
      <title>Python and/or Arcade built-in to handle reserved label characters</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idi-p/1588790</link>
      <description>&lt;P&gt;&lt;STRONG&gt;NOTE:&lt;/STRONG&gt; I'm deliberately posting this in ArcGIS Pro Ideas because it's fundamentally an issue with the label &amp;amp; text engines, but there's a strong overlap with both the Python and Arcade boards, as well.&amp;nbsp; I'd be happy to move it if the moderators think it would be better in one/both of those.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Background:&lt;/STRONG&gt;&lt;/U&gt;&lt;/P&gt;&lt;P&gt;As many likely know, the ampersand (&lt;STRONG&gt;&amp;amp;&lt;/STRONG&gt;) and left angle bracket (&lt;STRONG&gt;&amp;lt;&lt;/STRONG&gt;) are both reserved characters for labels and similar text outputs in ArcGIS Pro.&amp;nbsp; Let's say I have a feature class that has a comments field that I'd like displayed in either a label or a text box on a map series.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Feature 1 Comment: "Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;Feature 2 Comment: "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Let's also say for argument that I want to print the Asset ID in bold, while the comments are in regular text.&amp;nbsp; Below is an abbreviated portion of some Python and Arcade code that will handle adding the text formatting strings to do the bold.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = [Comments]
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = $feature.Comments
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Only, we have a problem, here.&amp;nbsp; One of my comment strings has a less-than sign, which is a reserved character.&amp;nbsp; The first feature would display correctly, but the second one breaks:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&amp;nbsp;&lt;/STRONG&gt;"Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;&amp;lt;BOL&amp;gt;[Asset 2]&amp;lt;/BOL&amp;gt; "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Okay, so you add some code to handle the character replacement, and all is well:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = [Comments]
    commo = commo.replace('&amp;amp;','&amp;amp;amp;').replace('&amp;lt;','&amp;amp;lt;')
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = Replace(Replace($feature.Comments,'&amp;amp;','&amp;amp;amp;'),'&amp;lt;','&amp;amp;lt;')
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`​&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Results:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&lt;/STRONG&gt; "Reference both DEM and Contours"&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 2]&lt;/STRONG&gt; "Contains &amp;lt; 1000 sq ft"&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Problem:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;But what if I wanted to emphasize the word "both" in Asset 1?&amp;nbsp; Maybe it's not normal for the person looking at this text to reference both DEM and contours at the same time, but for this case I need them to do so.&amp;nbsp; In normal cases, I could just embed the necessary tags in the underlying comment:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Feature 1 Raw Comment: "Reference &amp;lt;BOL&amp;gt;&amp;lt;UND&amp;gt;both&amp;lt;/UND&amp;gt;&amp;lt;/BOL&amp;gt; DEM and Contours"&lt;/LI&gt;&lt;LI&gt;Feature 1 Intended Result:&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&amp;nbsp;&lt;/STRONG&gt;"Reference&amp;nbsp;&lt;U&gt;&lt;STRONG&gt;both&lt;/STRONG&gt;&lt;/U&gt; DEM and Contours"&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;Feature 1 Actual Result:&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;[Asset 1]&lt;/STRONG&gt; "Reference &amp;amp;lt;BOL&amp;gt;&amp;amp;lt;UND&amp;gt;both&amp;amp;lt;/UND&amp;gt;&amp;amp;lt;/BOL&amp;gt; DEM and Contours"&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;As you can see, because I wrote code to bypass the escape characters, these tags aren't going to work properly.&amp;nbsp; It's an either/or decision, unless you want to&amp;nbsp;&lt;STRONG&gt;&lt;EM&gt;manually&lt;/EM&gt;&lt;/STRONG&gt; go through every Comment and make sure you don't have any unescaped reserved characters.&amp;nbsp; No bueno.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Idea:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;I'd love to see a built-in command for arcpy and/or Arcade that would handle the replacement of reserved characters on the fly&amp;nbsp;&lt;EM&gt;without&lt;/EM&gt; replacing those characters when they're a part of a valid tag or escape string.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def FindLabel ([ID], [Comments]):
    id = [ID]
    commo = arcpy.EscapeChar([Comments])
    return f'&amp;lt;BOL&amp;gt;[{id}]&amp;lt;/BOL&amp;gt; "{commo}"'&lt;/LI-CODE&gt;&lt;LI-CODE lang="javascript"&gt;var id = $feature.ID
var commo = EscapeChar($feature.Comments)
return `&amp;lt;BOL&amp;gt;[${id}]&amp;lt;/BOL&amp;gt; "${commo}"`​&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Added bonus:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Currently, if you're going to escape both ampersand and left-angle-bracket, you have to do it&amp;nbsp;&lt;EM&gt;in that order&lt;/EM&gt;, or you'll break your own character escapes (because you'll end up changing that left-angle-bracket to "&amp;amp;amp;lt;").&amp;nbsp; And if someone happened to put the correct escape text in the underlying text, you'd break that, too, for the same reasons.&lt;/P&gt;&lt;P&gt;If instead, you could just call something like "&lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;EscapeChar($feature.comments)&lt;/FONT&gt;&lt;/STRONG&gt;" in Arcade or "&lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;arcpy.EscapeChar(commo)&lt;/FONT&gt;&lt;/STRONG&gt;" in arcpy, all these edge cases could be handled in the back end—probably much more efficiently than any ad-hoc function I bake into my label &amp;amp; text scripts.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Feb 2025 14:07:45 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idi-p/1588790</guid>
      <dc:creator>MErikReedAugusta</dc:creator>
      <dc:date>2025-02-27T14:07:45Z</dc:date>
    </item>
    <item>
      <title>Re: Python and/or Arcade built-in to handle reserved label characters</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idc-p/1590037#M33980</link>
      <description>&lt;P&gt;Weirdly, right-angle-bracket (&lt;STRONG&gt;&amp;gt;&lt;/STRONG&gt;)&amp;nbsp;&lt;EM&gt;doesn't&lt;/EM&gt; seem to break the text, in my experience.&amp;nbsp; The only two I've ever encountered are the two mentioned in my original post.&lt;/P&gt;&lt;P&gt;Beyond that, absolutely agreed: This is poor UX to begin with, even in simple cases.&amp;nbsp; In the more complex cases at the top, it's even worse.&lt;/P&gt;&lt;P&gt;Solving it "automagically" in the back end without user input might be difficult to do without being overzealous, though.&lt;/P&gt;</description>
      <pubDate>Thu, 27 Feb 2025 14:10:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/python-and-or-arcade-built-in-to-handle-reserved/idc-p/1590037#M33980</guid>
      <dc:creator>MErikReedAugusta</dc:creator>
      <dc:date>2025-02-27T14:10:49Z</dc:date>
    </item>
  </channel>
</rss>

