@Thomas *About the HTML end result:* His customer/ end users may actually want that type of front-end layout (big bootstrap accordions, tooltips, etc.) his product may be some documentation for non-technical users for whom those types of rich front end components are desired.
*About using external libraries: *In modern web development and front end production, those 'bootstrap', 'react', 'tailwind' are common usage. Respectfully, I'd like to say: Let's try not to comment like on stackoverflow, where instead of answering what the original poster asked, (in its given context or constraints & requirements), they tell them his question is wrong and he should do his project completely differently. Hoping I'm not coming across as inappropriate with that last remark... In a spirit of friendship, :) Félix On Sunday, September 14, 2025 at 11:46:48 PM UTC-4 [email protected] wrote: > Thanks. It seems to me that the HTML is much more complicated than it > needs to be. For one thing, I would prefer that the page will work without > an Internet connection. There is nothing going on in the page that > requires Internet calls. For another, the page can be much simpler, to the > point that I don't see why any templating machinery is needed. I admit that > if you insist on those timed transitions and some other visual features > that the code would get more complicated. I personally would not bother - > an easily readable, simple layout is what I would be going after. The tool > tips also add a little complication, especially as I don't like them > showing up whether or not I want them. I think that could be handled > fairly easily, again without needing a template of Django. > > On Sunday, September 14, 2025 at 7:37:43 PM UTC-4 brian wrote: > >> @tbp1 >> >> Attached is html generated from the sample_input4.leo. I don't believe I >> changed the html from the earlier post. My main work was converting flat >> html to Django template. >> >> Brian >> >> On Sunday, September 14, 2025 at 6:19:25 PM UTC-4 Félix wrote: >> >>> @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 [email protected] >>>> 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 [email protected] >>>>>> 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 <[email protected]> >>>>>>>>>>> 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 [email protected]. To view this discussion visit https://groups.google.com/d/msgid/leo-editor/0e535c7f-7953-4df7-bf1a-6c6c2c385c52n%40googlegroups.com.
