Tomorrow, I'll see whether the suggested function that perplexity.ai gave me does what I want.
Category Archives: Uncategorized
MIC 04-3 Non-recursive walk of a panflute document
Next round of programming yields:
def panflute_to_bike_etree_nr(e, level=0) -> ET.Element:
# questions about how header levels are handled as we put them into the etree
etree = None
stack = [(e, level)]
# current ul_elem
ul_elem = None
heading_level = 0
while stack:
(e, level) = stack.pop()
print(" " * level, e.tag)
if is_inline_or_contentless(e):
li_elem = ET.Element("li")
# TO DO: handle rich text
p_elem = ET.SubElement(li_elem, "p")
p_elem.text = pf.stringify(e).strip()
# 2 things to figure out: parent_ul (where to attach li_elem) and what the current ul_elem is
if e.tag == "Header":
print ("header", e.level, e.identifier, e.classes, e.attributes, pf.stringify(e))
li_elem.attrib["data-type"] = "heading"
li_elem.attrib["data-level"] = str(e.level)
if e.level > heading_level:
# child
parent_ul = ul_elem
print ("e.level > heading_level", ul_elem)
elif e.level == heading_level:
# sibling
# parent_ul has to be ul parent of ul_elem
parent_ul = ul_elem.getparent().getparent()
else:
# e.level < heading_level
# uncle or higher
parent_ul = find_ul_ancestor(ul_elem, int(e.level)-1)
heading_level = e.level
ul_elem = ET.SubElement(li_elem, "ul")
parent_ul.append(li_elem)
else:
ul_elem.append(li_elem)
else:
if e.tag == "Doc":
etree = empty_bike_etree()
ul_elem = etree.xpath("//ul")[0]
else:
# BulletList
# OrderedList
# ListItem
print("block", e.tag)
try:
for c in reversed(e.content):
stack.append((c, level + 1))
except AttributeError:
pass
# clean up etree by adding ids
etree = add_ids_to_bike_etree(etree)
return etree
MIC-04-2 some progress
My first pass -- taking a recursive approach:
def panflute_to_bike_etree(pfe) -> ET.Element:
"""
pfe: panflute element
base_header_level: the base header level to use for the document
TO DO: handle different header levels -- might need to abandon this approach in favor of non-recursive approach with a manual stack
"""
if is_inline_or_contentless(pfe):
p_elem = ET.Element("p")
p_elem.text = pf.stringify(pfe).strip()
return p_elem
else:
if pfe.tag == "Doc":
etree = empty_bike_etree()
ul_elem = etree.xpath("//ul")[0]
else:
ul_elem = ET.Element("ul")
try:
for c in pfe.content:
e = panflute_to_bike_etree(c)
li_elem = ET.SubElement(ul_elem, "li")
li_elem.append(e)
except AttributeError:
pass
else:
if pfe.tag == "Doc":
etree = add_ids_to_bike_etree(etree)
return etree
else:
return ul_elem
MIC-04-1 Will structural pattern matching help me?
On my to-study list is a tutorial on PEP 636 -- Structural Pattern Matching: Tutorial | peps.python.org that I think will be useful to my work to convert the pandoc AST to a bike outline:
- Structural Pattern Matching in the Real World - Raymond Hettinger - YouTube
- Raymond Hettinger on X: \"Here\'s a PDF for my #Python #PyConIT2022 talk: Structural Pattern Matching in the Real World: New tooling, real code, problems solved. This is intermediate and advanced level Structural Pattern Matching. tl;dr The "good stuff" is in section 1.2 https://t.co/CwguxhRaZS\" / X
MIC-03-5 Figuring out how to use multiple versions of pandoc
Until today, I didn't worry about the specific version of pandoc
I used. However, as pandoc continues to evolve, there might be differences that affect the computations I conduct with pandoc, pypandoc, panflute, and the pandoc Python library. I don't have the energy this evening to write what I learned. Stay tuned.
MIC-03-4 Working on the plan I wrote about yesterday
Not much to say except to say that I'm on track.
MIC-03-3 Starting to write a Pandoc writer for Bike
Today, I am focused on creating a first cut of a pandoc writer for Bike. I will start by having a writer emit the simple output of a valid but empty Bike document. The next step would be to have the writer flatten a pandoc AST into a single list of plain text Bike nodes. I defer dealing with the rich text and hierarchical structures until I have the simple writer in place. Dealing with rich text and containment of elements requires me to better grok the pandoc AST, particularly what can contain which other element. I will use pandoc (Python library) and panflute interactively in a Jupyter notebook to facilitate that grokking. I aim for good coverage of pandoc AST examples by writing pandoc markdown, which I then convert to pandoc JSON (note the documentation on pandoc markdown.
Ideally, my pandoc Bike reader and writer will enable lossless roundtripping of Bike conversion. In other words, if I use the reader to convert a bike document to pandoc JSON and then use my pandoc Bike writer to convert the JSON to a Bike document, the resulting Bike document should essentially be the same the original document.
A question to answer as I dive into the pandoc writer for Bike: how to handle parts of the pandoc AST that I don\'t know how to translate into Bike elements but would nonetheless like to park in some placeholding structure?
MIC-03-2 My Bike outline automatically converted to markdown for Obsidian
I\'m pleased that I reached a programming milestone. Now whenever I save my main Bike outline (overall.bike
), my CLI for interacting with Bike (and Bike outlines) is fired off (specifically, bike.py pandoc)
. I use Hammerspoon to look for changes in the enclosing directory for overall.bike
and then I have some logic to check for telltale changes in overall.bike
. I was stuck for a while: It turns out that the tricky part is detecting reliably whether there is data on stdin. My solution is good enough for now, but I will probably revisit it.
MIC-03-1 Writing and programming all day: so close
I've been writing all day, with a fluency that I've not had in a long while. What I've written isn't ready for sharing with the public, however. I've also made some good progress in getting my script to run but I'm stuck on an issue that might take 10 more minutes to solve -- or hours. I'm surprised that I'm serenely accepting however long it ends up taking. What choice do I have?
MIC-02-5 Small progress during a busy end of week
I set the stage for command groups in bike.py with [my latest change to bike.py](added sel2pb command to bike.py ยท rdhyee/python-learning@a161fe9).
It seems that Keyboard Maestro doesn't allow for watching for changes in files that already exist. Maybe, more likely, I've just not been able to figure out how. I have some progress using hammerspoon though. Here's a relevant part of my init.lua
:
function list_true_flags(flags)
local true_flags = " "
for key, value in pairs(flags) do
if value then
true_flags = true_flags .. key .. " | "
end
end
return true_flags
end
function fileModifiedCallback(paths, flagTables)
for i, file in ipairs(paths) do
if file == "/Volumes/ryvault1/MacHD/Users/raymondyee/obsidian/MainRY/bike/overall.bike" then
local flags = flagTables[i]
print(i, file)
print_true_flags(flags)
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
-- local message = timestamp .. " overall.bike changed\n"
local logFile = io.open("/tmp/hschange.log", "a")
logFile:write(timestamp .. list_true_flags(flags) .. "\n")
logFile:close()
end
end
end
watcher = hs.pathwatcher.new("/Volumes/ryvault1/MacHD/Users/raymondyee/obsidian/MainRY/bike", fileModifiedCallback)
watcher:start()