Skip to content

Commit

Permalink
fix: #4 (ordering) and #19, (dashes in categories)
Browse files Browse the repository at this point in the history
  • Loading branch information
hatton committed Nov 30, 2022
1 parent 35abd64 commit 5c7f420
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 60 deletions.
3 changes: 2 additions & 1 deletion jest.config.js
Expand Up @@ -4,5 +4,6 @@ module.exports = {
transform: {
"^.+\\.ts?$": "ts-jest",
},
transformIgnorePatterns: ["<rootDir>/node_modules/"],
modulePathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/dist/"],
transformIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/dist/"],
};
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -7,7 +7,8 @@
"dist/**/*"
],
"scripts": {
"build": "tsc && cp ./src/css/*.css dist/",
"test": "jest",
"build": "yarn test && tsc && cp ./src/css/*.css dist/",
"clean": "rm -rf ./dist/",
"semantic-release": "semantic-release",
"typecheck": "tsc --noEmit",
Expand Down
1 change: 1 addition & 0 deletions src/FlatGuidLayoutStrategy.ts
Expand Up @@ -14,6 +14,7 @@ export class FlatGuidLayoutStrategy extends LayoutStrategy {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public newLevel(
rootDir: string,
order: number,
context: string,
_levelLabel: string
): string {
Expand Down
47 changes: 33 additions & 14 deletions src/HierarchicalNamedLayoutStrategy.ts
Expand Up @@ -10,26 +10,24 @@ import { NotionPage } from "./NotionPage";
export class HierarchicalNamedLayoutStrategy extends LayoutStrategy {
public newLevel(
dirRoot: string,
order: number,
context: string,
levelLabel: string
): string {
const path = context + "/" + sanitize(levelLabel).replaceAll(" ", "-");
// The docusaurus documentation doesn't specify how the prefix should look (such that it recognizes and strips it)
// A following dash works.
const prefix = "";
const path = context + "/" + prefix + sanitize(levelLabel); //.replaceAll(" ", "-");

//console.log("Creating level " + path);
fs.mkdirSync(dirRoot + "/" + path, { recursive: true });
const newPath = dirRoot + "/" + path;
fs.mkdirSync(newPath, { recursive: true });
this.addCategoryMetadata(newPath, order);
return path;
}

public getPathForPage(page: NotionPage, extensionWithDot: string): string {
let path =
this.rootDirectory +
"/" +
page.context +
"/" +
sanitize(page.nameForFile()) +
extensionWithDot;

path = path
const sanitizedName = sanitize(page.nameForFile())
.replaceAll("//", "/")
.replaceAll("%20", "-")
.replaceAll(" ", "-")
Expand All @@ -40,9 +38,30 @@ export class HierarchicalNamedLayoutStrategy extends LayoutStrategy {
.replaceAll("”", "")
.replaceAll("'", "")
.replaceAll("?", "-");
// console.log(
// `getPathForPage(${context}, ${pageId}, ${title}) with root ${this.rootDirectory} --> ${path}`
// );

const context = ("/" + page.context + "/").replaceAll("//", "/");
const path =
this.rootDirectory + context + sanitizedName + extensionWithDot;

return path;
}

//{
// "position": 2.5,
// "label": "Tutorial",
// "collapsible": true,
// "collapsed": false,
// "className": "red",
// "link": {
// "type": "generated-index",
// "title": "Tutorial overview"
// },
// "customProps": {
// "description": "This description can be used in the swizzled DocCard"
// }
// }
private addCategoryMetadata(dir: string, order: number) {
const data = `{"position":${order}}`;
fs.writeFileSync(dir + "/_category_.json", data);
}
}
5 changes: 3 additions & 2 deletions src/LayoutStrategy.ts
Expand Up @@ -24,7 +24,8 @@ export abstract class LayoutStrategy {

public abstract newLevel(
rootDir: string,
ontext: string,
order: number,
context: string,
levelLabel: string
): string;
public abstract getPathForPage(
Expand All @@ -34,7 +35,7 @@ export abstract class LayoutStrategy {

public getLinkPathForPage(page: NotionPage): string {
// the url we return starts with a "/", meaning it is relative to the root of the markdown root (e.g. /docs root in Docusaurus)
return this.getPathForPage(page, "").replace(this.rootDirectory, "");
return ("/" + page.slug).replaceAll("//", "/");
}

public pageWasSeen(page: NotionPage): void {
Expand Down
18 changes: 14 additions & 4 deletions src/NotionImage-CaptionReading.spec.ts
@@ -1,25 +1,35 @@
import { parseImageBlock } from "./images";
import { initImageHandling, parseImageBlock } from "./images";

const kPrimaryImageUrl =
"https://s3.us-west-2.amazonaws.com/primaryImage.png?Blah=foo";

/* didn't work?
beforeAll(async () => {
console.log("before");
await initImageHandling("", "", []);
console.log("azfter");
});
*/
/* eslint-disable @typescript-eslint/require-await */
test("finds primary image url", async () => {
const img = parseImageBlock(kImageBlockWithTwoLocalizedImages);
await initImageHandling("", "", []);
const img = parseImageBlock(kImageBlockWithTwoLocalizedImages.image);
expect(img.primaryUrl).toBe(kPrimaryImageUrl);
});

test("primary caption content after image links are removed", async () => {
await initImageHandling("", "", []);
const img = parseImageBlock(
kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText
kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText.image
);
// carriage returns seem to mess up the markdown, so should be removed
expect(img.caption).toBe("Caption before images. Caption after images.");
});

test("gets localized image links", async () => {
await initImageHandling("", "", []);
const img = parseImageBlock(
kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText
kImageBlockWithTwoLocalizedImagesWrappedWithActualCaptionText.image
);
expect(img.localizedUrls.length).toBe(2);
expect(img.localizedUrls[0].iso632Code).toBe("fr");
Expand Down
33 changes: 23 additions & 10 deletions src/NotionPage.ts
Expand Up @@ -7,6 +7,7 @@ import {
import { RateLimiter } from "limiter";
import { Client } from "@notionhq/client";
import { logDebug } from "./log";
import { info } from "console";

const notionLimiter = new RateLimiter({
tokensPerInterval: 3,
Expand All @@ -33,17 +34,20 @@ export function initNotionClient(notionToken: string): Client {
export class NotionPage {
private metadata: GetPageResponse;
public readonly pageId: string;
public readonly order: number;
public context: string; // where we found it in the hierarchy of the outline
public foundDirectlyInOutline: boolean; // the page was found as a descendent of /outline instead of being linked to

private constructor(
context: string,
pageId: string,
order: number,
metadata: GetPageResponse,
foundDirectlyInOutline: boolean
) {
this.context = context;
this.pageId = pageId;
this.order = order;
this.metadata = metadata;
this.foundDirectlyInOutline = foundDirectlyInOutline;

Expand All @@ -55,11 +59,19 @@ export class NotionPage {
public static async fromPageId(
context: string,
pageId: string,
order: number,
foundDirectlyInOutline: boolean
): Promise<NotionPage> {
const metadata = await getPageMetadata(pageId);
//logDebug(JSON.stringify(metadata));
return new NotionPage(context, pageId, metadata, foundDirectlyInOutline);

//logDebug("notion metadata", JSON.stringify(metadata));
return new NotionPage(
context,
pageId,
order,
metadata,
foundDirectlyInOutline
);
}

public matchesLinkId(id: string): boolean {
Expand Down Expand Up @@ -162,7 +174,6 @@ export class NotionPage {
block_id: this.pageId,
page_size: 100, // max hundred links in a page
});

return children;
}

Expand Down Expand Up @@ -257,19 +268,21 @@ export class NotionPage {
}

public async getContentInfo(): Promise<{
childPages: any[];
linksPages: any[];
childPageIdsAndOrder: { id: string; order: number }[];
linksPageIdsAndOrder: { id: string; order: number }[];
hasParagraphs: boolean;
}> {
const children = await this.getChildren();

for (let i = 0; i < children.results.length; i++) {
(children.results[i] as any).order = i;
}
return {
childPages: children.results
childPageIdsAndOrder: children.results
.filter((b: any) => b.type === "child_page")
.map((b: any) => b.id),
linksPages: children.results
.map((b: any) => ({ id: b.id, order: b.order })),
linksPageIdsAndOrder: children.results
.filter((b: any) => b.type === "link_to_page")
.map((b: any) => b.link_to_page.page_id),
.map((b: any) => ({ id: b.link_to_page.page_id, order: b.order })),
hasParagraphs: children.results.some(
b =>
(b as any).type === "paragraph" &&
Expand Down
6 changes: 5 additions & 1 deletion src/images.ts
Expand Up @@ -155,7 +155,10 @@ async function saveImage(imageSet: ImageSet): Promise<void> {
localizedImage.iso632Code
}/docusaurus-plugin-content-docs/current/${imageSet.relativePathToParentDocument!}`;

writeImageIfNew(directory + "/" + imageSet.outputFileName!, buffer);
writeImageIfNew(
(directory + "/" + imageSet.outputFileName!).replaceAll("//", "/"),
buffer
);
}
}

Expand All @@ -177,6 +180,7 @@ function writeImageIfNew(path: string, buffer: Buffer) {
}

export function parseImageBlock(image: any): ImageSet {
if (!locales) throw Error("Did you call initImageHandling()?");
const imageSet: ImageSet = {
primaryUrl: "",
caption: "",
Expand Down
7 changes: 4 additions & 3 deletions src/links.ts
Expand Up @@ -83,16 +83,17 @@ function transformLinks(

// The key to understanding this while is that linkRegExp actually has state, and
// it gives you a new one each time. https://stackoverflow.com/a/1520853/723299
verbose(`transformLinks ${pageMarkdown}`);

while ((match = linkRegExp.exec(pageMarkdown)) !== null) {
const string = match[0];
const originalLink = match[0];

const hrefFromNotion = match[2];
const text = convertLinkText(match[1] || "", hrefFromNotion);
const hrefForDocusaurus = convertHref(hrefFromNotion);

if (hrefForDocusaurus) {
output = output.replace(string, `[${text}](${hrefForDocusaurus})`);
output = output.replace(originalLink, `[${text}](${hrefForDocusaurus})`);
verbose(`transformed link: ${originalLink}-->${hrefForDocusaurus}`);
} else {
verbose(`Maybe problem with link ${JSON.stringify(match)}`);
}
Expand Down

0 comments on commit 5c7f420

Please sign in to comment.