Structure and Interpretation of Computer Programs (SICP) Adaptations

repository·master·Indexed 21 days ago

https://github.com/source-academy/sicp

Infrastructure for the multi-edition adaptation of the SICP textbook into JavaScript (SICP JS), Python (SICPy), and the original Scheme. The repository includes processing scripts to generate PDF, Web, Markdown, and JSON formats from XML sources, as well as test suites for example programs using js-slang, py-slang, and MIT/GNU Scheme.

Tokens
2.3K
Snippets
9
Records
14
Agent score
77%

What's inside source-academy-sicp

  1. Available SICP Editions

    master

    This repository provides three editions of Structure and Interpretation of Computer Programs (SICP):

    • SICP JS: Adapted for JavaScript. Includes a PDF, an interactive web version, and a comparison edition (Scheme vs. JS).
    • SICPy: Adapted for Python. Includes a PDF, an interactive web version, a comparison edition (Scheme vs. Python), and an AI chatbot knowledge base.
    • Scheme: The original edition. Includes a PDF and structured JSON content (not yet interactive).

    Each edition provides source code archives containing program snippets (e.g., programs_js, programs_py, programs_scm) and single-file Markdown exports.

  2. SICPy Chatbot Knowledge Base

    master

    The chatbot_notes_py/ directory contains a knowledge base designed for Retrieval-Augmented-Generation (RAG) Q&A bots. It is not autogenerated by the XML pipeline but is AI-generated and checked into git.

    For each chapter, it provides:

    • sicpy_notes_chapter<N>.ex: An Elixir module containing bullet-point summaries and key terms.
    • sicpy_index_terms_chapter<N>.json: A lookup table mapping terms to section numbers for keyword-based retrieval.
  3. Test SICPy (Python) example programs

    master

    Testing SICPy involves two steps: generating the programs from XML and then running the tests.

    1. Generate Programs

    Use the following command to generate the programs_py folder:

    SICP_EDITION=py npx tsx ./javascript/index.js programs_py

    2. Run Tests

    By default, tests run through py-slang (the Source Academy Python interpreter). You can also run tests against CPython for ground-truth comparison.

    Usage:

    # Run all py-slang tests
    yarn test:py
    
    # Run tests for a specific chapter/section
    yarn test:py -- programs_py/chapter1/section1/subsection4
    
    # Run tests against CPython
    yarn test:py:cpython
    
    # Run tests against a local py-slang build
    PY_SLANG=../py-slang/dist/index.cjs yarn test:py

    Note for CPython users: You must have the sourceacademy-sicp runtime installed (via pip install sourceacademy-sicp) or available in a sibling py-slang directory.

    SICP_EDITION=py npx tsx ./javascript/index.js programs_py
    yarn test:py
  4. Generate SICP JSON and Program files

    master

    You can generate the JSON textbook content and extract program snippets from XML sources using Node.js.

    Platform Requirements:

    • Node.js: Required for yarn json and yarn programs.
    • Unix/macOS: Required for generating PDF editions and running the full build. Windows users should use WSL.
  5. Test Scheme (Original) example programs

    master

    Testing the original Scheme edition requires MIT/GNU Scheme to be installed and available on your PATH.

    Usage:

    # Generate the programs
    SICP_EDITION=scm npx tsx ./javascript/index.js programs_scm
    
    # Run all tests
    SICP_EDITION=scm yarn test:scm
    
    # Run tests for a specific chapter
    SICP_EDITION=scm yarn test:scm -- programs_scm/chapter1

    Note: This infrastructure is currently informational; many failures are due to missing cross-snippet prerequisites (REQUIRES) in the Scheme edition.

    SICP_EDITION=scm yarn test:scm -- programs_scm/chapter1
  6. Install the favicon in a Ruby on Rails project

    master

    To install a custom favicon in the project, copy your generated .ico file to the Rails assets directory. The Ruby on Rails asset pipeline will automatically detect and process it for use in the application.

    cp lambda1.ico ../../app/assets/images/favicon.ico
  7. Test SICP JS example programs

    master

    You can test the JavaScript example programs (programs_js) against expected outputs using scripts/test.js.

    By default, tests run through js-slang. To run tests natively on Node using the sicp npm package instead, set the JS_SLANG environment variable to 0.

    Usage:

    # Run all tests
    yarn test
    
    # Run tests scoped to a specific chapter
    yarn test -- programs_js/chapter1
    
    # Run tests natively on Node (using 'sicp' package)
    JS_SLANG=0 yarn test:native
    yarn test -- programs_js/chapter1
  8. Convert a PNG to an ICO favicon using ImageMagick

    master

    To create a favicon, design a simple, bold icon and export it as a PNG. If you require a transparent background, use a tool like Adobe Photoshop with the 'Magic Eraser Tool' to remove white areas before saving.

    To transform the PNG into a 32x32 pixel ICO format, use the ImageMagick convert command.

    convert -resize x32 -gravity center -crop 32x32+0+0 lambda1_transparent.png lambda1.ico
  9. How the different output formats are generated

    master

    The processing logic varies significantly based on the selected parseType:

    PDF (pdf)

    1. Sets up snippets via setupSnippetsPdf.
    2. Recursively processes text into LaTeX using recursiveProcessTextLatex.
    3. Collects exercise answers via getAnswers() and writes them to answers.tex.

    Web (web)

    1. Generates a Table of Contents (TOC) using generateTOC.
    2. Sets up snippets and references using setupSnippetsHtml and setupReferences.
    3. Parses XML into HTML files using parseXmlHtml.
    4. Supports versions like split or scheme to adjust HTML structure.

    Markdown (md)

    1. Generates a TOC.
    2. Performs a collectLabels pass to resolve cross-references.
    3. Performs a renderMarkdown pass to accumulate content.
    4. Finalizes the single file using finalizeMarkdown.

    Programs (programs)

    1. Sets up snippets via setupSnippetsJs.
    2. Parses XML into program files via parseXmlJs.

    JSON (json)

    1. Generates a TOC via createTocJson.
    2. Sets up snippets and references via setupSnippetsJson and setupReferencesJson.
    3. Parses XML into JSON via parseXmlJson.
    4. Writes search data using writeSearchData.
  10. Run the SICP edition processing scripts

    master

    The javascript/index.ts file serves as the entrypoint for processing SICP XML source files into various formats (PDF/LaTeX, Web/HTML, Markdown, Programs, or JSON). The script is executed via CLI, where the first argument determines the parseType and subsequent arguments may specify versions or modes.

    Supported parseType values:

    • pdf: Generates LaTeX files for PDF production.
    • web: Generates HTML files (supports split or scheme versions).
    • md: Generates a single-file plain Markdown export.
    • programs: Processes JavaScript/Python programs into a dedicated directory.
    • json: Generates JSON data for frontend use (e.g., search indexes).

    Execution Pattern

    The script uses process.argv to determine the workflow. It automatically detects the current edition (JavaScript or Python) using getEdition() and sets the appropriate input/output directories.

    # Example: Generate the web version (split mode)
    npx ts-node javascript/index.ts web split
    
    # Example: Generate the Markdown version
    npx ts-node javascript/index.ts md
    
    # Example: Generate JSON data
    npx ts-node javascript/index.ts json
  11. Extract and format a name with addName()

    master

    The addName function extracts a name from a node by looking for the first child element with the tag name NAME. It processes the text content of that element using recursiveProcessTextLatex, joins the resulting parts, trims them, and pushes the name followed by }\n\n into the writeTo array. It returns the extracted name string.

    // node: the parent node containing the <NAME> tag
    // writeTo: an array to which the formatted name is pushed
    const name = addName(node, writeTo);
  12. Process a list of nodes with processList()

    master

    The processList function iterates through a linked list of DOM nodes. If a node is an LI element, it appends the LaTeX list item marker \item to the writeTo array and then recursively processes the node's first child using recursiveProcessTextLatex. It then continues to the next sibling in the list.

    // node: the starting DOM node
    // writeTo: an array to which processed strings are pushed
    processList(node, writeTo);