import { getImageSize, imgToDataUrl, parseDataUrl, getTextFromHtml, createUid } from './index' // 解析出新xmind的概要文本 export const getSummaryText = (node, topicId) => { if (node.children.summary && node.children.summary.length > 0) { for (let i = 0; i < node.children.summary.length; i++) { const cur = node.children.summary[i] if (cur.id === topicId) { return cur.title } } } } // 解析出旧xmind的概要文本 export const getSummaryText2 = (item, topicId) => { const summaryElements = getElementsByType(item.elements, 'summary') if (summaryElements && summaryElements && summaryElements.length > 0) { for (let i = 0; i < summaryElements.length; i++) { const cur = summaryElements[i] if (cur.attributes.id === topicId) { return cur.elements && cur.elements[0] && cur.elements[0].elements && cur.elements[0].elements[0] ? cur.elements[0].elements[0].text : '' } } } return '' } // 解析旧版xmind数据时,找出根节点 export const getRoot = list => { let root = null const walk = arr => { if (!arr) return for (let i = 0; i < arr.length; i++) { if (!root && arr[i].name === 'topic') { root = arr[i] return } } arr.forEach(item => { walk(item.elements) }) } walk(list) return root } // 解析旧版xmind数据,从一个数组中根据name找出该项 export const getItemByName = (arr, name) => { return arr.find(item => { return item.name === name }) } // 解析旧版xmind数据,从一个数组中根据attributes.type找出该项 export const getElementsByType = (arr, type) => { return arr.find(el => { return el.attributes.type === type }).elements } // 解析xmind数据,将概要转换为smm支持的结构 export const addSummaryData = (selfList, childrenList, getText, range) => { const summaryData = { expand: true, isActive: false, text: getText(), range: null } const match = range.match(/\((\d+),(\d+)\)/) if (match) { const startIndex = Number(match[1]) const endIndex = Number(match[2]) if (startIndex === endIndex) { childrenList[startIndex] = summaryData } else { summaryData.range = [startIndex, endIndex] selfList.push(summaryData) } } else { selfList.push(summaryData) } } // 解析xmind数据时,解析其中的图片数据 export const handleNodeImageFromXmind = async ( node, newNode, promiseList, files ) => { if (node.image && /\.(jpg|jpeg|png|gif|webp)$/.test(node.image.src)) { // 处理异步逻辑 let resolve = null const promise = new Promise(_resolve => { resolve = _resolve }) promiseList.push(promise) try { // 读取图片 const imageType = /\.([^.]+)$/.exec(node.image.src)[1] const imageBase64 = `data:image/${imageType};base64,` + (await files['resources/' + node.image.src.split('/')[1]].async( 'base64' )) newNode.data.image = imageBase64 // 如果图片尺寸不存在 if (!node.image.width && !node.image.height) { const imageSize = await getImageSize(imageBase64) newNode.data.imageSize = { width: imageSize.width, height: imageSize.height } } else { newNode.data.imageSize = { width: node.image.width, height: node.image.height } } resolve() } catch (error) { console.log(error) resolve() } } } // 导出为xmind时,处理图片数据 export const handleNodeImageToXmind = async ( node, newData, promiseList, imageList ) => { if (node.data.image) { // 处理异步逻辑 let resolve = null let promise = new Promise(_resolve => { resolve = _resolve }) promiseList.push(promise) try { let imgName = '' let imgData = node.data.image // base64之外的其他图片要先转换成data:url if (!/^data:/.test(node.data.image)) { imgData = await imgToDataUrl(node.data.image) } // 从data:url中解析出图片类型和ase64 let dataUrlRes = parseDataUrl(imgData) imgName = 'image_' + imageList.length + '.' + dataUrlRes.type imageList.push({ name: imgName, data: dataUrlRes.base64 }) newData.image = { src: 'xap:resources/' + imgName, width: node.data.imageSize.width, height: node.data.imageSize.height } resolve() } catch (error) { console.log(error) resolve() } } } export const getXmindContentXmlData = () => { return ` Warning 警告 Attention Warnung 경고 This file can not be opened normally, please do not modify and save, otherwise the contents will be permanently lost! You can try using XMind 8 Update 3 or later version to open 该文件无法正常打开,请勿修改并保存,否则文件内容将会永久性丢失! 你可以尝试使用 XMind 8 Update 3 或更新版本打开 該文件無法正常打開,請勿修改並保存,否則文件內容將會永久性丟失! 你可以嘗試使用 XMind 8 Update 3 或更新版本打開 この文書は正常に開かないので、修正して保存しないようにしてください。そうでないと、書類の内容が永久に失われます。! XMind 8 Update 3 や更新版を使って開くこともできます Datei kann nicht richtig geöffnet werden. Bitte ändern Sie diese Datei nicht und speichern Sie sie, sonst wird die Datei endgültig gelöscht werden. Bitte versuchen Sie, diese Datei mit XMind 8 Update 3 oder später zu öffnen. Ce fichier ne peut pas ouvert normalement, veuillez le rédiger et sauvegarder, sinon le fichier sera perdu en permanence. Vous pouvez essayer d'ouvrir avec XMind 8 Update 3 ou avec une version plus récente. 파일을 정상적으로 열 수 없으며, 수정 및 저장하지 마십시오. 그렇지 않으면 파일의 내용이 영구적으로 손실됩니다! XMind 8 Update 3 또는 이후 버전을 사용하여 -1 Sheet 1 ` } // 获取节点的概要列表 const formatGetGeneralization = data => { const generalization = data.generalization return Array.isArray(generalization) ? generalization : generalization ? [generalization] : [] } // 获取节点自身的概要,非子节点区间 const getSelfGeneralization = data => { const list = formatGetGeneralization(data) return list.filter(item => { return !item.range || item.range.length <= 0 }) } // 获取节点区间概要 const getRangeGeneralization = data => { const list = formatGetGeneralization(data) return list.filter(item => { return item.range && item.range.length > 0 }) } // 导出为xmind时,将概要转换为xmind的格式 export const parseNodeGeneralizationToXmind = node => { const summary = [] const summaries = [] const collectSummary = (item, startIndex, endIndex) => { const summaryTopicId = createUid() const summaryTitle = getTextFromHtml(item.text) summary.push({ id: summaryTopicId, title: summaryTitle, attributedTitle: [ { text: summaryTitle } ] }) summaries.push({ id: createUid(), range: '(' + startIndex + ',' + endIndex + ')', topicId: summaryTopicId }) } // 在xmind中,概要都是保存在父节点的 // 而在simple-mind-map中,区间概要保存在父节点中,不带区间的保存在自身 // 所以先要过滤出自身的区间概要 const generalizationList = getRangeGeneralization(node.data) generalizationList.forEach(item => { collectSummary(item, item.range[0], item.range[1]) }) // 遍历子节点,找出子节点自身的概要 ;(node.children || []).forEach((child, childIndex) => { const list = getSelfGeneralization(child.data) list.forEach(item => { collectSummary(item, childIndex, childIndex) }) }) return { summary, summaries } }