diff --git a/LICENSE.txt b/LICENSE.txt index 1645e76..90cd477 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,7 @@ The MIT License (MIT) -Copyright (c) 2015 Tate Tian (tatetian@gmail.com) +Copyright (c) 2020 Saswat Padhi (saswat.sourav@gmail.com) +Copyright (c) 2015-2019 Tate Tian (tatetian@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 347593a..96960ae 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: default setup lint build release clean -VERSION=1.1 +VERSION=2.0 # Building tools BROWSERIFY = $(realpath ./node_modules/.bin/browserify) @@ -12,6 +12,8 @@ UGLIFYJS = $(realpath ./node_modules/.bin/uglifyjs) \ CLEANCSS = $(realpath ./node_modules/.bin/cleancss) ESLINT = $(realpath ./node_modules/.bin/eslint) +SAMPLES = build/katex-samples.html build/mathjax-v2-samples.html build/mathjax-v3-samples.html + default: build @@ -21,12 +23,12 @@ setup: static/katex/ static/katex/: @rm -rf static/katex - cd static && wget https://github.com/Khan/KaTeX/releases/download/v0.8.0/katex.zip && unzip katex.zip + cd static && wget https://github.com/Khan/KaTeX/releases/download/v0.11.1/katex.zip && unzip katex.zip @rm -rf static/katex.zip @echo "> Katex downloaded" -build: build/pseudocode.js build/pseudocode.css build/samples.html +build: build/pseudocode.js build/pseudocode.css $(SAMPLES) @echo "> Building succeeded" build/pseudocode.js: pseudocode.js $(wildcard src/*.js) @@ -43,7 +45,7 @@ watch-js: pseudocode.js $(wildcard src/*.js) build/pseudocode.css: static/pseudocode.css cp static/pseudocode.css build/pseudocode.css -build/samples.html: static/samples.html.template +build/%-samples.html: static/%-samples.html.template cp $< $@ @@ -57,7 +59,7 @@ build/pseudocode-js.tar.gz: build/$(RELEASE_DIR) build/pseudocode-js.zip: build/$(RELEASE_DIR) cd build && zip -rq pseudocode-js.zip $(RELEASE_DIR) -build/$(RELEASE_DIR): build/pseudocode.js build/pseudocode.min.js build/pseudocode.css build/pseudocode.min.css build/samples.html README.md +build/$(RELEASE_DIR): build/pseudocode.js build/pseudocode.min.js build/pseudocode.css build/pseudocode.min.css $(SAMPLES) README.md mkdir -p build/$(RELEASE_DIR) cp -r $^ build/$(RELEASE_DIR) diff --git a/README.md b/README.md index 71aea5f..5ba7a6d 100644 --- a/README.md +++ b/README.md @@ -16,57 +16,78 @@ It supports all modern browsers, including Chrome, Safari, Firefox, Edge, and IE 9 - IE 11. ## Demo -Visit the [project website](http://www.tatetian.io/pseudocode.js) for demo. +Visit the [project website](https://saswatpadhi.github.io/pseudocode.js) for demo. ## Usage ### Quick Start -Download [pseudocode.js](https://github.com/tatetian/pseudocode.js/releases), -and host the files on your server. And then include the `js` and `css` files in -your HTML files: + +Pseudocode.js can render math formulas using either +[KaTeX](https://github.com/Khan/KaTeX), or [MathJax](https://www.mathjax.org/). + +#### Step 1A · For KaTeX users +Include the following in the `
` of your page: ```html - - + + ``` -Pseudocode.js depends on [KaTeX](https://github.com/Khan/KaTeX) to render math -formulas and uses KaTeX's fonts to render texts. So make sure that [KaTeX is -setup](https://github.com/Khan/KaTeX#usage) properly. +#### Step 1B · For MathJax 2.x users +Include the following in the `` of your page: -Assume the pseudocode to be rendered is in a `` DOM element: ```html --\begin{algorithmc} -\PRINT \texttt{'hello world'} -\end{algorithmc} -+ + ``` -To render the above code as a HTML element and append to a parent DOM element, -call `pseudocode.render`: -```js -var code = document.getElementById("hello-world-code").textContent; -var parentEl = document.body; -var options = { - lineNumber: true -}; -pseudocode.render(code, parentEl, options); +#### Step 1C · For MathJax 3.x users +Include the following in the `` of your page: + +```html + + ``` -To generate a string of rendered HTML, call `pseudocode.renderToString`: -```js -var code = document.getElementById("hello-world-code").textContent; -var options = { - lineNumber: true -}; -var htmlStr = pseudocode.renderToString(code, options); -console.log(htmlStr); +#### Step 2 · Grab pseudocode.js +Download a stable release of [pseudocode.js](https://github.com/SaswatPadhi/pseudocode.js/releases), +and host the files on your server. +Then include the following in the `` of your page: + +```html + + ``` -### Example -To give you a sense of the grammar for pseudocode, here is an example that -illustrates a quicksort algorithm: + +#### Step 3 · Write your pseudocode inside a `` +We assume the pseudocode to be rendered is in a `` DOM element. +Here is an example that illustrates a quicksort algorithm: + ```tex % This quicksort algorithm is extracted from Chapter 7, Introduction to Algorithms (3rd edition) \begin{algorithm} @@ -95,6 +116,38 @@ illustrates a quicksort algorithm: \end{algorithm} ``` +### API +Assume the pseudocode to be rendered is in a `` DOM element: +```html ++\begin{algorithmc} +\PRINT \texttt{'hello world'} +\end{algorithmc} ++``` + +To render the above code as a HTML element and append to a parent DOM element, +call `pseudocode.render`: +```js +var code = document.getElementById("hello-world-code").textContent; +var parentEl = document.body; +var options = { + lineNumber: true +}; +pseudocode.render(code, parentEl, options); +``` + +To generate a string of rendered HTML, call `pseudocode.renderToString`: +```js +var code = document.getElementById("hello-world-code").textContent; +var options = { + lineNumber: true +}; +var htmlStr = pseudocode.renderToString(code, options); +console.log(htmlStr); +``` + + ### Grammar There are several packages for typesetting algorithms in LaTeX, among which [`algorithmic`](http://mirror.ctan.org/tex-archive/macros/latex/contrib/algorithms/algorithms.pdf) @@ -237,17 +290,21 @@ make setup make ``` -Then, open `static/test-suite.html` in your favourite browser to see whether -algorithms are typeset correctly. +Then, open one of the sample documents: +- `build/katex-samples.html`, or +- `build/mathjax-v2-samples.html`, or +- `build/mathjax-v3-samples.html` +in your favourite browser to check if the algorithms are typeset correctly. ## Author -Tate Tian ([@tatetian](https://github.com/tatetian)) creates pseudocode.js. Any -suggestions and bug reports are welcome. +pseudocode.js was originally written by Tate Tian ([@tatetian](https://github.com/tatetian)). +Together with [@ZJUGuoShuai](https://github.com/ZJUGuoShuai), +I ([@SaswatPadhi](https://github.com/SaswatPadhi)) added the MathJax support, +and I am the current maintainer of this project. +Suggestions, bug reports and pull requests are most welcome. ## Acknowledgement -Pseudocode.js is partially inspired by [KaTeX](http://khan.github.io/KaTeX/) and -relies on it to render math formulas. +Pseudocode.js is partially inspired by [KaTeX](http://khan.github.io/KaTeX/). Thanks Emily Eisenberg([@xymostech](https://github.com/xymostech)) and other contributers for building such a wonderful project. - diff --git a/package.json b/package.json index c8ca5da..ddb6f72 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,19 @@ { "name": "pseudocode", - "version": "1.1.1", + "version": "2.0", "author": { - "name": "Tate Tian", - "email": "tatetian@gmail.com", - "url": "http://www.tatetian.me" + "name": "Saswat Padhi", + "email": "saswat.sourav@gmail.com", + "url": "https://saswatpadhi.github.io/" }, "description": "Beautiful pseudocode for the Web", "main": "pseudocode.js", "repository": { "type": "git", - "url": "git://github.com/tatetian/pseudocode.js" + "url": "git://github.com/SaswatPadhi/pseudocode.js" }, "files": [ - "PseudoCode.js", + "pseudoCode.js", "src/" ], "devDependencies": { diff --git a/src/Renderer.js b/src/Renderer.js index 064d7b3..d9f41f4 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -3,7 +3,7 @@ var utils = require('./utils'); /* - * TextStyle - used by TextEnvironment class to handles LaTeX text-style + * TextStyle - used by TextEnvironment class to handle LaTeX text-style * commands or declarations. * * The font declarations are: @@ -141,7 +141,7 @@ TextEnvironment.prototype._renderCloseText = function(node) { var newTextStyle = new TextStyle(this._textStyle.fontSize()); var closeTextEnv = new TextEnvironment(node.children, newTextStyle); if (node.whitespace) this._html.putText(' '); - this._html.putSpan(closeTextEnv.renderToHTML()); + this._html.putHTML(closeTextEnv.renderToHTML()); }; TextEnvironment.prototype.renderToHTML = function() { @@ -160,12 +160,24 @@ TextEnvironment.prototype.renderToHTML = function() { this._html.putText(text); break; case 'math': - if (!katex) { + useKatex = true; + if (typeof katex === 'undefined') { try { katex = require('katex'); } - catch (e) { throw 'katex is required to render math'; } + catch (e) { + if (typeof MathJax === 'undefined') { + throw 'KaTeX or MathJax is required to render math'; + } + var useKatex = false; + } } - var mathHTML = katex.renderToString(text); - this._html.putSpan(mathHTML); + + if (useKatex) { // KaTeX + this._html.putHTML(katex.renderToString(text)); + } + else { // MathJax + this._html.putText("$" + text + "$"); + } + break; case 'cond-symbol': this._html @@ -244,7 +256,7 @@ TextEnvironment.prototype.renderToHTML = function() { this._html.beginSpan(null, this._textStyle.toCSS()); var textEnvForDclr = new TextEnvironment(this._nodes, this._textStyle); - this._html.putSpan(textEnvForDclr.renderToHTML()); + this._html.putHTML(textEnvForDclr.renderToHTML()); this._html.endSpan(); break; case 'font-cmd': @@ -256,7 +268,7 @@ TextEnvironment.prototype.renderToHTML = function() { this._html.beginSpan(null, innerTextStyle.toCSS()); var textEnvForCmd = new TextEnvironment(textNode.children, innerTextStyle); - this._html.putSpan(textEnvForCmd.renderToHTML()); + this._html.putHTML(textEnvForCmd.renderToHTML()); this._html.endSpan(); break; default: @@ -308,8 +320,7 @@ HTMLBuilder.prototype.endSpan = function() { return this._endTag('span'); }; -HTMLBuilder.prototype.putHTML = -HTMLBuilder.prototype.putSpan = function(html) { +HTMLBuilder.prototype.putHTML = function(html) { this._flushText(); this._body.push(html); return this; @@ -799,13 +810,13 @@ Renderer.prototype._buildTree = function(node) { case 'open-text': var openTextEnv = new TextEnvironment(node.children, this._globalTextStyle); - this._html.putSpan(openTextEnv.renderToHTML()); + this._html.putHTML(openTextEnv.renderToHTML()); break; case 'close-text': var outerFontSize = this._globalTextStyle.fontSize(); var newTextStyle = new TextStyle(outerFontSize); var closeTextEnv = new TextEnvironment(node.children, newTextStyle); - this._html.putSpan(closeTextEnv.renderToHTML()); + this._html.putHTML(closeTextEnv.renderToHTML()); break; default: throw new ParseError('Unexpected ParseNode of type ' + node.type); diff --git a/static/samples.html.template b/static/katex-samples.html.template similarity index 89% rename from static/samples.html.template rename to static/katex-samples.html.template index db24b48..0a9f306 100644 --- a/static/samples.html.template +++ b/static/katex-samples.html.template @@ -1,19 +1,22 @@ + -Pseudocode.js Samples - - - - +Pseudocode.js Samples with KaTeX + + + + + +