{ const ID = 'BEtiGoivUaqXO5' const escape = s => s.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll('\n', '
') const { blocks, rootBlockId } = await fetch(`https://www.craft.do/api/share/${ID}?enablePagination=true`).then(r => r.json()) // const blockBetter = Object.fromEntries(blocks.map(({blocks,style, content,id}) => [id, {blocks,style:JSON.parse(style)}])) const blocksMap = Object.fromEntries(blocks.map(({blocks,style, content,id,type,rawProperties}) => [id, {content,blocks,style:JSON.parse(style),type,rawProperties:JSON.parse(rawProperties)}])) for (const block of Object.values(blocksMap)) { block.blocks = block.blocks.map(a => blocksMap[a]) } console.log(Object.fromEntries(blocks.map((block) => [block.id, {content:block.content,...block}]))) const { content: title, blocks: cblocks } = blocksMap[rootBlockId] // new Set(Object.values(blocksMap).filter(b => b.style.textStyle !== 'body')) let output = `# ${title}\n\n` let indentLevel = 0 for (const {content, style:{_runAttributes = [],indentationLevel,listStyle}, type, rawProperties} of cblocks) { while (indentLevel > indentationLevel) { indentLevel-- // output += '\n\n' } if (type === 'image') { //console.log(content, rawProperties) output += `\n\n` continue } if (listStyle === 'toggle') { // output += `
\n\n` output += `` } else output += '

' let last = 0 for (const {isBold,isCode,isItalic,isStrikethrough,range:[start,len],linkURL} of _runAttributes.sort((a, b) => a.range[0] - b.range[0])) { // NOTE: there can be overlappng runattributes. not dealing with them if (start < last) continue const end = start + len output += escape(content.slice(last, start)) if (isBold) output += '' if (isItalic) output += '' if (isStrikethrough) output += '' if (linkURL) output += `` if (isCode) output += '

'
      output += escape(content.slice(start, end))
      if (isCode) output += '
' if (linkURL) output += `` if (isStrikethrough) output += '' if (isItalic) output += '' if (isBold) output += '' last = end } output += escape(content.slice(last)) if (listStyle === 'toggle') { output += `
` // output += `
\n\n` indentLevel = indentationLevel } else output += '

\n\n' } while (indentLevel > 0) { indentLevel-- // output += '
\n\n' } console.log(window.output = output) }