-
Leo Editor - 簡單的節點控制
簡述 Leo Editor 的 @button 節點運用。
-
預先定義名稱:c、g、p
-
Vnode
-
Position
-
Generator
-
使用 @button 複製節點正文
-
-
Pyslvs 手冊應用
Leo Editor - 簡單的節點控制
參考資料:
預先定義名稱:c、g 和 p
在可執行腳本中預先定義的符號 c、g 和 p。
c 為包含腳本大綱的 commander。
- Commander 為指令類別的實體(instance),在
leoCommands.py
文件中定義。 - Commander 提供了所有大綱資料與 Leo 原始碼的權限。
g 為 Leo 的 leo.core.leoGlobals 模組。
- 這個模組包含許多實用的函式,如
g.es
。
p 是當前選擇節點的 position。
- position 為位置類別的實體,在
leoNodes.py
文件中定義。 - 位置類型提供安全、方便的方式來存取與修改大綱節點。
- 對於任何位置的
p
,p.v
是一個 vnode 物件。 - vnode 包含所有在 Leo 大綱的永久資料。
Vnode
vnode 為 vnode 類別的實體,在 leoNodes.py
文件中定義。每個 vnode 代表關聯著一個大綱節點的所有資訊,包含著專用數據帶有它的大鋼結構。
- v.b 是(大綱)節點的正文(body text)。
- v.h 是節點的標題(headline)。
- v.u 是節點的使用者資訊。
所有分身節點共用同一個 vnode。反之,每個 vnode 表示出所有分身相應的節點。
由於單一個 vnode 可以代表多個大綱節點,直接使用 vnode 會變得較尷尬。這就是為何出現 position:position 簡化對 vnode 的存取。
Position
一個 position 代表一個具體的大綱節點在大綱一個精確的位置上,position 為位置類別的實體,在 leoNodes.py
文件中定義。
- 在位置
p
上的 vnode 就是p.v
。 - 由於所有分身共用一樣的 vnode,多個 position 可能會擁有一樣的
p.v
內容。 p.b
、p.h
、p.u
代表著p.v.b
、p.v.h
、p.v.u
。- 對於任何一個 Commander
c
,c.p
為當前選擇的節點。
position 常因為大綱結構改變而變成無效。腳本應當只在確保大綱結構不會發生任何改變時儲存位置以供稍後使用。
c.positionExists(p)
會在c.p
仍為有效值時回傳 True。
Generator
Leo 的 Generator 即為 Python generator,這些 generator 追蹤(逐漸地)Leo 大綱的一個個節點:Leo generators yield 出一個位置序列。
命令(commander)和位置類別定義了數個 generator,c.all_positions()
隨著大綱順序追蹤大綱。下面的程式 print 出正確縮排的標題清單。
for p in c.all_positions(): print(' '*p.level()+p.h)
Leo generator yield(回傳一個環節)出 position。它們不會回傳一個實際的 list;這為大型的大綱節省了不少空間。事實上,這個位置序列其實是一個單一、不斷變化位置的序列。這是一個非常重要的空間優化。
當一個 generator 已經回傳完成,這個單一位置變成了一個空的 position。p.v
會在空的 position 為 None。這裡有正確及錯誤的方式測試空的 position。
if not p: # Right if not p.v: # Right if p is None: # Wrong!
為了避免上述情形,應當使用 copy()
方法複製 vnode 與 position 類型的物件,再予以修改。
使用 @button 複製節點正文
自己做了一個按鈕程式來應用 Leo editor 的腳本功能。
目標:將 I 節點下的 Hellow World! 文章改名複製到 J 節點下。
由於還不太熟悉 Leo 的 generator,先用比較生疏的方式指定目標。
複製節點文章程式:
pList = [e.copy() for e in c.all_positions()] nList = [e.h for e in c.all_nodes()] bList = [e.b for e in c.all_nodes()] Istart = nList.index("I")+1 Iend = nList.index("i-c")+1 Jstart = nList.index("J")+1 Jend = nList.index("j-c")+1 B = bList[Istart:Iend] P = pList[Jstart:Jend] B = [e.replace('i', 'j') for e in B] for e in range(len(P)): P[e].b = B[e] g.es('Copied!')
清空節點文章程式:
pList = [e.copy() for e in c.all_positions()] nList = [e.h for e in c.all_nodes()] Jstart = nList.index("J")+1 Jend = nList.index("j-c")+1 P = pList[Jstart:Jend] for e in range(len(P)): P[e].b = '' g.es('Cleaned!')
列出 position 和 vnode 程式:
pList = [str(e.copy()) for e in c.all_positions()] nList = [str(e.copy()) for e in c.all_nodes()] g.es('\n'.join(pList)) g.es('\n'.join(nList))
Pyslvs 手冊應用
使用 Leo editor 的腳本功能達成轉換 Pandoc 特殊語法。
目前功能:
- 及時裁切處理 Markdown 文件,輸出 Reveal.js 的 Markdown + html 語法到指定節點(Target node)。
- 切開
\newpage
記號成水平投影片。 - 圖片參照記號移除,但是內文的還未解決。
- 其他皆按照 data-markdown 的功能排版。
程式還有些雜亂,之後會整修一下。
轉換程式:
pList = [e.copy() for e in c.all_positions()] nList = [e.h for e in c.all_nodes()] bList = [e.b for e in c.all_nodes()] Istart = nList.index("@clean {}.md".format(filename)) Iend = nList.index("@clean reveal.js/{}.html".format(filename)) pos = nList.index("{} Target node".format(filename)) B = bList[Istart:Iend] P = pList[pos] B[0] = B[0].replace("%", "##")+"\n\\newpage" B = ''.join(B).replace("\n@language md", '').replace("\n@others", '').split("\n\n\\newpage") head = """""" B = [head+e+tail for e in B] P.b = removeParentheses("@language html\n"+'\n'.join(B)) g.es("{} HTML 簡報轉換完畢".format(filename))
移除圖片參照專用函式 removeParentheses()
:
def removeParentheses(content): while content.find("{")!=-1: start = content.find("{") end = content.find("}")+1 result = content[start:end] content = content.replace(result, '') return content
轉換過程不會用到外部程式,三份 html 文件都是共用同一份 js 檔案。
Comments
comments powered by Disqus