Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>For this kind of thing, parse the entries in a state-machine loop.</p> <p>The following code was always the first answer to:</p> <ol> <li>Group the HTML as specified in the question. </li> <li>Provide click control to expand/contract the groupings.</li> <li>Collapse entries to start -- for better initial overview.</li> </ol> <p><a href="http://jsfiddle.net/6Cvaw/" rel="nofollow"><strong>See a demo of it at jsFiddle.</strong></a> </p> <h2>UPDATE:</h2> <p>The question's HTML did not match <a href="http://jsbin.com/ureyin" rel="nofollow">the actual page structure</a>. Updated the script below to account for that, and also added the CSS to the script-code:</p> <pre class="lang-js prettyprint-override"><code>var containerNode = document.querySelector ("p font xpre"); var contentNodes = containerNode.childNodes; var tempContainer = document.createElement ("div"); var groupingContainer = null; var hidableDiv = null; var bInEntry = false; var bPrevNodeWasBr = false; for (var J = 0, numKids = contentNodes.length; J &lt; numKids; ++J) { var node = contentNodes[J]; //--- Is the node an entry start? if ( node.nodeType === Node.TEXT_NODE &amp;&amp; bPrevNodeWasBr &amp;&amp; /^\s*\w.*\s\(.+?\)\s+-\s+\w.+?:\s*$/.test (node.textContent) ) { //--- End the previous grouping, if any and start a new one. if (bInEntry) { groupingContainer.appendChild (hidableDiv); tempContainer.appendChild (groupingContainer); } else bInEntry = true; groupingContainer = document.createElement ("div"); groupingContainer.className = "groupingDiv"; /*--- Put the entry header in a special &lt;span&gt; to allow for expand/contract functionality. */ var controlSpan = document.createElement ("span"); controlSpan.className = "expandCollapse"; controlSpan.textContent = node.textContent; groupingContainer.appendChild (controlSpan); //--- Since we can't style text nodes, put everythin in this sub-wrapper. hidableDiv = document.createElement ("div"); } else if (bInEntry) { //--- Put a copy of the current node to the latest grouping container. hidableDiv.appendChild (node.cloneNode(false) ); } if ( node.nodeType === Node.ELEMENT_NODE &amp;&amp; node.nodeName === "BR" ) { bPrevNodeWasBr = true; } else bPrevNodeWasBr = false; } //--- Finish up the last entry, if any. if (bInEntry) { groupingContainer.appendChild (hidableDiv); tempContainer.appendChild (groupingContainer); } /*--- If we have done any grouping, replace the original container contents with our collection of grouped nodes. */ if (numKids) { while (containerNode.hasChildNodes() ) { containerNode.removeChild (containerNode.firstChild); } while (tempContainer.hasChildNodes() ) { containerNode.appendChild (tempContainer.firstChild); } } //--- Initially collapse all sections and make the control spans clickable. var entryGroups = document.querySelectorAll ("div.groupingDiv span.expandCollapse"); for (var J = entryGroups.length - 1; J &gt;= 0; --J) { ExpandCollapse (entryGroups[J]); entryGroups[J].addEventListener ("click", ExpandCollapse, false); } //--- Add the CSS styles that make this work well... addStyleSheet ( " \ div.groupingDiv { \ border: 1px solid blue; \ margin: 1ex; \ padding: 1ex; \ } \ span.expandCollapse { \ background: lime; \ cursor: pointer; \ } \ div.groupingDiv span.expandCollapse:before { \ content: '-'; \ background: white; \ font-weight: bolder; \ font-size: 150%; \ padding: 0 1ex 0 0; \ } \ div.groupingDiv span.expandCollapse.collapsed:before { \ content: '+'; \ } \ " ); //--- Functions used... function ExpandCollapse (eventOrNode) { var controlSpan; if (typeof eventOrNode.target == 'undefined') controlSpan = eventOrNode; else controlSpan = eventOrNode.target; //--- Is it currently expanded or contracted? var bHidden; if (/\bcollapsed\b/.test (controlSpan.className) ) { bHidden = true; controlSpan.className = controlSpan.className.replace (/\s*collapsed\s*/, ""); } else { bHidden = false; controlSpan.className += " collapsed"; } //--- Now expand or collapse the matching group. var hidableDiv = controlSpan.parentNode.children[1]; hidableDiv.style.display = bHidden ? "" : "none"; } function addStyleSheet (text) { var D = document; var styleNode = D.createElement ('style'); styleNode.type = "text/css"; styleNode.textContent = text; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; //--- Don't error check here. if DOM not available, should throw error. targ.appendChild (styleNode); } </code></pre> <hr> <p>If nested/quoted entries are to be wrapped separately, you will also need to recurse. For nested/quoted entries, open a new question after this one is answered.</p> <p>Note: The new sample HTML has multiple pairs of <code>&lt;html&gt;</code> tags and 2 sets of entries! This is probably a cut-and-paste error, but if it is not, open a new question if help is needed for the easy mod to process multiple sets.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload