Переглянути джерело

Use the new markdown rendermime

Steven Silvester 9 роки тому
батько
коміт
6cc5fc821f

+ 2 - 1
examples/notebook/src/index.ts

@@ -21,7 +21,7 @@ import {
 
 import {
   HTMLRenderer, LatexRenderer, ImageRenderer, TextRenderer,
-  ConsoleTextRenderer, JavascriptRenderer, SVGRenderer
+  ConsoleTextRenderer, JavascriptRenderer, SVGRenderer, MarkdownRenderer
 } from 'jupyter-js-ui/lib/renderers';
 
 import {
@@ -72,6 +72,7 @@ function main(): void {
   let rendermime = new RenderMime<Widget>();
   const transformers = [
     new JavascriptRenderer(),
+    new MarkdownRenderer(),
     new HTMLRenderer(),
     new ImageRenderer(),
     new SVGRenderer(),

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     "diff-match-patch": "^1.0.0",
     "file-loader": "^0.8.5",
     "jupyter-js-services": "^0.7.1",
-    "jupyter-js-ui": "^0.6.0",
+    "jupyter-js-ui": "file:../ui",
     "jupyter-js-utils": "^0.3.4",
     "marked": "^0.3.5",
     "phosphor-disposable": "^1.0.5",

+ 10 - 13
src/notebook/cells/widget.ts

@@ -2,9 +2,6 @@
 // Distributed under the terms of the Modified BSD License.
 'use strict';
 
-import * as marked
-  from 'marked';
-
 import {
   RenderMime
 } from 'jupyter-js-ui/lib/rendermime';
@@ -30,12 +27,12 @@ import {
 } from '../input-area';
 
 import {
-  OutputAreaWidget, IOutputAreaModel
-} from '../output-area';
+  MimeBundle
+} from '../notebook/nbformat';
 
 import {
-  removeMath, replaceMath, typeset
-} from '../utils/latex';
+  OutputAreaWidget, IOutputAreaModel
+} from '../output-area';
 
 import {
   sanitize
@@ -229,12 +226,12 @@ class MarkdownCellWidget extends BaseCellWidget {
     if (model.rendered) {
       if (this._dirty) {
         let text = model.input.textEditor.text || DEFAULT_MARKDOWN_TEXT;
-        let data = removeMath(text);
-        let html = marked(data['text']);
-        // Always sanitize markdown output.
-        html = sanitize(html);
-        this.rendered.node.innerHTML = replaceMath(html, data['math']);
-        typeset(this.rendered.node);
+        text = sanitize(text);
+        let bundle: MimeBundle = { 'application/vnd.jupyter.markdown': text };
+        this._rendered.dispose();
+        this._rendered = this._rendermime.render(bundle);
+        this._rendered.addClass(RENDERER_CLASS);
+        (this.layout as PanelLayout).addChild(this._rendered);
       }
       this._rendered.show();
       this.input.hide();

+ 0 - 1
src/notebook/typings.d.ts

@@ -1,5 +1,4 @@
 /// <reference path="../typings/es6-promise/es6-promise.d.ts"/>
-/// <reference path="../typings/marked/marked.d.ts"/>
 /// <reference path="../typings/sanitizer/sanitizer.d.ts"/>
 /// <reference path="../typings/codemirror/codemirror.d.ts"/>
 /// <reference path="../typings/diff-match-patch/diff-match-patch.d.ts"/>

+ 0 - 213
src/notebook/utils/latex.ts

@@ -1,213 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-'use strict';
-
-
-// Some magic for deferring mathematical expressions to MathJax
-// by hiding them from the Markdown parser.
-// Some of the code here is adapted with permission from Davide Cervone
-// under the terms of the Apache2 license governing the MathJax project.
-// Other minor modifications are also due to StackExchange and are used with
-// permission.
-
-const inline = '$'; // the inline math delimiter
-
-// MATHSPLIT contains the pattern for math delimiters and special symbols
-// needed for searching for math in the text input.
-const MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
-
-// A module-level initialization flag.
-let initialized = false;
-
-
-/**
- *  Break up the text into its component parts and search
- *    through them for math delimiters, braces, linebreaks, etc.
- *  Math delimiters must match and braces must balance.
- *  Don't allow math to pass through a double linebreak
- *    (which will be a paragraph).
- */
-export
-function removeMath(text: string): { text: string, math: string[] } {
-  let math: string[] = []; // stores math strings for later
-  let start: number;
-  let end: string;
-  let last: number;
-  let braces: number;
-  let deTilde: (text: string) => string;
-
-  if (!initialized) {
-    init();
-    initialized = true;
-  }
-
-  // Except for extreme edge cases, this should catch precisely those pieces of the markdown
-  // source that will later be turned into code spans. While MathJax will not TeXify code spans,
-  // we still have to consider them at this point; the following issue has happened several times:
-  //
-  //     `$foo` and `$bar` are varibales.  -->  <code>$foo ` and `$bar</code> are variables.
-  let hasCodeSpans = /`/.test(text);
-  if (hasCodeSpans) {
-    text = text.replace(/~/g, '~T').replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, (wholematch) => wholematch.replace(/\$/g, '~D'));
-    deTilde = (text: string) => {
-      return text.replace(/~([TD])/g,
-        (wholematch, character) => (character === 'T') ? '~' : '$');
-    };
-  } else {
-    deTilde = (text: string) => { return text; };
-  }
-
-  let blocks = text.replace(/\r\n?/g, '\n').split(MATHSPLIT);
-
-  for (let i = 1, m = blocks.length; i < m; i += 2) {
-    let block = blocks[i];
-    if (block.charAt(0) === '@') {
-      //
-      //  Things that look like our math markers will get
-      //  stored and then retrieved along with the math.
-      //
-      blocks[i] = '@@' + math.length + '@@';
-      math.push(block);
-    }
-    else if (start) {
-      //
-      //  If we are in math, look for the end delimiter,
-      //    but don't go past double line breaks, and
-      //    and balance braces within the math.
-      //
-      if (block === end) {
-        if (braces) {
-          last = i;
-        }
-        else {
-          blocks = processMath(start, i, deTilde, math, blocks);
-          start  = null;
-          end    = null;
-          last   = null;
-        }
-      }
-      else if (block.match(/\n.*\n/)) {
-        if (last) {
-          i = last;
-          blocks = processMath(start, i, deTilde, math, blocks);
-        }
-        start = null;
-        end = null;
-        last = null;
-        braces = 0;
-      }
-      else if (block === '{') {
-        braces++;
-      }
-      else if (block === '}' && braces) {
-        braces--;
-      }
-    }
-    else {
-      //
-      //  Look for math start delimiters and when
-      //    found, set up the end delimiter.
-      //
-      if (block === inline || block === '$$') {
-        start = i;
-        end = block;
-        braces = 0;
-      }
-      else if (block.substr(1, 5) === 'begin') {
-        start = i;
-        end = '\\end' + block.substr(6);
-        braces = 0;
-      }
-    }
-  }
-  if (last) {
-    blocks = processMath(start, last, deTilde, math, blocks);
-    start = null;
-    end = null;
-    last = null;
-  }
-  return { text: deTilde(blocks.join('')), math };
-};
-
-
-/**
- * Put back the math strings that were saved,
- * and clear the math array (no need to keep it around).
- */
-export
-function replaceMath(text: string, math: string[]): string {
-  text = text.replace(/@@(\d+)@@/g, (match, n) => math[n]);
-  return text;
-};
-
-
-/**
- * Typeset the math in a node.
- */
-export
-function typeset(node: HTMLElement): void {
-  if (!initialized) {
-    init();
-    initialized = true;
-  }
-  if ((window as any).MathJax) {
-    MathJax.Hub.Queue(['Typeset', MathJax.Hub, node]);
-  }
-}
-
-
-/**
- * Initialize latex handling.
- */
-function init() {
-  if (!(window as any).MathJax) {
-    return;
-  }
-  MathJax.Hub.Config({
-    tex2jax: {
-      inlineMath: [ ['$', '$'], ['\\(', '\\)'] ],
-      displayMath: [ ['$$', '$$'], ['\\[', '\\]'] ],
-      processEscapes: true,
-      processEnvironments: true
-    },
-    // Center justify equations in code and markdown cells. Elsewhere
-    // we use CSS to left justify single line equations in code cells.
-    displayAlign: 'center',
-    CommonHTML: {
-       linebreaks: { automatic: true }
-     }
-  });
-  MathJax.Hub.Configured();
-}
-
-
-/**
- * Process math blocks.
- *
- * The math is in blocks i through j, so
- *   collect it into one block and clear the others.
- *  Replace &, <, and > by named entities.
- *  For IE, put <br> at the ends of comments since IE removes \n.
- *  Clear the current math positions and store the index of the
- *   math, then push the math string onto the storage array.
- *  The preProcess function is called on all blocks if it has been passed in
- */
-function processMath(i: number, j: number, preProcess: (input: string) => string, math: string[], blocks: string[]): string[] {
-  let block = blocks.slice(i, j + 1).join('').replace(/&/g, '&amp;') // use HTML entity for &
-  .replace(/</g, '&lt;') // use HTML entity for <
-  .replace(/>/g, '&gt;') // use HTML entity for >
-  ;
-  if (navigator && navigator.appName === 'Microsoft Internet Explorer') {
-    block = block.replace(/(%[^\n]*)\n/g, '$1<br/>\n');
-  }
-  while (j > i) {
-    blocks[j] = '';
-    j--;
-  }
-  blocks[i] = '@@' + math.length + '@@'; // replace the current block text with a unique tag to find later
-  if (preProcess){
-    block = preProcess(block);
-  }
-  math.push(block);
-  return blocks;
-};

+ 0 - 128
typings/marked/marked.d.ts

@@ -1,128 +0,0 @@
-// Type definitions for Marked
-// Project: https://github.com/chjj/marked
-// Definitions by: William Orr <https://github.com/worr>
-// Definitions: https://github.com/borisyankov/DefinitelyTyped
-
-
-interface MarkedStatic {
-    /**
-     * Compiles markdown to HTML.
-     *
-     * @param src String of markdown source to be compiled
-     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
-     * @return String of compiled HTML
-     */
-    (src: string, callback: Function): string;
-
-    /**
-     * Compiles markdown to HTML.
-     *
-     * @param src String of markdown source to be compiled
-     * @param options Hash of options
-     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
-     * @return String of compiled HTML
-     */
-    (src: string, options?: MarkedOptions, callback?: Function): string;
-
-    /**
-     * @param src String of markdown source to be compiled
-     * @param options Hash of options
-     */
-    lexer(src: string, options?: MarkedOptions): any[];
-
-    /**
-     * Compiles markdown to HTML.
-     *
-     * @param src String of markdown source to be compiled
-     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
-     * @return String of compiled HTML
-     */
-    parse(src: string, callback: Function): string;
-
-    /**
-     * Compiles markdown to HTML.
-     *
-     * @param src String of markdown source to be compiled
-     * @param options Hash of options
-     * @param callback Function called when the markdownString has been fully parsed when using async highlighting
-     * @return String of compiled HTML
-     */
-    parse(src: string, options?: MarkedOptions, callback?: Function): string;
-
-    /**
-     * @param options Hash of options
-     */
-    parser(src: any[], options?: MarkedOptions): string;
-
-    /**
-     * Sets the default options.
-     *
-     * @param options Hash of options
-     */
-    setOptions(options: MarkedOptions): void;
-}
-
-interface MarkedOptions {
-    /**
-     * Type: object Default: new Renderer()
-     *
-     * An object containing functions to render tokens to HTML.
-     */
-    renderer?: Object; 
-
-    /**
-     * Enable GitHub flavored markdown.
-     */
-    gfm?: boolean;
-
-    /**
-     * Enable GFM tables. This option requires the gfm option to be true.
-     */
-    tables?: boolean;
-
-    /**
-     * Enable GFM line breaks. This option requires the gfm option to be true.
-     */
-    breaks?: boolean;
-
-    /**
-     * Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.
-     */
-    pedantic?: boolean;
-
-    /**
-     * Sanitize the output. Ignore any HTML that has been input.
-     */
-    sanitize?: boolean;
-
-    /**
-     * Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.
-     */
-    smartLists?: boolean;
-
-    /**
-     * Shows an HTML error message when rendering fails.
-     */
-    silent?: boolean;
-
-    /**
-     * A function to highlight code blocks. The function takes three arguments: code, lang, and callback.
-     */
-    highlight? (code: string, lang: string, callback?: Function): string;
-
-    /**
-     * Set the prefix for code block classes.
-     */
-    langPrefix?: string;
-
-    /**
-     * Use "smart" typograhic punctuation for things like quotes and dashes.
-     */
-    smartypants?: boolean;
-}
-
-declare module "marked" {
-    export = marked;
-}
-
-declare var marked: MarkedStatic;

+ 0 - 30
typings/transformime/transformime.d.ts

@@ -1,30 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-declare type Transformer = (mimetype: string, 
-                           data: string, 
-                           document: HTMLDocument) => HTMLElement;
-
-
-declare module 'transformime' {
-    export interface TransformResult {
-        mimetype: string
-        el: HTMLElement;
-    }
-    export class Transformime {
-        constructor(transformers: Transformer[])
-        transform(bundle: any, document: HTMLDocument): Promise<TransformResult>
-    }
-    export var TextTransformer: Transformer
-    export var ImageTransformer: Transformer
-    export var HTMLTransformer: Transformer
-}
-
-declare module 'transformime-jupyter-transformers' {
-    export var consoleTextTransform: Transformer;
-    export var markdownTransform: Transformer;
-    export var LaTeXTransform: Transformer;
-    export var PDFTransform: Transformer;
-    export var SVGTransform: Transformer;
-    export var ScriptTransform: Transformer; 
-}