inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 13, 2013 16:09:30 GMT -8
ok, since drafts don't seem to be working, I've lost my explanation twice already... so screw the plugin's description, I'll hit it when I feel like typing it again. so what I'm currently trying to do is get a bunch of lines of text into nested array elements. the outer container element (in BBC) is [tree] each line between these elements is a single node of the tree, where [node] is a nested node array what I'm trying to figure out is how to get something like this: [tree]node0 node1 [node]node2 node2-0 node2-1 [node]node2-2 node2-2-0[/node][/node] [node]node3 node3-0 [/node] [/tree] into something like this: [ "node0", "node1", ["node2", "node2-0", "node2-1", ["node2-2", "node2-2-0"]], ["node3", "node3-0] ] I can get it to look like this example from here. thanx
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 14, 2013 7:44:52 GMT -8
ok, I've put down the JS and went over to python for my tests, so far this is what I've got: post = 'node0<br>node1<br>[node]node2<br>node2-0<br>node2-1<br>[node]node2-2<br>node2-2-0[/node]node2-3[/node]<br>[node]node3<br>node3-0<br>[/node]' #imitating the post text between the [tree] tags
nlevel = 0 for level,data in enumerate(post.split('[node]')): for T,node in enumerate(data.split('[/node]')): if T>0: nlevel+=1 singles = node.split('<br>') for N,single in enumerate(singles): if single=='': continue outer = (1 if len(singles)>1 else 0) if N==0 else 0 print ''.join([' ']*(level-nlevel-outer))+single output: >>> node0 node1 node2 node2-0 node2-1 node2-2 node2-2-0 node2-3 node3 node3-0 but I'm not exactly sure how to check for the last node on the current level :/ (meaning the last node will continue drawing the line for the rest of the level where it should be spaced) any help here is appreciated. thanx
|
|
inherit
The Dream Crusher (Ret.)
164921
0
Apr 1, 2014 11:00:25 GMT -8
Tim Camara
Teach a man to fish, etc., etc.
1,721
March 2011
tcamara
|
Post by Tim Camara on Nov 14, 2013 12:26:52 GMT -8
What do lines have to do with reading the data into a tree structure? Parsing the data into a tree structure and displaying it like the image you posted is probably easiest done in two steps. Also, I'm not sure how doing this in Python is going to help that much, since you're going to have to write it in JS eventually.
As for detecting the last element in a given array/node/thing, the easiest way is probably just to get the length of the array before you start iterating it. I haven't used Python in a while, so I'm rusty on the syntax, but don't they have a for(i = 0; i < array_length; i++) syntax? If you already know the length of the array, you can easily add a check into that foreach loop for if(i == array_length - 1) or something like that.
You could probably achieve the same effect with CSS using the last-child pseudo class, at least assuming you don't care about how it looks for users with IE7.
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 14, 2013 16:34:28 GMT -8
for i in range( len(array) ):
that's why I was first thinking to build an array of arrays like such: [ 'node0', 'node1', ['node2', 'node2-0', 'node2-1', ['node2-2', 'node2-2-0'], 'node2-3'], ['node3', 'node3-0'] ] but that gets quite complex and is less efficient.
this new code in python tries to do everything in 1 pass by keeping track of the levels by first splitting by "[node]" then splitting by "[/node]" useing detections to keep the nodes on the correct levels... and then finally splitting by "<br>"
and python helps because I can test it better in building the thing... once it works properly in python, I can rewrite later it in JS.
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 15, 2013 9:55:12 GMT -8
ok... I admit... there is no simple way to do it all in 1 pass...
so I've finally figured out how to write a simple parser to return the expandable nodes as nested arrays:
nodes = post.split('<br>') length = len(nodes) index = 0 def parse(): global index,nodes,length; node = [] while True: line = nodes[index] index+=1 if index== length: break #should only be hit once for the outer level if line == "[/node]": break if line == '': continue #skip blank nodes if line.count("[node]"): node += [ [ line.replace("[node]",'') ]+parse() ] else: node += [line] return node
print parse()
works perfectly on a single-line per node only syntax
good: - [node]title<br> - node1<br> - [/node]<br>
bad: - outer-node/title[node]title - node[/node] - [/node][/node]
acceptable: - [node]<br> - [node]<br><br>node
|
|
inherit
The Dream Crusher (Ret.)
164921
0
Apr 1, 2014 11:00:25 GMT -8
Tim Camara
Teach a man to fish, etc., etc.
1,721
March 2011
tcamara
|
Post by Tim Camara on Nov 15, 2013 10:21:29 GMT -8
Well, you could always write a simplified recursive descent parser. That's how we handle most of the places we need to do parsing. You only have three entities, so it shouldn't be terribly complicated. Who knows, maybe someone has written a JS implementation of ANTLR that can do it for you.
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 15, 2013 10:50:02 GMT -8
lol I was just coming back to post I had gotten it in working 2 passes XD here's the 2nd half: (just because I like sharing)
def parsenode(level,data): size = len(data)-1 for i,n in enumerate(data): if type(n)==list: print level+'|- '+n[0] parsenode( level+(' ' if i==size else '| '), n[1:] ) else: print level+'|- '+n
parsenode( '', parse() )
as well as the test code: (the data to parse) post = ''' node0<br> node1<br> [node]node2<br> node2-0<br> node2-1<br> [node]node2-2<br> node2-2-0<br><br> [node]node2-2-1<br> node2-2-1-0<br> node2-2-1-1<br> [/node]<br> [/node]<br> node2-3<br> [/node]<br> [node]node3<br> node3-0<br> [/node]<br> node4<br> [node]node5<br> node5-0<br> node5-1<br> [/node]<br>'''.replace('\n','')
output: >>> |- node0 |- node1 |- node2 | |- node2-0 | |- node2-1 | |- node2-2 | | |- node2-2-0 | | |- node2-2-1 | | |- node2-2-1-0 | | |- node2-2-1-1 | |- node2-3 |- node3 | |- node3-0 |- node4 |- node5 |- node5-0 |- node5-1
I'll look into that reference >.> if it's possible to do it in a single pass, I think that would be more efficient recursive loops like I'm doing thanx
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 15, 2013 15:43:51 GMT -8
ok... so I've converted the code to JS fully, and low and behold, it doesn't work 9_9 could I ask for a hand on a small amount of help?? here's the page where it should be working: tcll5850.proboards.com/thread/173/trees-plugin-darkpikachu-finally-workingwhat I've done is logged a variable to the console... what happens is the var is blank, and I can't seem to figure out why >_> I'm missing something, but I'm not quite sure what... EDIT: the var should be holding the HTML of the finished result... I get no errors throughout the process so everything seems to be working... I just don't get it D:
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 15, 2013 19:49:49 GMT -8
I found out why...
this function:
function Tcll5850_BBC_tree(post) { return post.replace( /\[tree\](.+?)\[\/tree\]/g, Tcll5850_BBC_tree_parser('$1') ); };
what was being sent was '$1' as a string itself rather than the text between the [tree] tags
the fix for this was to use a function rather than a string:
return post.replace( /\[tree\](.+?)\[\/tree\]/g, function(nodes){ })};
|
|
inherit
172351
0
Sept 5, 2019 10:56:35 GMT -8
DarkPikachu
Complexity == Fun
320
October 2011
tcll
|
Post by DarkPikachu on Nov 16, 2013 19:50:07 GMT -8
yea, after fixxing that, I ran into another problem that caused a memory error... turns out it was cause I was using a for loop recursively...
basically, the memory overflow happened on the first occurrence of an expandable node
to put things into perspective, what basically happened was this:
var size = 1; for (i=0; i<size; i++) { //recursive: for (i=0; i<size; i++) { console.log(i) //i is logged from the outer for loop }; };
>>> 0 0 0 0 0 0 ... Memory Overflow: script terminated
so I fixed that by using a while loop
|
|