Skip to content

Commit

Permalink
Use frontmatter title and description (#119)
Browse files Browse the repository at this point in the history
Injects an H1 and p tag at start of document based on frontmatter title and description
  • Loading branch information
AristurtleDev authored Mar 16, 2024
1 parent 833ee80 commit bb54978
Showing 1 changed file with 48 additions and 24 deletions.
72 changes: 48 additions & 24 deletions documentation/templates/monogame/conceptual.extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,60 @@
* This method will be called at the start of exports.transform in conceptual.html.primary.js
*/
exports.preTransform = function (model) {

// The model.conceptual property has all of the generated HTMl that's used
// by docfx for the article. For each HTML tag, there is a `sourcestartlinenumber`
// value that defines the line within the article that markdown was at.
// We'll need this to determine the values to inject for the title and
// description
const lineNumber = getStartingLineNumber(model);

// Each HTMl tag also uses a `sourceFile` attribute which is just the path
// to the markdown file.
const sourceFile = model.path

// If a `title` frontmatter is supplied, this will inject that as the first
// <H1> tag of the article.
if (model.title) {
const titleLineNumber = Math.max(0, lineNumber - 2);
const id = slugify(model.title);
model.rawTitle = `<h1 id="${id}" sourceFile="${sourceFile}" sourcestartlinenumber="${titleLineNumber}">${model.title}</h1>`;
}

// If a `description` frontmatter is supplied, this will inject that as the
// first <p> tag of the article
if (model.description) {
const style = model.descriptionStyle ?? 'text-secondary';
const pLineNumber = Math.max(0, lineNumber - 1);
const p = `<p sourcefile="${sourceFile}" sourcestartlinenumber="${pLineNumber}" class="${style}">${model.description}</p>`
model.conceptual = p + model.conceptual;
}

return model;
}

function getStartingLineNumber(model) {
const start = model.conceptual.indexOf('sourcestartlinenumber="');
const end = model.conceptual.indexOf('"', start);

if (start != -1 && end != -1) {
return model.conceptual.substring(start, end);
}

return 0;
}

function slugify(value) {
return value.toLowerCase() // Lower case title
.replace(/\s+/g, '-') // Replaces spaces with hyphens
.replace(/[^\w\-]+/g, '') // Remove all non-word characters
.replace(/\-\-+/g, '-') // Double hyphen to single hyphen
.trim(); // Trim it up
}

/**
* This method will be called at the end of exports.transform in conceptual.html.primary.js
*/
exports.postTransform = function (model) {
model.title = model.title ?? getTitle(model);
model.description = model.description ?? getDescription(model);
return model;
}

function getTitle(model) {
// model.rawTitle is the full contents of the first <h1> tag on the page.
// So just remove the HTML tag info and take the innerText for the title.
return model.rawTitle.replace(/<.*?>/g, '').trim();
}

function getDescription(model) {
// model.conceptual contains the conceptual generated HTML for the page.
// Locate the first p tag opening and the first </p> tag close after that
// then capture the substring using those indexes, then remove the HTML tag
// info to get the innerText as the description.
const pOpen = model.conceptual.indexOf('<p');
const pClose = model.conceptual.indexOf('</p>', pOpen);

if (pOpen != -1 && pClose != -1) {
const p = model.conceptual.substring(pOpen, pClose + 4);
return p.replace(/<.*?>/g, '').trim();
}

return '';
}

0 comments on commit bb54978

Please sign in to comment.