JSFiddle - React, Tailwind, and code Playground
by Константин Дралюк
HTML
<textarea name="" id="pug" cols="100" rows="10"></textarea>
<textarea name="" id="sass" cols="100" rows="10"></textarea>
JavaScript
const getStartOffset = line => {
return line.length - line.trimStart().length
}
const removeOffset = text => {
const lines = text.split('\n')
const firstLine = lines.find(line => /\b/.test(line))
return lines.map(line => line.slice(getStartOffset(firstLine))).join('\n')
}
const removeLinesChunks = lines => {
return lines.filter(line => {
return /^\+b|\+e/.test(line.trim())
})
}
const textToLines = text => {
const lines = text.split('\n')
return removeLinesChunks(lines)
}
const buildBlocks = lines => {
const blocks = []
const items = []
const clearLine = line => {
let clearedLine = line.trim().replace(/\(.*\)/, '').replace(/( |!).*$/, '')
return clearedLine
}
const buildItem = line => {
const lineArray = clearLine(line).split('.')
const hasTag = lineArray[1].toUpperCase() === lineArray[1]
const type = /^\+b/.test(line.trim()) ? 'block' : 'element'
const name = hasTag ? lineArray[2] : lineArray[1]
return {type, name, line}
}
const buildItems = lines.map(line => {
const item = buildItem(line)
const parent = [...items].reverse().find(item =>
item.type === 'block' &&
getStartOffset(line) > getStartOffset(item.line)
)
item.parent = parent ? parent.name : null
items.push(item)
return line
})
const buildBlocks = items.map((item) => {
if (item.type === 'block') {
const exists = blocks.find(block => item.name === block.name)
if (!exists) {
blocks.push({
name: item.name,
elements: [],
content: `.${item.name}\n`
})
}
} else {
const parent = blocks.find(block => item.parent === block.name)
const exists = parent.elements.includes(item.name)
if (!exists) {
parent.content += ` &__${item.name}\n`
parent.elements.push(item.name)
}
}
})
return blocks
}
const buildSass = blocks => {
let sass = ``
for (let i in blocks) {
sass +=...