模擬Scratch的視覺化指令碼編輯器(二)
本次以Markdown流程圖Flow為例,來說明Block擴充套件方法。
流程圖主要有6種Block
#開始 start st=>start: 開始 #結束 end e=>end: 結束 #普通操作塊 opration op1=>opration: 第一個操作塊 op2=>opration: 第二個操作塊 #判斷塊 condition cond1=>condition: 第一個判斷 cond2=>condition: 第二個判斷 #輸入輸出塊 inputoutput io1=>inputoutput: 輸入輸出塊1 io2=>inputoutput: 輸入輸出塊2 #子任務塊 sub1=>subroutine: 子任務1 sub2=>subroutine: 子任務2
根據每個Block的格式,編寫描述檔案,在專案目錄/client/src/scratch/blockDefs/packages目錄下新建一個markdown目錄,在目錄中建立index.js和flow.js。
index.js檔案內容
import flow from './flow'
let blocks = []
blocks = blocks.concat(flow)
export default blocks
flow.js檔案中編寫Block定義,輸出為一個數組。以start單元為例, 先根據start語法規則** [模組名稱]=start: [標題文字]:>[超連結]**,將語法中的主要資料項轉變為section定義 START [index] TAG [模組文字] URL [超連結]
section定義好之後,就可以編寫Block定義檔案來,其描述資訊如下:
{ id: 'mk-flow-start', type: 'action', // shape: 'slot', category: 'presentation', draggable: true, // 允許拖放 state: { data: { sections: [ { type: 'text', text: 'START' }, { // index type: 'argument', datatype: 'number' }, { type: 'text', text: 'TAG' }, { // 模組文字 type: 'argument', datatype: 'string', data: { value: '開始' } }, { type: 'text', text: 'URL' }, { // 超連結 type: 'argument', datatype: 'string' } ] } }
寫好定義檔案後,修改一下包配置檔案(檔案位於專案目錄/client/src/scratch/blockDefs/index.js), 在其中引入新建的markdown包即可。
import categories from './categories'
// 載入Block包
import base from './packages/base'
import chinese from './packages/chinese'
import ml from './packages/ml'
import markdown from './packages/markdown'
export default {
categories: categories,
packages: [base, chinese, ml, markdown]
}
進入編輯器,就可以看見start模組(見下圖)。Block的顏色是根據category欄位來定義,可以修改改欄位來改變顏色方案。具體欄位可以檢視專案目錄/client/src/scratch/blockDefs/categories.js檔案
同理,將其餘5個Block定義編寫好(如圖)
到目前為止,只能使用編輯器進行流程圖的設計,但是並沒有生產實際的flow程式碼,需要繼續在flow.js檔案中編寫匯出函式。另外為了方便使用,額外建立來一個流程圖Block,將匯出功能放在它的上下文選單中。每次建立流程圖時,始終以這個Block作為頭部Block來建立
在Block定義中新增export屬性,是一個數組,可以提供多種匯出功能,併為匯出功能定義上下文選單資訊,其格式如下:
export: [
{
menuItem: true, // 是否新增到選單上
menuName: '匯出為MarkDown', // 選單上顯示文字
fmt: 'markdown', // 匯出格式
ext: '.md', // 副檔名
action: function() { // 匯出功能實現函式
const fmt = 'markdown'
start = this.nextBlock()
if (start.protoId() !== 'mk-flow-start') {
logger.warn('MarkDown Export: first block is not <start> Block')
}
...
}
}
]
在action函式中,this就是當前Block自己,可以通過this.nextBlock()來獲取下游Block,呼叫每個Block的export(fmt)來得到Block自身生成的程式碼片段,然後在根據序列結構拼接為完整的程式碼。例如start單元生成的程式碼片段為:
st8=>start: 開始:> https://www.baidu.com
補充好export定義後,再次進入編輯器,在流程圖Block上點選右鍵,就可以看到自定義的選單項了。由於匯出程式碼比較長,可自行檢視flow.js檔案。
接下來,設計一個簡單的流程圖,測試下匯出功能。
點選“匯出為Markdown”,顯示彈出選單,輸入一個檔名,點選確定,會將生成的檔案下載到本地。
下面為匯出的程式碼為,其真實顯示圖案就是文章開頭顯示的流程圖:
st8=>start: 開始:> https://www.baidu.com
op9=>operation: 程式
c10=>condition: 條件
op11=>operation: 程式
e12=>end: 結束
op13=>operation: 程式
op14=>operation: 程式
st8->op9(bottom)->c10
c10(no)->op14(bottom)->op11
c10(yes, right)->op13(bottom)->op11
op11(bottom)->e12