diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 394c5435b..000000000 --- a/.babelrc +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", - { - "targets": { - "node": "current" - } - } - ] - ] -} diff --git a/javascript/TocCards.tsx b/javascript/TocCards.tsx new file mode 100644 index 000000000..d2507b619 --- /dev/null +++ b/javascript/TocCards.tsx @@ -0,0 +1,79 @@ +import { html, raw } from "hono/html"; +import type { FC } from "hono/jsx"; + +type HeaderCardProps = { + index: number; + chapterIndex: number; + displayTitle: string; + toIndexFolder: string; +}; + +export const IndexHeaderCard: FC = ({ + index, + chapterIndex, + displayTitle, + toIndexFolder +}) => { + return html``; +}; + +export const SidebarHeaderCard: FC = ({ + index, + chapterIndex, + displayTitle, + toIndexFolder +}) => { + return html``; +}; diff --git a/javascript/commands/utils.ts b/javascript/commands/utils.ts new file mode 100644 index 000000000..895c7b396 --- /dev/null +++ b/javascript/commands/utils.ts @@ -0,0 +1,66 @@ +import fs from "node:fs"; +import fse from "fs-extra"; +import path from "node:path"; +import { ending, frontmatter, preamble } from "../latexContent.js"; + +const __dirname = path.resolve(import.meta.dirname); + +export const createMain = ( + inputDir: string, + outputDir: string, + parseType: string +) => { + // TODO: Use fs-extra to auto create subfolders + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir); + } + + if (parseType == "js" || parseType == "json") { + return; + } + + if (parseType == "web") { + if (!fs.existsSync(path.join(outputDir, "/chapters"))) { + fs.mkdirSync(path.join(outputDir, "/chapters")); + } + fse.copy(path.join(__dirname, "../../static"), outputDir, err => { + if (err) return console.error(err); + }); + return; + } + + // for latex version only + // create sicpjs.tex file + // FIXME: Remove any + const chaptersFound: any[] = []; + const files = fs.readdirSync(inputDir); + files.forEach(file => { + if (file.match(/chapter/)) { + chaptersFound.push(file); + } + }); + const stream = fs.createWriteStream(path.join(outputDir, "sicpjs.tex")); + stream.once("open", fd => { + stream.write(preamble); + stream.write(frontmatter); + chaptersFound.forEach(chapter => { + const pathStr = "./" + chapter + "/" + chapter + ".tex"; + stream.write("\\input{" + pathStr + "}\n"); + }); + stream.write(ending); + stream.end(); + }); + // makes the .latexmkrc file + const latexmkrcStream = fs.createWriteStream( + path.join(outputDir, ".latexmkrc") + ); + latexmkrcStream.once("open", fd => { + latexmkrcStream.write(latexmkrcContent); + latexmkrcStream.end(); + }); +}; + +const latexmkrcContent = `$pdflatex = "xelatex %O %S"; +$pdf_mode = 1; +$dvi_mode = 0; +$postscript_mode = 0;`; diff --git a/javascript/constants.js b/javascript/constants.ts similarity index 80% rename from javascript/constants.js rename to javascript/constants.ts index 518571c61..c4c8aa8e9 100644 --- a/javascript/constants.js +++ b/javascript/constants.ts @@ -1,12 +1,5 @@ export const sourceAcademyURL = "https://sourceacademy.org"; - -// to change to localhost if required -// http://localhost:8075 - export const authors = "Harold Abelson and Gerald Jay Sussman"; - export const authors_with = "Julie Sussman"; - export const adapters = "Martin Henz and Tobias Wrigstad"; - export const adapters_with = "Samuel Fang"; diff --git a/javascript/findBadTags.js b/javascript/findBadTags.ts similarity index 89% rename from javascript/findBadTags.js rename to javascript/findBadTags.ts index 0681bcd04..94535f374 100644 --- a/javascript/findBadTags.js +++ b/javascript/findBadTags.ts @@ -1,6 +1,6 @@ -import fs from "fs"; -import util from "util"; -import path from "path"; +import fs from "node:fs"; +import util from "node:util"; +import path from "node:path"; import { DOMParser as dom } from "xmldom"; @@ -8,6 +8,7 @@ const readdir = util.promisify(fs.readdir); const open = util.promisify(fs.open); const readFile = util.promisify(fs.readFile); +const __dirname = path.resolve(import.meta.dirname); const inputDir = path.join(__dirname, "../xml"); const validTags = new Set([ @@ -171,11 +172,10 @@ const recursiveCheckChildrenForValidTag = node => { return found; }; -async function recursiveCheckXmlForTag(filepath, tagName) { - let files; +async function recursiveCheckXmlForTag(filepath: string, tagName: string) { const fullPath = path.join(inputDir, filepath); - files = await readdir(fullPath); - const promises = []; + const files = await readdir(fullPath); + const promises: Promise[] = []; files.forEach(file => { if (file.match(/\.xml$/)) { @@ -189,7 +189,11 @@ async function recursiveCheckXmlForTag(filepath, tagName) { await Promise.all(promises); } -async function checkXmlForTag(filepath, filename, tagName) { +async function checkXmlForTag( + filepath: string, + filename: string, + tagName: string +) { const fullFilepath = path.join(inputDir, filepath, filename); const fileToRead = await open(fullFilepath, "r"); @@ -210,7 +214,7 @@ async function checkXmlForTag(filepath, filename, tagName) { async function main() { const args = process.argv; let tagName = ""; - if (args.length > 2 && args[2] != "") { + if (args.length > 2 && args[2]) { tagName = args[2]; console.log("\nLooking for tag: " + tagName + "\n"); } else { @@ -220,7 +224,7 @@ async function main() { recursiveCheckXmlForTag("", tagName); } -// babel-node ./javascript/findBadTags +// tsx ./javascript/findBadTags // Can provide 0 or 1 arguments. // If no arguments provided, checks for all invalid tags. diff --git a/javascript/generateSearchData.js b/javascript/generateSearchData.ts similarity index 94% rename from javascript/generateSearchData.js rename to javascript/generateSearchData.ts index 98548744f..7c35871d6 100644 --- a/javascript/generateSearchData.js +++ b/javascript/generateSearchData.ts @@ -1,4 +1,4 @@ -import { getChildrenByTagName, ancestorHasTag } from "./utilityFunctions"; +import { getChildrenByTagName, ancestorHasTag } from "./utilityFunctions.js"; import { allFilepath, tableOfContent } from "./index.js"; import path from "path"; import fs from "fs"; @@ -12,7 +12,8 @@ import { processSnippetJson, recursiveProcessPureText, recursivelyProcessTextSnippetJson -} from "./processingFunctions"; +} from "./processingFunctions/index.js"; +import type { WriteBuffer } from "./types.js"; let paragraph_count = 0; let heading_count = 0; @@ -26,6 +27,8 @@ let chapterTitle = ""; let displayTitle = ""; export let chapterIndex = ""; +const __dirname = path.resolve(import.meta.dirname); + export const tagsToRemove = new Set([ "#comment", "ATTRIBUTION", @@ -72,17 +75,26 @@ const ignoreTags = new Set([ "p", "WEB_ONLY" ]); -export const trieTree = {}; + +type TrieEnd = { + value: string; + pureIndex: [string, string][]; + subIndex: { value: string; id: [string, string]; order: string }[]; +}; + +type TrieTree = { + [key: string]: TrieTree | { value: TrieEnd }; +}; +export const trieTree: TrieTree = {}; export const trieTreeText = {}; export const writeSearchData = () => { const outputDir = path.join(__dirname, "../json"); - const outputFile = path.join(outputDir, "searchData.json"); - const searchData = {}; - searchData["textbook"] = textBook; - searchData["indexSearch"] = trieTree; - searchData["userSearch"] = trieTreeText; - + const searchData = { + textbook: textBook, + indexSearch: trieTree, + userSearch: trieTreeText + }; fs.writeFile(outputFile, JSON.stringify(searchData), err => { if (err) { console.error(err); @@ -172,8 +184,8 @@ function maintainTextTrie(arr) { } function maintainIndexTrie() { - function add(obj, trie) { - let current = trie; + function add(obj, trie: TrieTree) { + let current: TrieTree | { value: TrieEnd } = trie; if (obj["parse"] == null || obj["parse"]["value"] == null) { if (obj["parse"]["DECLARATION"]) { @@ -198,14 +210,13 @@ function maintainIndexTrie() { var index = obj["parse"]["value"]; - for (let i = 0; i < index.length; i++) { - let char = index[i]; - char = char.toLowerCase(); - - if (!current.hasOwnProperty(char)) { - current[char] = {}; + for (let char of index) { + // FIXME: Once we can type `char` as `string`, fix the type gymnastics + const key = char.toLowerCase(); + if (!Object.prototype.hasOwnProperty.call(current, key)) { + current[key as keyof typeof current] = {}; } - current = current[char]; + current = (current as any)[key]!; } if (!current.value) { current.value = { value: index, pureIndex: [], subIndex: [] }; @@ -246,24 +257,28 @@ function maintainIndexTrie() { } else { toAdd["order"] = obj["parse"]["SUBINDEX"]["value"]; } + // TODO: Use type guard instead + const _current = current as { value: TrieEnd }; if ( - !current.value.subIndex.find( + !_current.value.subIndex.find( obj => obj.value === toAdd.value && obj.id[0] === toAdd.id[0] && obj.id[1] === toAdd.id[1] ) ) { - current.value.subIndex.push(toAdd); - for (let i = 0; i < current.value.subIndex.length; i++) { + _current.value.subIndex.push(toAdd); + for (let i = 0; i < _current.value.subIndex.length; i++) { //console.log(current.value.subIndex[i]["order"].toString.localeCompare("gh")); - current.value.subIndex.sort((a, b) => + _current.value.subIndex.sort((a, b) => a["order"].localeCompare(b.order) ); } } } else { - current.value.pureIndex.push(obj["parentId"]); + // TODO: Use type guard instead + const _current = current as { value: TrieEnd }; + _current.value.pureIndex.push(obj["parentId"]); } } let len = index.length; @@ -321,12 +336,12 @@ const processTagWithChildren = (node, obj) => { }; const processLatex = (node, obj, inline) => { - const writeTo = []; + const writeTo: WriteBuffer = []; if (inline) { recursiveProcessPureText(node.firstChild, writeTo, { removeNewline: "all" - }); + } as any); } else { recursiveProcessPureText(node.firstChild, writeTo); } @@ -358,23 +373,14 @@ const processTextFunctions = { // Tags with children and no body B: processTagWithChildren, - EM: processTagWithChildren, - LI: processTagWithChildren, - TT: processTagWithChildren, - TABLE: processTagWithChildren, - TR: processTagWithChildren, - TD: processTagWithChildren, - REFERENCE: processTagWithChildren, - OL: processTagWithChildren, - UL: processTagWithChildren, br: (node, obj) => { diff --git a/javascript/generateTocHtml.js b/javascript/generateTocHtml.tsx similarity index 57% rename from javascript/generateTocHtml.js rename to javascript/generateTocHtml.tsx index 978bedaa3..f7390995a 100644 --- a/javascript/generateTocHtml.js +++ b/javascript/generateTocHtml.tsx @@ -3,42 +3,14 @@ import { tableOfContent, allFilepath } from "./index.js"; import { html_links_part1, html_links_part2, - html_licences, indexPage -} from "./htmlContent"; - -const generateChapterIndex = filename => { - let chapterIndex = ""; - if (filename.match(/chapter/)) { - // match the number after string "chapter" - chapterIndex += filename.match(/(?<=chapter)\d+/g)[0]; - } - if (filename.match(/section/)) { - // "section" - chapterIndex += "." + filename.match(/(?<=section)\d+/g)[0]; - } - if (filename.match(/subsection/)) { - // "subsection" - chapterIndex += "." + filename.match(/(?<=subsection)\d+/g)[0]; - } - if (filename.match(/foreword/)) { - chapterIndex = filename.match(/foreword\d*/g)[0]; - } else if (filename.match(/prefaces/)) { - chapterIndex = filename.match(/prefaces\d*/g)[0]; - } else if (filename.match(/acknowledgements/)) { - chapterIndex = "acknowledgements"; - } else if (filename.match(/references/)) { - chapterIndex = "references"; - } else if (filename.match(/see/)) { - chapterIndex = "see"; - } else if (filename.match(/indexpreface/)) { - chapterIndex = "index"; - } else if (filename.match(/making/)) { - chapterIndex = "making-of"; - } - //console.log(chapterNumber); - return chapterIndex; -}; +} from "./htmlContent.js"; +import LinksHead from "./html/LinksHead.js"; +import Licences from "./html/Licences.js"; +import { generateChapterIndex } from "./tocUtils.js"; +import { IndexHeaderCard, SidebarHeaderCard } from "./TocCards.js"; +import { html, raw } from "hono/html"; +import type { WriteBuffer } from "./types.js"; const truncateTitle = chapterTitle => { let truncatedTitle = ""; @@ -96,7 +68,12 @@ export const sortTOC = allFilepath => { return head.concat(mid, tail); }; -export const recursiveProcessTOC = (index, writeTo, option, toIndexFolder) => { +export const recursiveProcessTOC = ( + index: number, + writeTo: WriteBuffer, + option, + toIndexFolder +) => { if (index >= allFilepath.length) { return; } @@ -121,37 +98,45 @@ export const recursiveProcessTOC = (index, writeTo, option, toIndexFolder) => { if (filename.match(/others/) || filename.match(/subsection/)) { if (option == "index") { - writeTo.push(` + writeTo.push(html` - `); + `); } else if (option == "sidebar") { - writeTo.push(` + writeTo.push(html` - `); + `); } if (filename.match(/others/)) { @@ -165,25 +150,14 @@ export const recursiveProcessTOC = (index, writeTo, option, toIndexFolder) => { if (option == "index") { writeTo.push(`
- + ${( + + )}
- + ${( + + )} \n"); // \n"); //
- writeToIndex.push(html_licences); + writeToIndex.push(); writeToIndex.push("
\n"); //
writeToIndex.push(""); }; diff --git a/javascript/html/Attribution.tsx b/javascript/html/Attribution.tsx new file mode 100644 index 000000000..a980692e9 --- /dev/null +++ b/javascript/html/Attribution.tsx @@ -0,0 +1,26 @@ +import { html } from "hono/html"; +import type { FC } from "hono/jsx"; + +const Attribution: FC = () => { + return html`
+ Harold Abelson and Gerald Jay Sussman
with Julie Sussman
+ original authors +
+ +
+ Martin Henz and Tobias Wrigstad
with Julie Sussman
adapters to JavaScript +
+ +
+ Chan Ger Hean, He Xinyue, Liu Hang, Feng Piaopiao, Jolyn Tan and Wang + Qiandevelopers of Comparison Edition +
`; +}; + +export default Attribution; diff --git a/javascript/html/Licences.tsx b/javascript/html/Licences.tsx new file mode 100644 index 000000000..ea1176983 --- /dev/null +++ b/javascript/html/Licences.tsx @@ -0,0 +1,43 @@ +import { html } from "hono/html"; +import type { FC } from "hono/jsx"; + +const Licences: FC = () => { + return html`
+ +

+ The text of the original SICP 2nd edition is licensed by Harold Abelson + and Gerald Jay Sussman under a + Creative Commons Attribution-ShareAlike 4.0 International License + (CC BY-SA). The text of the JavaScript adaptation is licensed by Harold + Abelson, Gerald Jay Sussman, Martin Henz, and Tobias Wrigstad, also under + CC BY-SA. The figures in the JavaScript adaptation are derived from + figures created by Andres Raba in 2015 and are licensed by Martin Henz and + Tobias Wrigstad, also under CC BY-SA. +

+ +
+ GPL 3 +

+ All Scheme programs in this work are licensed by Harold Abelson and Gerald + Jay Sussman under the + GNU General Public License Version 3 + (GPLv3). All JavaScript programs in this work are licensed by Martin Henz + and Tobias Wrigstad, also under GPLv3. +

`; +}; + +export default Licences; diff --git a/javascript/html/LinksHead.tsx b/javascript/html/LinksHead.tsx new file mode 100644 index 000000000..67efa08d3 --- /dev/null +++ b/javascript/html/LinksHead.tsx @@ -0,0 +1,129 @@ +import { html } from "hono/html"; +import type { FC } from "hono/jsx"; + +const HtmlHeadPart1: FC = () => { + return html` + + + + + + `; +}; + +type HtmlHeadPart2Props = { + toIndexFolder: string; +}; + +const HtmlHeadPart2: FC = ({ toIndexFolder }) => { + return html` + + + + + + + + + + + + + + + + + + + + `; +}; + +type LinksHeadProps = { + children?: any; + toIndexFolder: string; + version: string; +}; + +const LinksHead: FC = ({ + children, + toIndexFolder, + version +}) => { + return ( + + + {children} + + + ); +}; + +export default LinksHead; diff --git a/javascript/html/Navigation.tsx b/javascript/html/Navigation.tsx new file mode 100644 index 000000000..b3647d9f4 --- /dev/null +++ b/javascript/html/Navigation.tsx @@ -0,0 +1,70 @@ +import { html, raw } from "hono/html"; +import type { FC } from "hono/jsx"; + +const NavigationElements: FC = () => { + return html`
+ Color highlighting:
+
+
+ + Unchanged █ + +
+
+ + Scheme █ + +
+
+ + Javascript █ + +
+
+ + Explanation █ + +
+
+ + Web-only █ + +
`; +}; + +const Navigation: FC = () => { + return html` + + `; +}; + +export default Navigation; diff --git a/javascript/htmlContent.js b/javascript/htmlContent.js deleted file mode 100755 index d68352a3b..000000000 --- a/javascript/htmlContent.js +++ /dev/null @@ -1,269 +0,0 @@ -const shortTitleDefault = `SICP — JS`; -const longTitleDefault = `Structure and Interpretation of Computer Programs — Comparison Edition`; -let shortTitle = shortTitleDefault; -let longTitle = longTitleDefault; -let this_edition = ` -
- Mobile-friendly Web Edition -
`; -let legend = ` -
- also available
-
-`; - -export const switchTitle = version => { - if (version == "js") { - shortTitle = shortTitleDefault; - longTitle = longTitleDefault; - this_edition = ` -
- Mobile-friendly Web Edition -
`; - legend = ` -
- also available
-
- - `; - } else if (version == "split") { - shortTitle = `SICP — Scheme/JS`; - longTitle = `Structure and Interpretation of Computer Programs — Comparison Edition`; - this_edition = ` -
- Comparison Edition -
`; - legend = ` -
- Color highlighting:
-
-
- - Unchanged █ - -
-
- - Scheme █ - -
-
- - Javascript █ - -
-
- - Explanation █ - -
-
- - Web-only █ - -
- `; - } else if (version == "scheme") { - // scheme version of the web textbook has yet been developed - console.log("generate sicp scheme web textook"); - } -}; - -// `\\\\`' is used to display double back-slash \\ in template literals -export const html_links_part1 = ` - - - - - - - - - - `; - -export const html_links_part2 = (writeTo, toIndexFolder, version) => { - writeTo.push(` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - `); -}; - -export const indexPage = writeTo => { - writeTo.push(` - - - - -
- - - ${this_edition} - -
- ${legend} -
- -
- Harold Abelson and Gerald Jay Sussman
with Julie Sussman
- original authors -
- -
- Martin Henz and Tobias Wrigstad
with Julie Sussman
adapters to JavaScript -
- -
- Chan Ger Hean, He Xinyue, Liu Hang, Feng Piaopiao, Jolyn Tan and Wang Qiandevelopers of Comparison Edition -
- - `); -}; - -export const beforeContentWrapper = ` -
-`; - -export const html_licences = `
- -

-The text of the original SICP 2nd edition is licensed by Harold Abelson and Gerald Jay Sussman under a Creative Commons Attribution-ShareAlike 4.0 -International License (CC BY-SA). The text of the JavaScript adaptation is licensed by Harold Abelson, Gerald Jay Sussman, Martin Henz, and Tobias Wrigstad, also under CC BY-SA. The figures in the JavaScript adaptation are derived from figures created by Andres Raba in 2015 and are licensed by Martin Henz and Tobias Wrigstad, also under CC BY-SA. -

- -
-GPL 3 -

-All Scheme programs in this work are licensed by Harold Abelson and Gerald Jay Sussman under the -GNU General Public License Version 3 (GPLv3). All JavaScript programs in this work are licensed by Martin Henz and Tobias Wrigstad, also under GPLv3. -

-`; diff --git a/javascript/htmlContent.tsx b/javascript/htmlContent.tsx new file mode 100755 index 000000000..063025367 --- /dev/null +++ b/javascript/htmlContent.tsx @@ -0,0 +1,99 @@ +import { html, raw } from "hono/html"; +import Attribution from "./html/Attribution.js"; +import Navigation from "./html/Navigation.js"; +import type { WriteBuffer, WriteBufferElement } from "./types.js"; +import { JsVersionEdition, JsVersionLegend } from "./versions/js.js"; +import { SplitVersionEdition, SplitVersionLegend } from "./versions/split.js"; + +const shortTitleDefault: WriteBufferElement = `SICP — JS`; +const longTitleDefault: WriteBufferElement = `Structure and Interpretation of Computer Programs — Comparison Edition`; +let shortTitle: WriteBufferElement = shortTitleDefault; +let longTitle: WriteBufferElement = longTitleDefault; +let this_edition: WriteBufferElement = ` +
+ Mobile-friendly Web Edition +
`; +let legend: WriteBufferElement = ` +
+ also available
+
+`; + +export const switchTitle = version => { + if (version == "js") { + shortTitle = shortTitleDefault; + longTitle = longTitleDefault; + this_edition = ; + legend = ; + } else if (version == "split") { + shortTitle = `SICP — Scheme/JS`; + longTitle = `Structure and Interpretation of Computer Programs — Comparison Edition`; + this_edition = ; + legend = ; + } else if (version == "scheme") { + // scheme version of the web textbook has yet been developed + console.log("generate sicp scheme web textook"); + } +}; + +// `\\\\`' is used to display double back-slash \\ in template literals +export const html_links_part1 = ``; + +export const html_links_part2 = ( + writeTo: WriteBuffer, + toIndexFolder: string, + version: string +) => { + writeTo.push(``); + writeTo.push(); + writeTo.push( + html`${raw(shortTitle)} + ${raw(longTitle)}` + ); + writeTo.push(`
`); +}; + +export const indexPage = (writeTo: WriteBuffer) => { + writeTo.push(` + + + + +
+ + + ${this_edition} + +
+ ${legend} +
`); + writeTo.push(); +}; + +export const beforeContentWrapper = ` +
+`; diff --git a/javascript/index.js b/javascript/index.ts similarity index 81% rename from javascript/index.js rename to javascript/index.ts index 2271540f7..ae50077b8 100644 --- a/javascript/index.js +++ b/javascript/index.ts @@ -1,5 +1,4 @@ -import fs from "fs"; -import fse from "fs-extra"; +import fs from "node:fs"; import util from "util"; import path from "path"; @@ -13,39 +12,38 @@ const readFile = util.promisify(fs.readFile); import { switchParseFunctionsLatex, recursiveProcessTextLatex -} from "./parseXmlLatex"; -import { setupSnippetsPdf } from "./processingFunctions/processSnippetPdf"; -import { preamble, frontmatter, ending } from "./latexContent"; -const latexmkrcContent = `$pdflatex = "xelatex %O %S"; -$pdf_mode = 1; -$dvi_mode = 0; -$postscript_mode = 0;`; +} from "./parseXmlLatex.js"; +import { setupSnippetsPdf } from "./processingFunctions/processSnippetPdf.js"; // html (comparison version) -import { switchTitle } from "./htmlContent"; -import { switchParseFunctionsHtml, parseXmlHtml } from "./parseXmlHtml"; -import { setupSnippetsHtml } from "./processingFunctions/processSnippetHtml"; -import { setupReferences } from "./processingFunctions/processReferenceHtml"; -import { generateTOC, sortTOC, indexHtml } from "./generateTocHtml"; +import { switchTitle } from "./htmlContent.js"; +import { switchParseFunctionsHtml, parseXmlHtml } from "./parseXmlHtml.js"; +import { setupSnippetsHtml } from "./processingFunctions/processSnippetHtml.js"; +import { setupReferences } from "./processingFunctions/processReferenceHtml.js"; +import { generateTOC, sortTOC, indexHtml } from "./generateTocHtml.js"; export let allFilepath = []; export let tableOfContent = {}; // js (javascript programs) -import { parseXmlJs } from "./parseXmlJs"; -import { setupSnippetsJs } from "./processingFunctions/processSnippetJs"; -import { getAnswers } from "./processingFunctions/processExercisePdf"; +import { parseXmlJs } from "./parseXmlJs.js"; +import { setupSnippetsJs } from "./processingFunctions/processSnippetJs.js"; +import { getAnswers } from "./processingFunctions/processExercisePdf.js"; // json (for cadet frontend) -import { testIndexSearch } from "./searchRewriteTest"; -import { parseXmlJson } from "./parseXmlJson"; -import { writeRewritedSearchData } from "./searchRewrite"; -import { setupSnippetsJson } from "./processingFunctions/processSnippetJson"; -import { createTocJson } from "./generateTocJson"; -import { setupReferencesJson } from "./processingFunctions/processReferenceJson"; +import { testIndexSearch } from "./searchRewriteTest.js"; +import { parseXmlJson } from "./parseXmlJson.js"; +import { writeRewritedSearchData } from "./searchRewrite.js"; +import { setupSnippetsJson } from "./processingFunctions/processSnippetJson.js"; +import { createTocJson } from "./generateTocJson.js"; +import { setupReferencesJson } from "./processingFunctions/processReferenceJson.js"; +import { createMain } from "./commands/utils.js"; +import type { WriteBuffer } from "./types.js"; export let parseType; let version; -let outputDir; // depends on parseType +let outputDir: string; // depends on parseType + +const __dirname = path.resolve(import.meta.dirname); const inputDir = path.join(__dirname, "../xml"); const ensureDirectoryExists = (path, cb) => { @@ -232,7 +230,7 @@ async function recursiveTranslateXml(filepath, option) { // (to recreate non-split Mobile-friendly Web Edition: remove conditional) const createIndexHtml = version => { const indexFilepath = path.join(outputDir, "index.html"); - const writeToIndex = []; + const writeToIndex: WriteBuffer = []; indexHtml(writeToIndex); const stream = fs.createWriteStream(indexFilepath); stream.once("open", fd => { @@ -241,62 +239,13 @@ const createIndexHtml = version => { }); }; -const createMain = () => { - if (!fs.existsSync(outputDir)) { - fs.mkdirSync(outputDir); - } - - if (parseType == "js" || parseType == "json") { - return; - } - - if (parseType == "web") { - if (!fs.existsSync(path.join(outputDir, "/chapters"))) { - fs.mkdirSync(path.join(outputDir, "/chapters")); - } - fse.copy(path.join(__dirname, "/../static"), outputDir, err => { - if (err) return console.error(err); - }); - return; - } - - // for latex version only - // create sicpjs.tex file - const chaptersFound = []; - const files = fs.readdirSync(inputDir); - files.forEach(file => { - if (file.match(/chapter/)) { - chaptersFound.push(file); - } - }); - const stream = fs.createWriteStream(path.join(outputDir, "sicpjs.tex")); - stream.once("open", fd => { - stream.write(preamble); - stream.write(frontmatter); - chaptersFound.forEach(chapter => { - const pathStr = "./" + chapter + "/" + chapter + ".tex"; - stream.write("\\input{" + pathStr + "}\n"); - }); - stream.write(ending); - stream.end(); - }); - // makes the .latexmkrc file - const latexmkrcStream = fs.createWriteStream( - path.join(outputDir, ".latexmkrc") - ); - latexmkrcStream.once("open", fd => { - latexmkrcStream.write(latexmkrcContent); - latexmkrcStream.end(); - }); -}; - async function main() { parseType = process.argv[2]; if (parseType == "pdf") { outputDir = path.join(__dirname, "../latex_pdf"); switchParseFunctionsLatex(parseType); - createMain(); + createMain(inputDir, outputDir, parseType); console.log("setup snippets\n"); await recursiveTranslateXml("", "setupSnippet"); @@ -324,7 +273,7 @@ async function main() { switchParseFunctionsHtml(version); switchTitle(version); - createMain(); + createMain(inputDir, outputDir, parseType); console.log("\ngenerate table of content\n"); await recursiveTranslateXml("", "generateTOC"); @@ -343,7 +292,7 @@ async function main() { } else if (parseType == "js") { outputDir = path.join(__dirname, "../js_programs"); - createMain(); + createMain(inputDir, outputDir, parseType); console.log("setup snippets\n"); await recursiveTranslateXml("", "setupSnippet"); console.log("setup snippets done\n"); @@ -351,7 +300,7 @@ async function main() { } else if (parseType == "json") { outputDir = path.join(__dirname, "../json"); - createMain(); + createMain(inputDir, outputDir, parseType); console.log("\ngenerate table of content\n"); await recursiveTranslateXml("", "generateTOC"); @@ -363,7 +312,7 @@ async function main() { console.log("setup snippets and references done\n"); await recursiveXmlToHtmlInOrder("parseXml"); - writeRewritedSearchData(); + writeRewritedSearchData(outputDir); // this is meant to be temp; also, will remove the original "generateSearchData" after the updation at the frontend is completed. //testIndexSearch(); } diff --git a/javascript/parseXmlHtml.js b/javascript/parseXmlHtml.tsx similarity index 96% rename from javascript/parseXmlHtml.js rename to javascript/parseXmlHtml.tsx index 95a401c65..661e29e7a 100755 --- a/javascript/parseXmlHtml.js +++ b/javascript/parseXmlHtml.tsx @@ -1,11 +1,11 @@ -import { getChildrenByTagName, ancestorHasTag } from "./utilityFunctions"; +import { getChildrenByTagName, ancestorHasTag } from "./utilityFunctions.js"; import { allFilepath, tableOfContent } from "./index.js"; import { html_links_part1, html_links_part2, beforeContentWrapper -} from "./htmlContent"; -import { recursiveProcessTOC } from "./generateTocHtml"; +} from "./htmlContent.js"; +import { recursiveProcessTOC } from "./generateTocHtml.js"; import { replaceTagWithSymbol, @@ -17,7 +17,10 @@ import { processSnippetHtml, processSnippetHtmlScheme, recursiveProcessPureText -} from "./processingFunctions"; +} from "./processingFunctions/index.js"; +import LinksHead from "./html/LinksHead.js"; +import type { WriteBuffer } from "./types.js"; +import { raw } from "hono/html"; let paragraph_count = 0; let heading_count = 0; @@ -106,7 +109,7 @@ let processTextFunctionsHtml = { writeTo.push(`