Skip to content

Commit

Permalink
Fixed Referenced Style Broken Link (#1262)
Browse files Browse the repository at this point in the history
* Fixed broken referenced link (#1229)

* Fixed broken referenced link (#1229)

* removing unnecessary change of standard-change

* back out superfluous change to .github template

* undo standard-change

* Fixed mixed reference links

* implemented all links functionalities of cip to cps

* fixed correct parsing of table CIP dir links

---------

Co-authored-by: Robert Phair <[email protected]>
Co-authored-by: Tommy Kammerer <[email protected]>
  • Loading branch information
3 people authored Jun 4, 2024
1 parent a2703bb commit ede465e
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 14 deletions.
60 changes: 55 additions & 5 deletions scripts/cip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import {
getStringContentAsync,
getBufferContentAsync,
preventH1Headline,
getDocTag,
identifyReferenceLinks,
identifyMixedReferenceLinks,
identifyNestedExtendedCIPLinks,
} from "./reusable";
import {
cip_repo_raw_base_url,
Expand All @@ -22,6 +26,57 @@ const path_name = path.basename(__filename);

// Download markdown resources
const processCIPContentAsync = async (cip_name: string, content: string) => {
// Finding any reference links in the content and replacing to relative links where necessary
// to fix broken links in the CIPs
const referenceLinks = identifyReferenceLinks(content);
if(referenceLinks.length > 0) {
await Promise.all(
referenceLinks.map(async (link) => {
if(link.url.indexOf("./") == 0 || link.url.indexOf("../") == 0) {

console.log(`Found reference links in CIP ${cip_name}:`);
console.log(`WARNING: Reference link ${link.reference} in CIP ${cip_name} is an relative link: ${link.url}.`);

// Rewrite link to static folder
content = content.replace(
`[${link.reference}]`,
`[${link.reference}](${link.url})`
);
}
})
);
}

// Handle mixed reference links
const mixedReferenceLinks = identifyMixedReferenceLinks(content);
if (mixedReferenceLinks.length > 0) {
mixedReferenceLinks.forEach(mixedLink => {
const matchedReference = referenceLinks.find(link => link.reference === mixedLink.reference && (link.url.indexOf("./") == 0 || link.url.indexOf("../") == 0));
if (matchedReference) {

console.log(`Found mixed reference links in CIP ${cip_name}:`);
console.log(`WARNING: Mixed reference link [${mixedLink.text}][${mixedLink.reference}] is an relative mixed link: ${matchedReference.url}.`);

content = content.replace(`[${mixedLink.text}][${mixedLink.reference}]`, `[${mixedLink.text}](${cip_repo_raw_base_url}${cip_name}/${matchedReference.url})`);
}
});
}

// Handle nested extended CIP links
const nestedExtendedCIPs = identifyNestedExtendedCIPLinks(content);
if (nestedExtendedCIPs.length > 0) {
nestedExtendedCIPs.forEach(nestedCIP => {
console.log(`Found nested extended CIP links in CIP ${cip_name}:`);
console.log(`WARNING: Nested extended CIP link ${nestedCIP} in CIP ${cip_name} is a relative link.`);

const modifiedNestedCIP = nestedCIP.replace("(", "").replace(")", "");

content = content.replace(nestedCIP, `(${cip_repo_base_url}${cip_name}/${modifiedNestedCIP})`);
}
);
}

// Handle inline links
const cip_resource = content.match(cip_regex);
if (cip_resource) {
await Promise.all(
Expand Down Expand Up @@ -167,11 +222,6 @@ const stringManipulation = (content: string, cip_name: string) => {
return content;
};

// Get a specific doc tag
const getDocTag = (content: string, tag_name: string) => {
return content.match(new RegExp(`(?<=${tag_name}: ).*`, ""));
};

const main = async () => {
console.log("CIP Content Downloading...");
// Use https://raw.githubusercontent.com/cardano-foundation/CIPs/master/README.md as entry point to get URLs
Expand Down
72 changes: 63 additions & 9 deletions scripts/cps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
cip_source_repo,
cip_repo_base_url,
cip_readme_url,
cip_repo_raw_base_url,
cip_regex,
} from "./constants";
import { getDocTag } from "./reusable";
import { getDocTag, identifyReferenceLinks, identifyMixedReferenceLinks } from "./reusable";

// Fetch markdown files from Github
async function fetchReadmeContent(folderUrl: string, folderName: string): Promise<string | null> {
Expand Down Expand Up @@ -57,13 +59,13 @@ async function updateOrCreateReadmeFile(
const creationDate = getDocTag(content, "Created");

// Sanitize title
const newContent = content.replace(
content = content.replace(
/Title: .+/,
`Title: "${title}"\n${sidebarLabel}${custom_edit_url}`
);

// Add Content Info at the bottom of the page
const newContentWithInfo = newContent.concat(
content = content.concat(
"\n" +
"## CPS Information \nThis CPS was created on **" +
creationDate +
Expand All @@ -78,16 +80,68 @@ async function updateOrCreateReadmeFile(
")."
);

// Replace image paths
const newContentWithCorrectImagePaths = newContentWithInfo.replace(
/!\[.*?\]\(\.\/(.*?)\)/g,
`![same text](../../../static/img/cps/${folderName}/$1)`
);
const referenceLinks = identifyReferenceLinks(content);
if(referenceLinks.length > 0) {
await Promise.all(
referenceLinks.map(async (link) => {
if(link.url.indexOf("./") == 0 || link.url.indexOf("../") == 0) {

console.log(`Found reference links in CPS ${folderName}:`);
console.log(`WARNING: Reference link ${link.reference} in CPS ${folderName} is an relative link: ${link.url}.`);

// Rewrite link to static folder
content = content.replace(
`[${link.reference}]`,
`[${link.reference}](${link.url})`
);
}
})
);
}

const mixedReferenceLinks = identifyMixedReferenceLinks(content);
if (mixedReferenceLinks.length > 0) {
mixedReferenceLinks.forEach(mixedLink => {
const matchedReference = referenceLinks.find(link => link.reference === mixedLink.reference && (link.url.indexOf("./") == 0 || link.url.indexOf("../") == 0));
if (matchedReference) {

console.log(`Found mixed reference links in CPS ${folderName}:`);
console.log(`WARNING: Mixed reference link [${mixedLink.text}][${mixedLink.reference}] is an relative mixed link: ${matchedReference.url}.`);

content = content.replace(`[${mixedLink.text}][${mixedLink.reference}]`, `[${mixedLink.text}](${cip_repo_raw_base_url}${folderName}/${matchedReference.url})`);
}
});
}

const cip_resource = content.match(cip_regex);
if (cip_resource) {
await Promise.all(
cip_resource.map(async (r) => {
if (r.indexOf("http://") < 0 && r.indexOf("https://") < 0) {

// Create modified file_names in case we want to store files
// with a different ending, like JSON files
const modified_file_name = r
.replace("](", "")
.replace(".png)", ".png")
.replace(".jpg)", ".jpg")
.replace(".jpeg)", ".jpeg")
.replace(".json)", ".json");

// Rewrite link to static folder
content = content.replace(
modified_file_name,
`../../../static/img/cps/${folderName}/${modified_file_name}`
);
}
})
);
}

const filePath = path.join(cps_target_folder, `${folderName}.md`);

try {
await fs.promises.writeFile(filePath, newContentWithCorrectImagePaths);
await fs.promises.writeFile(filePath, content);
console.log(`Updated ${filePath}`);
} catch (error) {
console.error(`Error updating ${filePath}:`, error.message);
Expand Down
46 changes: 46 additions & 0 deletions scripts/reusable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,49 @@ export const preventH1Headline = (content: string, headline: string) => {
export const getDocTag = (content: string, tag_name: string) => {
return content.match(new RegExp(`(?<=${tag_name}: ).*`, ""));
};

export const identifyReferenceLinks = (content: string) => {
// Regular expression to match reference-style links
const referenceLinkRegex = /\[([^\]]+)\]:\s*(\S+)/g;
const matches = [];
let match;

// Loop through all matches and push them into the matches array
while ((match = referenceLinkRegex.exec(content)) !== null) {
matches.push({
reference: match[1], // The reference name
url: match[2] // The URL
});
}

return matches;
};

// Identify mixed reference links in Markdown content
export const identifyMixedReferenceLinks = (content: string) => {
const mixedReferenceLinkRegex = /\[([^\]]+)\]\[([^\]]+)\]/g;
const matches = [];
let match;

while ((match = mixedReferenceLinkRegex.exec(content)) !== null) {
matches.push({
text: match[1],
reference: match[2],
});
}

return matches;
};

// Identify nested extended CIP links in Markdown content
export const identifyNestedExtendedCIPLinks = (content: string) => {
const nestedExtendedCIPRegex = /\(\.\/CIPs\/\d{4}\)/gm;
const matches = [];
let match;

while ((match = nestedExtendedCIPRegex.exec(content)) !== null) {
matches.push(match[0]);
}

return matches;
};

0 comments on commit ede465e

Please sign in to comment.