@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.

Reply via email to