Textpattern CMS support forum

You are not logged in. Register | Login | Help

#11 2013-09-12 19:17:55

etc
Developer
Registered: 2010-11-11
Posts: 3,356
Website

Re: From PHP to txp:plugin -- need help troubleshooting!

johnstephens wrote:

Thanks again, Oleg! Your etc_query suggestions entirely solved my problem! Someone told me I should not use regular expressions for XHTML traversal, and I have abandoned pax_endnoter.

Glad it works, John, DOM parsing is more reliable indeed.

I adapted your code using the current version of etc_query before you posted the dev version. Is there a good reason to use the dev version instead, apart from readability in my TXP form?

No, especially because the idea of attributes reparsing was quickly dropped since. However, trying to optimally solve your problem, I had some alternative ideas that are implemented in the latest version now. One of them is the possibility to save the transformed DOM tree to quickly reuse it later. It works like this:

<!-- import all elements to process in one dom tree -->

<txp:etc_query data='<div><txp:variable name="content"/></div>
		<div><txp:body /></div>' 
	query="//span[@class='fnt']" save="endnotes"
	replace="&=<sup><a href='#endnote_{#row}' id='marker_{#row}'>{#row}</a></sup>"
>
	<txp:variable name="endnotes">
		<txp:variable name="endnotes" />
		<li id="endnote_{#row}">{text()}<a href="#marker_{#row}">^</a></li>
	</txp:variable>
</txp:etc_query>

<!-- now retrieve what needed where needed -->

<txp:etc_query markup="data" data="endnotes" query="div[1]/node()" />
...
<txp:etc_query markup="data" data="endnotes" query="div[2]/node()" />
...
<ol><txp:variable name="endnotes" /></ol>

That’s more readable and flexible, without significant performance drop.

Last edited by etc (2013-09-12 19:59:44)

Offline

#12 2017-06-02 18:50:30

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 987
Website

Re: From PHP to txp:plugin -- need help troubleshooting!

Oh, dear. I humbly ask for some help with this strange issue.

Some time ago, @etc helped me cook up a way to parse the body text of an article for my PrinceXML footnote markup to output the footnotes as an ordered list of endnotes.

This solution has worked with everything we threw at it. But I never imagined giving it an article text that did not contain footnote markup.

Here’s the code, at the time of this writing:

<txp:if_variable name="endnote_no">

  <txp:else />

  <txp:variable name="endnote_no" value="0"/>

</txp:if_variable>


<txp:etc_query
  data='<txp:body />'
  globals="variable"
  query="//span[@class='fnt']"
  replace='&=<sup><a href="#endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>" id="marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>">{$+({?endnote_no}|{#row})}</a></sup>'
  specials="replace,content"
  >

  <txp:variable name="endnotes">

    <txp:variable name="endnotes"/>

    <li id='endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>{text()} <a href='#marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>^</a></li>

  </txp:variable>

  {$=({#row}|{#rows}).?({//body/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

</txp:etc_query>

This works perfectly, as long as the <txp:body /> text contains the pattern etc_query is looking for<span class='fnt'>Footnote text here</span>.

But if the body contains no footnotes, the output is empty. Same behavior using versions 1.3.3 and 1.2.7 of etc_query.

The trouble is, I need it to return the body text even when it doesn’t contain any footnotes.

@etc, I know you’re a busy person. Can you offer any guidance?

Thank you!

Edit: Fix textile.

Last edited by johnstephens (2017-06-02 18:56:24)

Offline

#13 2017-06-05 21:15:42

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 987
Website

Re: From PHP to txp:plugin -- need help troubleshooting!

I found a solution!

In cases where the target pattern //span[@class=‘fnt’] doesn’t exist in the content, I don’t need to run the search-and-replace with etc_query.

So, after learning a little about XPath, I set a variable that gets content only when the target pattern is present in the content. Then I use Textpattern’s if_variable to check it: If the target pattern isn’t there, I return the content without parsing it with etc_query. If the target pattern is present, I run search and replace, as follows:

<txp:variable name="has_notes"><txp:etc_query data='<txp:body />' query="//span[@class='fnt']"/></txp:variable>

<txp:if_variable name="has_notes" value="">

  <txp:body />

  <txp:else/>






  <txp:etc_query
    data='<txp:body />'
    globals="variable"
    query="//span[@class='fnt']"
    replace='&=<sup><a href="#endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>" id="marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>">{$+({?endnote_no}|{#row})}</a></sup>'
    specials="replace,content"
    >

    <txp:variable name="endnotes">

      <txp:variable name="endnotes"/>

      <li id='endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>{text()} <a href='#marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>^</a></li>

    </txp:variable>

    {$=({#row}|{#rows}).?({//body/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

  </txp:etc_query>

</txp:if_variable>

Last edited by johnstephens (2017-06-05 21:16:50)

Offline

Board footer

Powered by FluxBB