How to highlight targetStrings within a macro with splitregex/join, i.e., treat the macro as a string?

閲覧: 117 回
最初の未読メッセージにスキップ

steve

未読、
2020/07/20 16:55:572020/07/20
To: TiddlyWiki
Hello:

I am working on a macro to highlight target strings within the text field of a tiddler. 
The use case is to make it easier to for me see where the targetStrings are (if any).  

My question is how to highlight the targetString in the macro (ie. treating
the macro as a string) as opposed to (apparently) executing the macro
and highlighting the targetString in the output.

!!! Here is the macro
```
\define formatTid.highlightText(inputText targetString)

<$set name="outputText" filter="[[$inputText$]] +[splitregexp[\b$targetString$\b]join[@@color:blue;$targetString$@@]]" select="0">

| ''outputText''|<<outputText>> |

\end
<$macrocall $name="formatTid.highlightText" inputText={{highlightTest.sentence!!text}} targetString="goFish"/>
```

The macro works as expected (goFish is highlighted in blue) when the text field contains

```
This goFish is in a sentence.
```

The macro works partially (i.e., goFish is highlighted only for the comment).

```
\define goFish()

!!! This example has three instances of goFish.

\end
<<goFish>>
```

TW Tones

未読、
2020/07/20 17:29:242020/07/20
To: TiddlyWiki
Steve,

Just a quick response for now. As I am not exactly sure of the mechanism you are trying to use.
  • Are you aware of the freelinks plugin?, if the tiddler title exists it will be highlighted in the text. It may be a more general solution.
    • This plugin is making use of other mechanisms to add the highlight layer on the text, in fact generates links.
  • We now have search and contains operators that may make detecting a string more easily. Rather than select="0" you could also use the First operator.
  • The splitregexp is powerful but so too are the standard filters.
  • I would be tempted to keep the highlight outside the filter, but that's me.
  • Perhaps try and concatenate the strings outside the filter
  • Sometimes wikifying is needed to ensure the value you expect is in use but since you not using variables/macros to do this it may not be relevant until you use them.
Regards
Tony

Saq Imtiaz

未読、
2020/07/20 17:33:062020/07/20
To: TiddlyWiki
@steve just in case you haven't seen it, there's a plugin that does something very similar:

https://tiddlywiki.com/prerelease/#%24%3A%2Fplugins%2Ftiddlywiki%2Fdynannotate

Check out the examples tab in the plugin tiddler.

Eric Shulman

未読、
2020/07/20 18:13:072020/07/20
To: tiddl...@googlegroups.com
On Monday, July 20, 2020 at 1:55:57 PM UTC-7, steve wrote:
I am working on a macro to highlight target strings within the text field of a tiddler. 
The use case is to make it easier to for me see where the targetStrings are (if any).  
 
My question is how to highlight the targetString in the macro (ie. treating
the macro as a string) as opposed to (apparently) executing the macro
and highlighting the targetString in the output.


There's nothing wrong with your filter and regexp usage.

To see the literal output text, I used the <$text> widget in the table, like this:
\define formatTid.highlightText(inputText targetString)
<$set name="outputText" filter="[[$inputText$]]  +[splitregexp[\b$targetString$\b]join[@@color:blue;$targetString$@@]]" select="0">

| ''outputText''|<$text text=<<outputText>>/>|

\end
<$macrocall $name="formatTid.highlightText" inputText={{highlightTest.sentence!!text}} targetString="goFish"/
>

The result of the above (using your example input) is:
outputText\define @@color:blue;goFish@@() !!! This example has three instances of @@color:blue;goFish@@. \end <<@@color:blue;goFish@@>>

As you can see, your regexp filter DID find and replace all the targetString instances by wrapping them with "@@color:blue;...@@" as you intended.  Of course, that doesn't produce the output you want, which is to see the full input text with the blue highlighting.

The problem with using just <<outputText>> in the table stems from the way the TWCore parser processes and renders the "outputText" value.

1) anything starting with "\define" or "\end" is part of a macro definition, and the TWCore doesn't *render* those as output.

2) anything from "<<" through ">>" is a macro invocation, and if the macro isn't defined in the current context, then it produces no output.

Thus, only the normal wikitext content in your example is displayed as output and the macro definition and macro invocation are not shown.

Fortunately, I did find a way to get something closer to what you want.  Try this:
\define formatTid.highlightText(inputText targetString)
<$set name="outputText" filter="[[$inputText$]]  +[splitregexp[\b$targetString$\b]join[@@color:blue;$targetString$@@]]" select="0">

| ''outputText''|@@white-space:pre;<<showOutput>>@@|
\end

\define showOutput()
\rules only styleinline
$
(outputText)$
\end

<$macrocall $name="formatTid.highlightText" inputText={{highlightTest.sentence!!text}} targetString="goFish"/>

* The @@white-space:pre;...@@ in the table forces whitespace to be rendered as-is (the default rendering collapses all whitespace)
* The showOutput() macro uses the "\rules" pragma to disable all parsing except for "styleinline" (the "@@" syntax)

The result of the above (using your example input) is:
outputText
\define goFish() !!! This example has three instances of goFish. \end <<goFish>>

Which is, I think, very close to what you intended.

Tricky stuff, eh?

Let me know how it goes...

enjoy,
-e

steve

未読、
2020/07/20 18:35:552020/07/20
To: TiddlyWiki
Hi Tony, Saq:

More about my use case ...

When I look at macro (code) in the editor it is very easy for me to overlook variable or macro names that I want to change
and so I fail to update all of them.  The purpose of the formatTid.highlightText macro is to create a highlighted copy of the macro code
with the css @@color:blue; targetString@@ imbedded around each instance of the targetString.

Tony: I am working through your suggestions -- thanks.
Saq: I tried dynannotate and it does what I want with regular text -- thanks!  I could not get it to work with text within macro code.

Is there a why to treat/convert/escape (?) macro code (ie anything between \define and \end as a string without executing/running it?

Thanks Again
Steve

steve

未読、
2020/07/20 19:00:042020/07/20
To: TiddlyWiki
Eric:

Very tricky indeed but you made it look simple!

It worked - yay! I am trying some more complex examples including
embedded macro calls and will report back.

Thanks!

Steve

TW Tones

未読、
2020/07/20 19:05:302020/07/20
To: TiddlyWiki
Steve,

Thanks for the clarification. So you are viewing the tiddler content as code and want the target within that to be highlighted?

I understand you have a solution but this is already handled in multiple ways.
  • The codemirror plugin and other tools are available with additional edit mode features such as search/and replace. Go to my playground wiki here and you can install plugins from multiple sources (4 libraries) and they are saved in local storage you can experiment, reload for plugins without saving works.
  • The dynannotate plugin is designed to help with annotations and search
  • The highlight plugin is also designed for this. 
  • There is a search that highlights the text in the page I will post back when I find it, just type you target in the search and its highlighted if on the page, I am yet to test with code view
Futures;
I have built a smart-showcode tool (95% done) and I will address this need for highlighting not you point it out.

Regards
Tony

steve

未読、
2020/07/20 19:19:502020/07/20
To: TiddlyWiki

Update:

This time I tried a macro with a filter that used goFish in a filter. See below.
Nothing was listed in the outputText.
Tomorrow I'll look at the literal output text.

----

\define goFish()

!!! This example has five goFish

!!! This goFish is in a macro.
<$list filter="[search:text[goFish]]" variable="match">

<<match>>

</$list>

\end
<<goFish>>

Eric Shulman

未読、
2020/07/20 19:55:222020/07/20
To: tiddl...@googlegroups.com
On Monday, July 20, 2020 at 4:19:50 PM UTC-7, steve wrote:
This time I tried a macro with a filter that used goFish in a filter. See below.
Nothing was listed in the outputText.
Tomorrow I'll look at the literal output text.

The problem here is that the input text contains quotes and doubled close squarebrackets.

The quotes in the inputText interfere with quotes that delimit the filter="..." syntax in your macro,
and the ]] in the inputText interferes with the brackets that surround the [[$inputText$]] in the filter.

To avoid all that, instead of passing the text into your macro as a parameter,
pass the name of the tiddler you want to process, and then fetch the text of
that tiddler inside your filter, like this:

\define formatTid.highlightText(source targetString)
<$set name="outputText" filter="[{$source$}splitregexp[$targetString$]join[@@color:blue;$targetString$@@]]" select="0">

| ''outputText''|@@white-space:pre-wrap;font-family:monospace;<<showOutput>>@@|

\end

\define showOutput()
\rules only styleinline
$
(outputText)$
\end

<$select tiddler="$:/temp/highlight/source">
   
<$list filter="[all[]sort[]]"><option value=<<currentTiddler>>><$text text=<<currentTiddler>>/></option></$list>
</$select>
<$edit-text tiddler="$:/
temp/highlight/target" tag="input" default="" placeholder="enter text to highlight" /><br>
<$macrocall $name="
formatTid.highlightText" source={{$:/temp/highlight/source}} targetString={{$:/temp/highlight/target}}/>

I made a few other tweaks in the above code:
1) in the filter, I changed splitregexp[\b$targetstring$\b] to just splitregexp[$targetstring$].  This allows matching text that is part of a word and not just a whole word surrounded by whitespace.
2) in the output table, I added "font-family:monospace" to the styles.  I just like fixed-width fonts for viewing tiddler source content
3) I added an input form using $select to list all tiddler titles, and $edit-text to enter the targetString.  Then, I pass the values of these inputs as the parameters to the $macrocall.  This makes it easier to test a variety of tiddler content and target strings without having to directly edit the $macrocall 

enjoy,
-e

steve

未読、
2020/07/21 11:05:572020/07/21
To: TiddlyWiki
Eric:

I made some additional tweaks to your solution to:

* narrow selection list to list of tiddlers that actually contain the targetString
* provide a GO button so that macro does not have to run for every keystroke in the edit box
* added a reveal so that macro is run only if a source tiddler was selected
* added parameter to set the highlightColor

Tony:
* I'll look into codemirror
* there did not appear to be a link for your playground wiki

Thanks to all that responded!

Steve





Enter code here...\define formatTid.highlightText(source:"MainMenu" targetString:"Handler" highlightColor:"blue")
<$set name="outputText" filter="[{$source$}splitregexp[$targetString$]join[@@color:$highlightColor$;$targetString$@@]]" select="0">

<!-- Future Ideas
       
* display number of matches
       
* use CSS for highlighting not just color
-->
|''targetString is highlighted in @@color:$highlightColor$; $highlightColor$@@''|

|@@white-space:pre-wrap;font-family:monospace;<<showOutput>>@@|

\end
\define showOutput()
\rules only styleinline
$
(outputText)$
\end

<!-- 1. Type string into entryBuffer
       
2. press GO to:
           
* copy string from entryBuffer to targetString (avoids responding to each keystroke)
           
* initialize source to ""
       
3. list tiddlers that contain targetString (if any)
       
4. select tiddler to be highlighted
-->
''Enter targetString and press GO'' <$edit-text tiddler="$:/temp/highlight/entryBuffer" tag="input" default="" placeholder="enter text to highlight" />
<$button><$action-setfield $tiddler="$:/temp/highlight/targetString"  $value={{$:/temp/highlight/entryBuffer}}/><$action-setfield $tiddler="$:/temp/highlight/source"  $value=""/>GO</$button>
<$vars targetString={{$:/
temp/highlight/targetString}}><br>

''Select Source Tid'' (if any) <$select tiddler="$:/temp/highlight/source" default="blurg">
<$list filter="[!is[system]search:text<targetString>has[code-library]sort[]]"><option value=<<currentTiddler>>><$text text=<<currentTiddler>>/></option></$list>
</$select><br>

<$reveal text={{$:/
temp/highlight/source}}  type="nomatch" default="">
<$macrocall $name="formatTid.highlightText" source={{$:/temp/highlight/source}} targetString=<<targetString>>/>
</
$reveal>
</$vars>


Eric Shulman

未読、
2020/07/21 12:25:142020/07/21
To: TiddlyWiki
On Tuesday, July 21, 2020 at 8:05:57 AM UTC-7, steve wrote:
<!-- Future Ideas
       
* display number of matches
       
* use CSS for highlighting not just color
-->

Here's a version that displays the number of matches and uses a CSS class definition:
\define formatTid.highlightText(source:"MainMenu" targetString:"Handler" style:"color:blue;font-weight:bold;")
<style> .highlight { $style$ } </style>
<$vars outputText={{{ [{$source$}splitregexp[$targetString$]join[@@.highlight $targetString$@@]] }}}>
<$text text={{{ [{$source$}splitregexp[$targetString$]count[]subtract[1]] }}} /
> matches:
<div style="border:1px solid;white-space:pre-wrap;font-family:monospace;"><<showOutput>></div>
\end
Note that I also changed from using a table to using a div

enjoy,
-e

steve

未読、
2020/07/21 13:48:352020/07/21
To: TiddlyWiki

HI Eric:

From your latest email I've incorporated the number of times targetString was matched and the div for the showOutput.
I've also echoed the input parameters to formatTid.highlightText and added a "pane" format for the target string.

Thanks to your help it keeps getting better and better.
Here is a screen shot of the results.

Thanks again
Steve




\define formatTid.highlightText(source:"MainMenu" targetString:"Handler" highlightColor:"blue" highlightStyle:"background-color:khaki;color:#656565;font-size:8.5pt;font-weight:bold;border-radius: 2px;border-style:solid;border-color:gray;border-width:1px;")

<$set name="outputText" filter="[{$source$}splitregexp[$targetString$]join[@@$highlightStyle$$targetString$@@]]" select="0">


|''For source'': @@color:navy;font-size:8pt;font-weight:bold;$source$@@; ''targetString'': @@color:navy;font-size:8pt;font-weight:bold;$targetString$@@; ''found'' @@color:navy;font-size:8pt;font-weight:bold;<$text text={{{ [{$source$}splitregexp[$targetString$]count[]subtract[1]] }}} /> match(es).@@|


<div style="border:1px solid;white-space:pre-wrap;font-family:monospace;">

<<showOutput>>
<
/div>

\end

\define showOutput()
\rules only styleinline
$(outputText)$
\end
\define formatTid.highlightText.ui()
<!-- User interface to:
        * enter target string
        * select source
        * display formatTid.highlightText results in table
-->

---

<!-- Type string into entryBuffer and press GO to

         * copy string from entryBuffer to targetString (avoids responding to each keystroke)
         * initialize source to (avoid retaining prev choice if no matching tiddlers were found)

-->
''Enter targetString and press GO'' <$edit-text tiddler="$:/
temp/highlight/entryBuffer" tag="input" default="" placeholder="enter text to highlight" />
<$button><$action-setfield $tiddler="
$:/temp/highlight/targetString"  $value={{$:/temp/highlight/entryBuffer}}/><$action-setfield $tiddler="$:/temp/highlight/source"  $value=""/>GO</$button>

<$vars targetString={{$:/temp/highlight/targetString}}><br>

<!-- Select source tiddler from tids that contain
        the search string (if any)
-->
''Select Source (tiddler)'' @@color:navy;font-variant:super;font-weight:bold;(<$count filter="
[!is[system]search:text<targetString>has[code-library]]"/> found)@@ <$select tiddler="$:/temp/highlight/source" default="blurg">
<$list filter="
[!is[system]search:text<targetString>has[code-library]sort[]]"><option value=<<currentTiddler>>><$text text=<<currentTiddler>>/></option></$list>
</$select><br>

<!-- Highlight targetString's in the selected source tid.
-->

<$reveal text={{$:/temp/highlight/source}}  type="
nomatch" default="">
<$macrocall $name="
formatTid.highlightText" source={{$:/temp/highlight/source}} targetString=<<targetString>>/>
</$reveal>
</$vars>

---
\end
<<formatTid.highlightText.ui>>


steve

未読、
2020/07/21 14:58:052020/07/21
To: TiddlyWiki
Example output with a bit more color

Steve


TW Tones

未読、
2020/07/21 20:02:242020/07/21
To: TiddlyWiki
Steve,

The pre-release version (may be out of date) https://anthonymuscio.github.io/empty-pre-release.html

Regards
Tony
全員に返信
投稿者に返信
転送
新着メール 0 件