Skip to content

Commit

Permalink
tweak key assignment in documentation classes, general code cleanup a…
Browse files Browse the repository at this point in the history
…nd add code comments
  • Loading branch information
derekwolpert committed Sep 28, 2022
1 parent 3817cfa commit 5ed6b10
Showing 1 changed file with 98 additions and 85 deletions.
183 changes: 98 additions & 85 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,51 +25,72 @@ class Documentation {
'Test'
]

static async load (file) {
const filePath = fileURLToPath(new URL(`../docs/${file}.md`, import.meta.url))
const fileContent = (await readFile(filePath)).toString()
const page = new Page(file, fileContent)
await page.load()
return page
}

version

// load documentation content
async load () {
const [pages, version] = await Promise.all([
Promise.all(Documentation.pages.map(page =>
this.constructor.load(page)
)),
this.#getVersion()
const [version, ...pages] = await Promise.all([
this.#getVersion(),
...Documentation.pages.map((file, index) =>
this.#getPage(file, index)
)
])
this.pages = pages
this.version = version
this.pages = pages
await Promise.all(this.pages.map(page => page.load()))
return this
}

// get version number of documentation from package.json
async #getVersion () {
const filePath = fileURLToPath(new URL('../package.json', import.meta.url))
const fileContent = (await readFile(filePath)).toString()
const fileContent = await this.#getFileContent('../package.json')
return JSON.parse(fileContent).version
}

// create page instances
async #getPage (file, index) {
const fileContent = await this.#getFileContent(`../docs/${file}.md`)
const entries = marked.lexer(fileContent)
return new Page(this, file, index, entries)
}

// retrieve raw text content from files
async #getFileContent (path) {
const filePath = fileURLToPath(new URL(path, import.meta.url))
return (await readFile(filePath)).toString()
}
}

class Page {
#file
key
title
body
sections = []
#raw
#documentation
#file
#index
#entries

constructor (file, raw) {
constructor (documentation, file, index, [header, ...entries]) {
this.#documentation = documentation
this.#file = file
this.#raw = raw
this.#index = index
this.#entries = entries
this.title = header.text
}

async load () {
this.#entries = marked.lexer(this.#raw)
// assigns unique key value for page
if (this.rawKey === 'page') {
this.key = `page_${this.#index + 1}`
} else {
const prior = this.documentation.pages.slice(0, this.#index)
const existing = prior.filter(({ rawKey }) => rawKey === this.rawKey)
const ending = existing.length ? `_${existing.length + 1}` : ''
this.key = `${this.rawKey}${ending}`
}

// process page content
const bodyBuffer = []
const sectionBuffer = []

Expand All @@ -79,32 +100,32 @@ class Page {
}
}

this.#entries.forEach(entry => {
if ((entry.type === 'heading') && (entry.depth <= 2)) {
if (entry.depth === 1) {
if (!this.title) this.title = entry.text
}
if (entry.depth === 2) {
processSection()
sectionBuffer.push(entry)
}
for (const entry of this.#entries) {
if ((entry.type === 'heading') && (entry.depth === 2)) {
processSection()
sectionBuffer.push(entry)
} else {
if (sectionBuffer.length) {
sectionBuffer.push(entry)
} else {
bodyBuffer.push(entry)
}
}
})
}
processSection()

// concats raw body content for page
this.body = bodyBuffer.map(({ raw }) => raw).join('')

// load all sections existing under this page
await Promise.all(this.sections.map(section => section.load()))
return this
}

get key () {
// generates the raw un-deduped key value for page
get rawKey () {
return (
this.#file
(this.title || this.#file)
.replace(/[^a-zA-Z0-9]+/g, ' ')
.trim()
.replace(/\s+/g, '-')
Expand All @@ -113,19 +134,16 @@ class Page {
)
}

toJSON () {
return {
key: this.key,
...this
}
get documentation () {
return this.#documentation
}
}

class Section {
key
title
body
subSections = []
subsections = []
#entries
#parent

Expand All @@ -134,85 +152,80 @@ class Section {
this.#entries = entries
this.title = header.text

// assigns unique key value for section
const prior = [
this.page.key,
...this.documentation.pages,
...this.page.sections
.map(section => [section, ...section.subSections])
.map(section => [section, ...section.subsections])
.flat()
.map(section => section.rawKey)
]
const existing = prior.filter(({ rawKey }) => rawKey === this.rawKey)
const ending = (existing.length || ['section', 'subsection'].includes(this.rawKey))
? `_${existing.length + 1}`
: ''

const existing = prior
.filter(key => key === this.rawKey)

this.key = `${
this.rawKey
}${
(existing.length || ['page', 'section', 'subsection'].includes(this.rawKey))
? (`_${existing.length + 1}`)
: ''
}`
this.key = `${this.rawKey}${ending}`
}

async load () {
// procee section content
const bodyBuffer = []
const subSectionBuffer = []
const subsectionBuffer = []

const processSubSection = () => {
if (subSectionBuffer.length) {
this.subSections.push(new this.constructor(this, subSectionBuffer.splice(0, subSectionBuffer.length)))
if (subsectionBuffer.length) {
this.subsections.push(new this.constructor(this, subsectionBuffer.splice(0, subsectionBuffer.length)))
}
}

this.#entries.forEach(entry => {
for (const entry of this.#entries) {
if ((entry.type === 'heading') && (entry.depth === 3)) {
processSubSection()
subSectionBuffer.push(entry)
subsectionBuffer.push(entry)
} else {
if (subSectionBuffer.length) {
subSectionBuffer.push(entry)
if (subsectionBuffer.length) {
subsectionBuffer.push(entry)
} else {
bodyBuffer.push(entry)
}
}
})
}
processSubSection()

// concats raw body content for section
this.body = bodyBuffer.map(({ raw }) => raw).join('')
await Promise.all(this.subSections.map(section => section.load()))

// load all subsections existing under this section
await Promise.all(this.subsections.map(section => section.load()))
return this
}

// generates the raw un-deduped key value for section
get rawKey () {
return (
// The resulting raw keyvalue might be shared with another
// section/subsection within this page. The value will be
// iterated to de-duplicate within the Section's constructor
this.title
.replace(/[^a-zA-Z0-9]+/g, ' ')
.trim()
.replace(/\s+/g, '-')
.toLowerCase() ||
(
// if there is a parent section that is using a non-default raw key value
(this.section?.rawKey && this.section.rawKey !== 'section')
// use the parent raw key value
? this.section.rawKey
// otherwise check if the parent page has a non-default raw key value
: (this.page?.key && this.page.key !== 'page')
// use the parent raw key value
? this.page.key
// fallback to default value for section raw key value
: this.section
? 'subsection'
: 'section'
)
)
const baseKey = this.title
.replace(/[^a-zA-Z0-9]+/g, ' ')
.trim()
.replace(/\s+/g, '-')
.toLowerCase()
if (baseKey) return baseKey

const sectionKey = this.section?.rawKey
if (sectionKey && sectionKey !== 'section') return sectionKey

const pageKey = this.page?.rawKey
if (pageKey && pageKey !== 'page') return pageKey

return this.section ? 'subsection' : 'section'
}

get parent () {
return this.#parent
}

get documentation () {
return this.page.documentation
}

get page () {
return this.parent.parent || this.parent
}
Expand Down

0 comments on commit 5ed6b10

Please sign in to comment.