@thomas forgot to mention, there is still indentation happening: because of the interleaving of the ul and il tags themselves. which are meant exactly for that use.
On Sunday, September 14, 2025 at 6:17:42 PM UTC-4 Félix wrote: > @Thomas > > That indentation is not meant to be rendered, it was just to indent the > html code to be more human readable. > (you are right that spaces inside tags as text content are all collapsed) > > On Sunday, September 14, 2025 at 5:53:43 PM UTC-4 tbp1...@gmail.com wrote: > >> Could you post a sample HTML output, please? >> >> On Sunday, September 14, 2025 at 4:00:18 PM UTC-4 brian wrote: >> >>> @Félix >>> >>> Attached is the first version of leo to html plugin I wrote and a sample >>> leo file I ran with. >>> >>> Overview of code: >>> - plugin called “s_leo_to_html”. I’m not sure best naming convention >>> within leo plugin. >>> - the class “HTMLDataWrapper” reads the leo outline and creates a >>> DataWrapper Pydantic object. DataWrapper includes options and pydantic >>> nodes. This is first time trying to write a leo plugin so I expect this >>> class to be hacky. Let me know if you have improvements. >>> - the class “GenerateHTMLFromNodesFactory” takes the DataWrapper >>> Pydantic object and uses Django to create the html. I wrote a normal >>> Django app to develop the templates and Pydantic models and then I pasted >>> the templates and Pydantic models into this leo plugin. The html can be >>> changed by editing the template. The node body is rendered with a markdown >>> render. I’m using Django 4.2. I haven't tested this with errors in the >>> html templates. I believe this code is solid. >>> - I have 3 loggers setup – python standard out, leo, and file. Search >>> for the line “logLevel =” to set the debug level. I currently have at >>> DEBUG level. The INFO level will produce less output. I’m not sure how >>> leo handles logging so it may not fit into the leo framework. You can >>> comment out all loggers or just handlers don’t want. Now that I think >>> about it, it seems the plugin method should use the leo method to write to >>> log console. Let me know if you suggests to better fit into the leo >>> framework. >>> - The class “sTiming” has a timer to track how long plugin took and >>> creates in a human readable format. >>> >>> I chose LEO ->Pydantic models -> html to help separate the processes. >>> I’m not sure if Django can be used dynamically like you are doing with >>> generating raw html. Also, with the Pydantic models approach, I could >>> write different output formats. I put all my html specific settings in >>> the HTMLDataWrapper Pydantic model so I could swap in other output formats >>> later. . >>> >>> In the html, I wanted cloned nodes reproduced. I'm thinking of ways I >>> can add 'go to clone' like feature in html. >>> >>> Brian >>> >>> On Sunday, September 14, 2025 at 3:40:21 PM UTC-4 tbp1...@gmail.com >>> wrote: >>> >>>> That's a nice simple example of using recursion. A point, not about >>>> the recursion but about the HTML - I'd like to point out that the rendered >>>> HTML won't show the indentation properly because all spaces will be >>>> collapsed into a single space. So >>>> >>>> f"\n{indent} <pre> >>>> >>>> won't show as intended. One way I've handled this is to use CSS to >>>> create the indents. Each <ul> or <li> element, for example, could use >>>> relative positioning with left padding. You can also produce a left >>>> margin >>>> line by specifying a left border for the elements. For example, in one >>>> project, I used a CSS class "term" for my indented items, and the CSS to >>>> produce the indent with margin line was >>>> >>>> .terms {border-left:1px lightgrey solid;} >>>> .terms {margin-left:0em; padding-left: 1.2em} >>>> >>>> On Sunday, September 14, 2025 at 1:22:09 PM UTC-4 Félix wrote: >>>> >>>>> Ah! jkn, *Very good question!!* >>>>> >>>>> That is because I'm not using positions and going from node to node >>>>> sequentially (and having to keep track of level, and keeping track of >>>>> level >>>>> going back lower to *close tags* when finishing doing children) >>>>> >>>>> I'm using the underlying vnodes, and *recursion*, thus simplifying >>>>> everything as I know exactly the levels going up/down as its tied >>>>> directly >>>>> to entering/exiting the doChildren function. (as opposed to using >>>>> 'c.all_nodes' for all vnodes in outline order, or 'c.all_positions' for >>>>> the >>>>> same but with positions) >>>>> >>>>> If you dont use recursion, again, you have then to keep track of the >>>>> current level you are outputting in order to know when to 'close' opened >>>>> tags. >>>>> >>>>> To illustrate this precise point, note that this canonical example >>>>> about generators at >>>>> https://leo-editor.github.io/leo-editor/tutorial-scripting.html#generators >>>>> >>>>> does NOT care about closing any tags, thus is totally ok with >>>>> "c.all_positions" >>>>> >>>>> >>>>> for p in c.all_positions(): >>>>> print(' '*p.level()+p.h) >>>>> >>>>> >>>>> Please take a few minutes to study this construction and its output - >>>>> compared to using 'Positions' (which do have their uses in other >>>>> scenarios). >>>>> def doChildren(children, level=0): >>>>> global output >>>>> for child in children: >>>>> indent = indentation * level >>>>> output += f"\n{indent} <li>" >>>>> output += f"\n{indent} <b>{child.headString()}</b>" >>>>> # output += f"\n{indent} >>>>> <pre>\n{child.bodyString()}\n{indent} </pre>" >>>>> output += f"\n{indent} <ul>" >>>>> doChildren(child.children, level + 1) >>>>> output += f"\n{indent} </ul>" >>>>> output += f"\n{indent} </li>" >>>>> >>>>> output += "<ul>" >>>>> doChildren(c.hiddenRootNode.children) >>>>> output += "\n</ul>" >>>>> g.es(output) >>>>> >>>>> Félix >>>>> On Sunday, September 14, 2025 at 7:40:19 AM UTC-4 jkn wrote: >>>>> >>>>>> Out of interest ... I haven't seen the use of child.headstring() and >>>>>> child.bodystring() before. Are these basically equivalent to p.h and >>>>>> p.b? >>>>>> Is one form to be preferred? >>>>>> >>>>>> Thanks, J^n >>>>>> >>>>>> On Thursday, September 11, 2025 at 4:00:39 AM UTC+1 Félix wrote: >>>>>> >>>>>>> @Edward @Thomas @jkn >>>>>>> >>>>>>> Ah! I'm so silly! Here's a much better (and smaller) minimal >>>>>>> example who's output can be saved in a file and dragged onto your >>>>>>> browser, >>>>>>> using vnodes instead of positions. (uncomment that line for bodies >>>>>>> too): >>>>>>> >>>>>>> >>>>>>> output = '' >>>>>>> indentation = ' ' >>>>>>> level = -1 >>>>>>> >>>>>>> def doChildren(children, level=0): >>>>>>> global output >>>>>>> for child in children: >>>>>>> indent = indentation * level >>>>>>> output += f"\n{indent} <li>" >>>>>>> output += f"\n{indent} <b>{child.headString()}</b>" >>>>>>> # output += f"\n{indent} >>>>>>> <pre>\n{child.bodyString()}\n{indent} </pre>" >>>>>>> output += f"\n{indent} <ul>" >>>>>>> doChildren(child.children, level + 1) >>>>>>> output += f"\n{indent} </ul>" >>>>>>> output += f"\n{indent} </li>" >>>>>>> >>>>>>> output += "<ul>" >>>>>>> doChildren(c.hiddenRootNode.children) >>>>>>> output += "\n</ul>" >>>>>>> g.es(output) >>>>>>> >>>>>>> >>>>>>> @brian I havent had the chance to look at your source leo file... (I >>>>>>> didnt notice it, and had only looked at your 'desired output file' oops >>>>>>> !!) >>>>>>> >>>>>>> I now understand your @tool-tip nodes and what you were going >>>>>>> for. >>>>>>> >>>>>>> I'll have some more time in the weekend to make a script that really >>>>>>> goes from your leo file example to your 'desired' output HTML file. >>>>>>> >>>>>>> Again - thanks for your interest in Leo - and sorry for that delay! >>>>>>> >>>>>>> Félix >>>>>>> On Tuesday, September 9, 2025 at 1:29:48 PM UTC-4 Edward K. Ream >>>>>>> wrote: >>>>>>> >>>>>>>> On Tue, Sep 9, 2025 at 11:37 AM brian <yakka...@gmail.com> wrote: >>>>>>>> >>>>>>>>> @Félix >>>>>>>>> >>>>>>>>> I cannot see the suggestions by Edward about merging that >>>>>>>>> 'all_root_children' into the commander's generators. >>>>>>>>> >>>>>>>> >>>>>>>> The devel branch now contains the new code. I merged it a few hours >>>>>>>> ago. >>>>>>>> >>>>>>>> Edward >>>>>>>> >>>>>>> -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/leo-editor/adfdb430-de4b-419c-9a94-a81b387180d1n%40googlegroups.com.