javascript - Dynamically group poorly-structured HTML, that has no IDs? -


there old website use , data not displayed in friendly fashion. write userscript (javascript/jquery) assists readability of site. content looks (the html comments own, show this):

<font size="3" face="courier">   <br>   <!-- begin entry 1 -->   name1 (location1) - date1:   <br>   text1   <br>   text1 (continued)   <br>   text1 (continued)   <br>   <br>   <!-- begin entry 2 -->   name2 (location2) - date2:   <br>   text2   <br>   text2 (continued)   <br>   <br>   text2 (continued)   <br>   text2 (continued)   <br>   <br>   <!-- begin entry 3 -->   name3 (location3) - date3:   <br>   text3   <br>   text3 (continued)   <br>   text3 (continued)   <br>   <br>   <br>   text3 (continued)   <br>   text3 (continued)   <!-- below text3, user copied entry1 here -->    name1 (location1) - date1: <!-- text3 -->   <br> <!-- text3 -->   text1 <!-- text3 -->   <br> <!-- text3 -->   text1 (continued) <!-- text3 -->   <br> <!-- text3 -->   text1 (continued) <!-- text3 -->   <br>   <br>   <!-- begin entry 4 -->   name4 ...   ...... </font> 
  • example of names: bob dole, smith,john
  • example of locations: via web, internal
  • example of dates: jul 25, 2011 - 1317 edt, dec 30, 2011 - 1411 est
  • example of text1/text2/etc: blah blah * (test) text goes here -thanks here: there

as can see, 2 <br> come before next "entry" (name, location, date) since text free text can contain various <br> including 2 or more. issue if text contains name (location) - date pasted entry elsewhere.

so if wanted write script added google chrome added button collapse (or uncollapse if collapsed) each entry, possible? issue i'm having since there no unique element starting or ending entry, i'm not sure how begin this.

the general concept loop through each "entry" (header being name/location/date) , text follows until next header) , allow each "entry" collapsible (such reddit comments collapsible).

or more simple concept, if wanted mark every other entry red font? of entry1 black font, entry2 red font, entry3 black font, entry4 red font, , on.

for kind of thing, parse entries in state-machine loop.

the following code first answer to:

  1. group html specified in question.
  2. provide click control expand/contract groupings.
  3. collapse entries start -- better initial overview.

see demo of @ jsfiddle.

update:

the question's html did not match the actual page structure. updated script below account that, , added css script-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;  (var j = 0, numkids = contentnodes.length;  j < numkids;  ++j) {     var node            = contentnodes[j];      //--- node entry start?     if (    node.nodetype === node.text_node         &&  bprevnodewasbr         &&  /^\s*\w.*\s\(.+?\)\s+-\s+\w.+?:\s*$/.test (node.textcontent)     ) {         //--- end previous grouping, if , start new one.         if (binentry) {             groupingcontainer.appendchild (hidablediv);             tempcontainer.appendchild (groupingcontainer);         }         else             binentry        = true;          groupingcontainer   = document.createelement ("div");         groupingcontainer.classname = "groupingdiv";          /*--- put entry header in special <span> allow             expand/contract functionality.         */         var controlspan         = document.createelement ("span");         controlspan.classname   = "expandcollapse";         controlspan.textcontent = node.textcontent;         groupingcontainer.appendchild (controlspan);          //--- since can't style text nodes, put everythin in sub-wrapper.         hidablediv          = document.createelement ("div");     }     else if (binentry) {         //--- put copy of current node latest grouping container.         hidablediv.appendchild (node.clonenode(false) );     }      if (    node.nodetype === node.element_node         &&  node.nodename === "br"     ) {         bprevnodewasbr  = true;     }     else         bprevnodewasbr  = false; }  //--- finish last entry, if any. if (binentry) {     groupingcontainer.appendchild (hidablediv);     tempcontainer.appendchild (groupingcontainer); }  /*--- if have done grouping, replace original container contents     our collection of grouped nodes. */ if (numkids) {     while (containernode.haschildnodes() ) {         containernode.removechild (containernode.firstchild);     }      while (tempcontainer.haschildnodes() ) {         containernode.appendchild (tempcontainer.firstchild);     } }  //--- collapse sections , make control spans clickable. var entrygroups         = document.queryselectorall ("div.groupingdiv span.expandcollapse"); (var j = entrygroups.length - 1;  j >= 0;  --j) {     expandcollapse (entrygroups[j]);      entrygroups[j].addeventlistener ("click", expandcollapse, false); }   //--- add css styles make 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;      //--- 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";     }      //--- expand or collapse 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); } 

if nested/quoted entries wrapped separately, need recurse. nested/quoted entries, open new question after 1 answered.

note: new sample html has multiple pairs of <html> tags , 2 sets of entries! cut-and-paste error, if not, open new question if needed easy mod process multiple sets.


Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -