Page 1 of 1

Refactor only a portion of a file?

Posted: Tue Apr 09, 2019 9:17 pm
by LaRae_Chasteen
Good day,
Is there any way to perform one of the built-in refactoring operations, but only on selected text within the open file?
Thank you,
LaRae Chasteen

Re: Refactor only a portion of a file?

Posted: Wed Apr 10, 2019 8:11 am
by Radu
Dear LaRae,

Unfortunately the XML refactor can only be applied on entire documents, not on selected content. I added an internal issue with your feedback and if we ever implement this I will update the forum thread. In the meantime you will probably need to use the "Find/Replace" dialog which works on a selection. Or extract the selected content to a separate file and apply the refactoring operation there (but the selected content needs to be wellformed XML).

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Tue Nov 05, 2019 7:10 pm
by Oleksii
Are there any news on this topic in the meantime? This kind of feature would be extremely useful.
It would be nice to be able to customize something like currently available Surround with tags which you can invoke with a shortcut.

Re: Refactor only a portion of a file?

Posted: Tue Nov 05, 2019 10:41 pm
by Radu
Hi Oleksii,

If you are working with the XML doc in the Author visual editing mode, you can create custom Author operation based on our predefined XSLT and XQuery operations:

https://www.oxygenxml.com/doc/versions/ ... yoperation

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Mon Nov 11, 2019 12:40 pm
by Oleksii
Hi Radu,

yes, I know about this possibility in Author mode and it would be an alternative. The point is that we are working with XML in MEI (https://dme.mozarteum.at/movi/navigator/525/001/01) namespace. Currently, we do not have an appropriate CSS for displaying it which could be also a bit tricky because an MEI document structure consists mainly of elements and their attributes. So we are working in the text mode only.

Regards,
Oleksii

Re: Refactor only a portion of a file?

Posted: Tue Nov 19, 2019 3:56 pm
by Radu
Hi Oleksii,

I understand, the only work around right now is to create an Oxygen plugin which adds some contextual menu actions in the Text editing mode which obtain the selected content, process it using XSLT and then replace the selection with the processed content.
We have lots of API, you can implement Oxygen plugins even using Javascript:

https://github.com/oxygenxml/wsaccess-j ... onTextPage

If you have someone willing to work on this I can guide them.

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Tue Nov 19, 2019 6:50 pm
by Oleksii
Hi Radu,

thank you, I'll take a closer look then.
As an even shorter workaround could be also to use a code template (options >> templates >> code templates) with ${selection} but especially if it could be evaluated through
${xpath_eval()}.
I tried to do

Code: Select all

${xpath_eval(
 ${selection}//* 
)}
or

Code: Select all

${xpath_eval(
let $n := ${selection}
return $n
)}
just to access the selection but obviously it is not serialized as an element. I also searched for XPath functions to convert string to a node-set or document node but didn't find anything. Maybe if you look behind the scenes of the ${selection} and ${xpath_eval()} you'll have an idea?

Regards,
Oleksii

Re: Refactor only a portion of a file?

Posted: Wed Nov 20, 2019 10:49 am
by Radu
Hi Oleksii,

If you want to go down that path of using xpath_eval, there is a Saxon function called parse-xml, it's used something like:

Code: Select all

${xpath_eval(parse-xml('${selection}')//*)}
but from my tests it seems the serialized output contains some extra namespaces, I managed to remove them with something like:

Code: Select all

${xpath_eval(
replace(
'${xpath_eval(parse-xml('${selection}')//*)}', 
' xmlns:xml="http://www.w3.org/XML/1998/namespace"', 
'')
)}
I will add an internal issue to see why those xmlns:xml namespace mappings get serialized.

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Thu Nov 21, 2019 12:15 pm
by Oleksii
Hi Radu,

I solved my particular problem for now as I needed the following value:

Code: Select all

${xpath_eval(
	(parse-xml('${selection}')//*[@xml:id])[1]/@xml:id/substring-after(., '_')
)}
But the example with replace() didn't work for me. I played around, also checking maybe the problem is something with a sequence handling but it didn't work either as I'm getting an empty sequence as a result of the evaluation:

Code: Select all

${xpath_eval(
		for $n in
			parse-xml('${selection}')//*
		return
			replace($n, ' xmlns:xml="http://www.w3.org/XML/1998/namespace"', 
		'' )
)}
Just replace() works, however:

Code: Select all

${xpath_eval(
	replace('abc', 'a', '')
)}
here is an xml snippet:

Code: Select all

<mei meiversion="3.0.0" xmlns="http://www.music-encoding.org/ns/mei">
	<staff dme.parts="11" n="7" xml:id="staff_18930">
		<layer n="1" xml:id="layer_18936">
			<mRest tstamp="1" xml:id="mRest_18942"/>
		</layer>
	</staff>
</mei>
The result is :

Code: Select all

<mei meiversion="3.0.0" xmlns="http://www.music-encoding.org/ns/mei">
	
		
			
		
	
			
		
</mei>

Re: Refactor only a portion of a file?

Posted: Fri Nov 22, 2019 3:26 pm
by Radu
Hi Oleksii,

Running replace on a node like you do:

Code: Select all

replace($n, ' xmlns:xml="http://www.w3.org/XML/1998/namespace"
is most probably invalid, you can run the replace on plain strings but once you have called the parse-xml, you have nodes there and not serialized XML strings.

This is why in the approach I gave you I first run the xpath evaluation to obtain the node set and the return of the method serializes the node set to an XML string, then I use an outer xpath evaluation which uses replace to replace in that returned string the xml prefix mapping which should not be there in the first place. So maybe you can take a look again at my example which uses the xpath_eval twice, an xpath eval which replaces and the inner xpath eval which actually does the processing.

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Tue Nov 26, 2019 7:30 pm
by Oleksii
Hi Radu,

the first thing I did was copy+paste of your code examples. :) As it didn't work for me (still getting empty string) I tried to play around.
I also noticed that you use xpath_eval() twice. It is strange it doesn't work for me.
oXygen 20.1

Regards,
Oleksii

Re: Refactor only a portion of a file?

Posted: Wed Nov 27, 2019 9:17 am
by Radu
Hi Oleksii,

In Oxygen 21.1 we made a major change in how our editor variables are evaluated, resulting in more flexibility when it comes to computing such constructs. So I was using in my tests Oxygen 21.1.

Regards,
Radu

Re: Refactor only a portion of a file?

Posted: Thu Feb 13, 2020 1:03 pm
by sorin_carbunaru
Hello,

Just wanted to let everybody know that the generation of extra "xmlns:xml" namespaces was fixed in the recently released oXygen 22.

Best wishes,
Sorin Carbunaru
oXygen XML

Embedding $ask{} into a code template.

Posted: Wed Sep 01, 2021 6:20 pm
by Oleksii
Hi,
The code template should add an attribute to multiple selected nodes at once, and it works fine like this:

Code: Select all

${xpath_eval(
let $node := parse-xml-fragment('${selection}')/node(),
$string := serialize($node),
$pattern := '(<.*?)(/>)',
$replacement := '$1 stem.dir="down" $2',
$output :=    replace($string, $pattern, $replacement)
  return    
$output
  )}	
Applying to the descendants of <beam>:

Code: Select all

    <beam xml:id="beam_17514">
                      <note artic="spicc" dur="8" oct="3" pname="a" tstamp="1.5" xml:id="note_17520"/>
                      <note artic="spicc" dur="8" oct="4" pname="c" tstamp="2" xml:id="note_17526"/>
                      <note accid="s" artic="spicc" dur="8" oct="3" pname="f" tstamp="2.5" xml:id="note_17532"/>
         </beam>
I get this:

Code: Select all

<beam xml:id="beam_17514">
                      <note artic="spicc" doxml.id="d27e3443" dur="8" oct="3" pname="a" tstamp="1.5" xml:id="note_17520" stem.dir="up" />
                      <note artic="spicc" doxml.id="d27e3445" dur="8" oct="4" pname="c" tstamp="2" xml:id="note_17526" stem.dir="up" />
                      <note accid="s" artic="spicc" doxml.id="d27e3447" dur="8" oct="3" pname="f" tstamp="2.5" xml:id="note_17532" stem.dir="up" />
                    </beam>
But the value of @stem.dir could be different, so it would be useful when the user can define the value dynamically. I wanted to implement this:

Code: Select all

${xpath_eval(
let $node := parse-xml-fragment('${selection}')/node(),
$string := serialize($node),
$pattern := '(<.*?)(/>)',
$attributeVal := "${ask('@stem.dir=', editable_combobox,('up':'up';'down':'down'), 'up')}",
$replacement := concat('$1 ', 'stem.dir="', $attributeVal, '" $2'),
$output := replace($string, $pattern, $replacement)
  return    
$output
  )}	
But it replaces the nodes with empty space, which usually happens when something fails. Through trial & error I found out that it could be something with fn:replace(). Because when using fn:concat() instead the combobox opens and the code works as expected:

Code: Select all

${xpath_eval(
let $node := parse-xml-fragment('${selection}')/node(),
$string := serialize($node),
$pattern := '(<.*?)(/>)',
$attributeVal := "${ask('@stem.dir=', editable_combobox,('up':'up';'down':'down'), 'up')}",
$replacement := concat('$1 ', 'stem.dir="', $attributeVal, '" $2'),
$output := concat($string, $pattern, $replacement)
  return    
$output
  )}	

Re: Refactor only a portion of a file?

Posted: Mon Sep 06, 2021 8:42 am
by alex_jitianu
Hello,

I've tested with an Oxygen 23.1 build and the code template worked as expected. The dialog appears, I give a value and @stem.dir is set to that value. What version of Oxygen are you running? Perhaps this was an issue that we fixed at some point.

Best regards,
Alex

Re: Refactor only a portion of a file?

Posted: Tue Sep 21, 2021 2:29 pm
by Oleksii
I'm using 20.1, build 2020010914

Re: Refactor only a portion of a file?

Posted: Wed Sep 22, 2021 12:54 pm
by alex_jitianu
Hi,

I'm sorry, but in version 20 we had a primitive editor expansion engine, which didn't treat all the nesting possibilities. We introduce a new engine in Oxygen 21.1.

Best regards,
Alex