The following hooks are called for each page of the book and can be used to change page content (html, data or markdown) Before parsing documents
343544
function(page) {
            // Get all code texts
            umls = page.content.match(/```(uml|puml|plantuml)((.*[\r\n]+)+?)?```/igm);
            // Begin replace
            if (umls instanceof Array) {
                for (var i = 0, len = umls.length; i < len; i++) {
                    page.content = page.content.replace(
                        umls[i],
                        // Parameter parser for user argument to gitbook argument
                        umls[i].replace(/```(uml|puml|plantuml)[ \t]+{(.*)}/i,
                            function(match, p1, p2) {
                                var newStr = "";
                                var modeQuote = false;
                                var modeArray = false;
                                var modeChar = false;
                                var modeEqual = false;
                                // Trim left and right space
                                var str = p2.replace(/^\s+|\s+$/g,"");

                                // Build new str
                                for(var i = 0; i < str.length; i++){
                                    if (str.charAt(i) == "\"") {
                                        modeQuote = !modeQuote;
                                        modeChar = true;
                                        newStr += str.charAt(i);
                                        continue;
                                    }
                                    if (str.charAt(i) == "[") {
                                        modeArray = true;
                                        newStr += str.charAt(i);
                                        continue;
                                    }
                                    if (str.charAt(i) == "]") {
                                        modeArray = false;
                                        newStr += str.charAt(i);
                                        continue;
                                    }
                                    if (modeQuote || modeArray) {
                                        // In quote, keep all string
                                        newStr += str.charAt(i);
                                    } else {
                                        // Out of quote, process it
                                        if (str.charAt(i).match(/[A-Za-z0-9_]/)) {
                                            modeChar = true;
                                            newStr += str.charAt(i);
                                        } else if (str.charAt(i).match(/[=]/)) {
                                            modeEqual = true;
                                            modeChar = false;
                                            newStr += str.charAt(i);
                                        } else if (modeChar && modeEqual) {
                                            modeChar = false;
                                            modeEqual = false;
                                            newStr += ",";
                                        }
                                    }
                                }

                                newStr = newStr.replace(/,$/,"");

                                return "{% uml " + newStr + " %}";
                            })
                        .replace(/```(uml|puml|plantuml)/i, '{% uml %}')
                        .replace(/```/, '{% enduml %}'));
                }
            }
            return page;
        }
1015126
function (hooks, ui) {

        var config = hooks
            .map(transformConfig)
            .reduce(createConfigItem, {});

        return {
            /**
             * pagesConfig - This is the angular configuration such as routes
             */
            pagesConfig: configTmpl
                .replace("%when%", hooks.reduce(
                    createAngularRoutes,
                    ""
                ))
                .replace("%pages%", JSON.stringify(
                    config,
                    null,
                    4
                )),
            /**
             * pagesConfig in object form
             */
            pagesObj: config,
            pageMarkup: function () {
                return preAngular(ui.pluginManager.plugins, config, ui);
            }
        };
    }
1167604
def add_content(self, text=None, *markdown_files):
        """"""
        for markdown_file in markdown_files:
            self.markdown_text += self._text_file(markdown_file)

        if text:
            self.markdown_text += text
411075
protected final static function initHooks()
    {
        if ( isset( $init ) )
            return;

        static $init = true;

        $ini = eZINI::instance( 'content.ini' );

        self::attachHooks( 'preQueue', $ini->variable( 'PublishingSettings', 'AsynchronousPublishingPreQueueHooks' ) );
        self::attachHooks( 'postHandling', $ini->variable( 'PublishingSettings', 'AsynchronousPublishingPostHandlingHooks' ) );
    }
872060
def on_page_markdown(self, markdown, page, config,
                          site_navigation=None, **kwargs):
        ""

        # the site_navigation argument has been made optional
        # (deleted in post 1.0 mkdocs, but maintained here
        # for backward compatibility)

        if not self.variables:
            return markdown

        else:

            # Create templae and get the variables
            md_template = Template(markdown)

            # Execute the jinja2 template and return
            return md_template.render(**self.variables)
1255132
function startModulesAfterPageLoad( lo ) {
  // header hooks
  if ( ( lo != null ) && ( lo.header != null ) && ( lo.header.modules != null ) ) {
    for ( var i = 0; i < lo.header.modules.length; i++ ) {
      startModuleAfterPageLoad( lo.header.modules[i] );
    }
  }
  // footer hooks
  if ( ( lo != null ) && ( lo.footer != null ) && ( lo.footer.modules != null ) ) {
    for ( var i = 0; i < lo.footer.modules.length; i++ ) {
      startModuleAfterPageLoad( lo.footer.modules[i] );
    }
  }
  ajaxOngoing--;
}
1364198
function BookmarkManager(selection) {
      var dom = selection.dom;

      /**
       * Returns a bookmark location for the current selection. This bookmark object
       * can then be used to restore the selection after some content modification to the document.
       *
       * @method getBookmark
       * @param {Number} type Optional state if the bookmark should be simple or not. Default is complex.
       * @param {Boolean} normalized Optional state that enables you to get a position that it would be after normalization.
       * @return {Object} Bookmark object, use moveToBookmark with this object to restore the selection.
       * @example
       * // Stores a bookmark of the current selection
       * var bm = tinymce.activeEditor.selection.getBookmark();
       *
       * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
       *
       * // Restore the selection bookmark
       * tinymce.activeEditor.selection.moveToBookmark(bm);
       */
      this.getBookmark = function (type, normalized) {
        var rng, rng2, id, collapsed, name, element, chr = '&#xFEFF;', styles;

        function findIndex(name, element) {
          var count = 0;

          Tools.each(dom.select(name), function (node) {
            if (node.getAttribute('data-mce-bogus') === 'all') {
              return;
            }

            if (node == element) {
              return false;
            }

            count++;
          });

          return count;
        }

        function normalizeTableCellSelection(rng) {
          function moveEndPoint(start) {
            var container, offset, childNodes, prefix = start ? 'start' : 'end';

            container = rng[prefix + 'Container'];
            offset = rng[prefix + 'Offset'];

            if (container.nodeType == 1 && container.nodeName == "TR") {
              childNodes = container.childNodes;
              container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
              if (container) {
                offset = start ? 0 : container.childNodes.length;
                rng['set' + (start ? 'Start' : 'End')](container, offset);
              }
            }
          }

          moveEndPoint(true);
          moveEndPoint();

          return rng;
        }

        function getLocation(rng) {
          var root = dom.getRoot(), bookmark = {};

          function getPoint(rng, start) {
            var container = rng[start ? 'startContainer' : 'endContainer'],
              offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;

            if (container.nodeType == 3) {
              if (normalized) {
                for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) {
                  offset += node.nodeValue.length;
                }
              }

              point.push(offset);
            } else {
              childNodes = container.childNodes;

              if (offset >= childNodes.length && childNodes.length) {
                after = 1;
                offset = Math.max(0, childNodes.length - 1);
              }

              point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
            }

            for (; container && container != root; container = container.parentNode) {
              point.push(dom.nodeIndex(container, normalized));
            }

            return point;
          }

          bookmark.start = getPoint(rng, true);

          if (!selection.isCollapsed()) {
            bookmark.end = getPoint(rng);
          }

          return bookmark;
        }

        function findAdjacentContentEditableFalseElm(rng) {
          function findSibling(node, offset) {
            var sibling;

            if (NodeType.isElement(node)) {
              node = RangeUtils.getNode(node, offset);
              if (isContentEditableFalse(node)) {
                return node;
              }
            }

            if (CaretContainer.isCaretContainer(node)) {
              if (NodeType.isText(node) && CaretContainer.isCaretContainerBlock(node)) {
                node = node.parentNode;
              }

              sibling = node.previousSibling;
              if (isContentEditableFalse(sibling)) {
                return sibling;
              }

              sibling = node.nextSibling;
              if (isContentEditableFalse(sibling)) {
                return sibling;
              }
            }
          }

          return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);
        }

        if (type == 2) {
          element = selection.getNode();
          name = element ? element.nodeName : null;
          rng = selection.getRng();

          if (isContentEditableFalse(element) || name == 'IMG') {
            return { name: name, index: findIndex(name, element) };
          }

          if (selection.tridentSel) {
            return selection.tridentSel.getBookmark(type);
          }

          element = findAdjacentContentEditableFalseElm(rng);
          if (element) {
            name = element.tagName;
            return { name: name, index: findIndex(name, element) };
          }

          return getLocation(rng);
        }

        if (type == 3) {
          rng = selection.getRng();

          return {
            start: CaretBookmark.create(dom.getRoot(), CaretPosition.fromRangeStart(rng)),
            end: CaretBookmark.create(dom.getRoot(), CaretPosition.fromRangeEnd(rng))
          };
        }

        // Handle simple range
        if (type) {
          return { rng: selection.getRng() };
        }

        rng = selection.getRng();
        id = dom.uniqueId();
        collapsed = selection.isCollapsed();
        styles = 'overflow:hidden;line-height:0px';

        // Explorer method
        if (rng.duplicate || rng.item) {
          // Text selection
          if (!rng.item) {
            rng2 = rng.duplicate();

            try {
              // Insert start marker
              rng.collapse();
              rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');

              // Insert end marker
              if (!collapsed) {
                rng2.collapse(false);

                // Detect the empty space after block elements in IE and move the
                // end back one character <p></p>] becomes <p>]</p>
                rng.moveToElementText(rng2.parentElement());
                if (rng.compareEndPoints('StartToEnd', rng2) === 0) {
                  rng2.move('character', -1);
                }

                rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
              }
            } catch (ex) {
              // IE might throw unspecified error so lets ignore it
              return null;
            }
          } else {
            // Control selection
            element = rng.item(0);
            name = element.nodeName;

            return { name: name, index: findIndex(name, element) };
          }
        } else {
          element = selection.getNode();
          name = element.nodeName;
          if (name == 'IMG') {
            return { name: name, index: findIndex(name, element) };
          }

          // W3C method
          rng2 = normalizeTableCellSelection(rng.cloneRange());

          // Insert end marker
          if (!collapsed) {
            rng2.collapse(false);
            rng2.insertNode(dom.create('span', { 'data-mce-type': "bookmark", id: id + '_end', style: styles }, chr));
          }

          rng = normalizeTableCellSelection(rng);
          rng.collapse(true);
          rng.insertNode(dom.create('span', { 'data-mce-type': "bookmark", id: id + '_start', style: styles }, chr));
        }

        selection.moveToBookmark({ id: id, keep: 1 });

        return { id: id };
      };

      /**
       * Restores the selection to the specified bookmark.
       *
       * @method moveToBookmark
       * @param {Object} bookmark Bookmark to restore selection from.
       * @return {Boolean} true/false if it was successful or not.
       * @example
       * // Stores a bookmark of the current selection
       * var bm = tinymce.activeEditor.selection.getBookmark();
       *
       * tinymce.activeEditor.setContent(tinymce.activeEditor.getContent() + 'Some new content');
       *
       * // Restore the selection bookmark
       * tinymce.activeEditor.selection.moveToBookmark(bm);
       */
      this.moveToBookmark = function (bookmark) {
        var rng, root, startContainer, endContainer, startOffset, endOffset;

        function setEndPoint(start) {
          var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;

          if (point) {
            offset = point[0];

            // Find container node
            for (node = root, i = point.length - 1; i >= 1; i--) {
              children = node.childNodes;

              if (point[i] > children.length - 1) {
                return;
              }

              node = children[point[i]];
            }

            // Move text offset to best suitable location
            if (node.nodeType === 3) {
              offset = Math.min(point[0], node.nodeValue.length);
            }

            // Move element offset to best suitable location
            if (node.nodeType === 1) {
              offset = Math.min(point[0], node.childNodes.length);
            }

            // Set offset within container node
            if (start) {
              rng.setStart(node, offset);
            } else {
              rng.setEnd(node, offset);
            }
          }

          return true;
        }

        function restoreEndPoint(suffix) {
          var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;

          if (marker) {
            node = marker.parentNode;

            if (suffix == 'start') {
              if (!keep) {
                idx = dom.nodeIndex(marker);
              } else {
                node = marker.firstChild;
                idx = 1;
              }

              startContainer = endContainer = node;
              startOffset = endOffset = idx;
            } else {
              if (!keep) {
                idx = dom.nodeIndex(marker);
              } else {
                node = marker.firstChild;
                idx = 1;
              }

              endContainer = node;
              endOffset = idx;
            }

            if (!keep) {
              prev = marker.previousSibling;
              next = marker.nextSibling;

              // Remove all marker text nodes
              Tools.each(Tools.grep(marker.childNodes), function (node) {
                if (node.nodeType == 3) {
                  node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
                }
              });

              // Remove marker but keep children if for example contents where inserted into the marker
              // Also remove duplicated instances of the marker for example by a
              // split operation or by WebKit auto split on paste feature
              while ((marker = dom.get(bookmark.id + '_' + suffix))) {
                dom.remove(marker, 1);
              }

              // If siblings are text nodes then merge them unless it's Opera since it some how removes the node
              // and we are sniffing since adding a lot of detection code for a browser with 3% of the market
              // isn't worth the effort. Sorry, Opera but it's just a fact
              if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !Env.opera) {
                idx = prev.nodeValue.length;
                prev.appendData(next.nodeValue);
                dom.remove(next);

                if (suffix == 'start') {
                  startContainer = endContainer = prev;
                  startOffset = endOffset = idx;
                } else {
                  endContainer = prev;
                  endOffset = idx;
                }
              }
            }
          }
        }

        function addBogus(node) {
          // Adds a bogus BR element for empty block elements
          if (dom.isBlock(node) && !node.innerHTML && !Env.ie) {
            node.innerHTML = '<br data-mce-bogus="1" />';
          }

          return node;
        }

        function resolveCaretPositionBookmark() {
          var rng, pos;

          rng = dom.createRng();
          pos = CaretBookmark.resolve(dom.getRoot(), bookmark.start);
          rng.setStart(pos.container(), pos.offset());

          pos = CaretBookmark.resolve(dom.getRoot(), bookmark.end);
          rng.setEnd(pos.container(), pos.offset());

          return rng;
        }

        if (bookmark) {
          if (Tools.isArray(bookmark.start)) {
            rng = dom.createRng();
            root = dom.getRoot();

            if (selection.tridentSel) {
              return selection.tridentSel.moveToBookmark(bookmark);
            }

            if (setEndPoint(true) && setEndPoint()) {
              selection.setRng(rng);
            }
          } else if (typeof bookmark.start == 'string') {
            selection.setRng(resolveCaretPositionBookmark(bookmark));
          } else if (bookmark.id) {
            // Restore start/end points
            restoreEndPoint('start');
            restoreEndPoint('end');

            if (startContainer) {
              rng = dom.createRng();
              rng.setStart(addBogus(startContainer), startOffset);
              rng.setEnd(addBogus(endContainer), endOffset);
              selection.setRng(rng);
            }
          } else if (bookmark.name) {
            selection.select(dom.select(bookmark.name)[bookmark.index]);
          } else if (bookmark.rng) {
            selection.setRng(bookmark.rng);
          }
        }
      };
    }
1127692
private static void alterHtmlDocs(Options opt, String outputFolder, String packageName, String className,
	    String htmlFileName, Pattern insertPointPattern, RootDoc root) throws IOException {
	// setup files
	File output = new File(outputFolder, packageName.replace(".", "/"));
	File htmlFile = new File(output, htmlFileName);
	File alteredFile = new File(htmlFile.getAbsolutePath() + ".uml");
	if (!htmlFile.exists()) {
	    System.err.println("Expected file not found: " + htmlFile.getAbsolutePath());
	    return;
	}

	// parse & rewrite
	BufferedWriter writer = null;
	BufferedReader reader = null;
	boolean matched = false;
	try {
	    writer = new BufferedWriter(new OutputStreamWriter(new
		    FileOutputStream(alteredFile), opt.outputEncoding));
	    reader = new BufferedReader(new InputStreamReader(new
		    FileInputStream(htmlFile), opt.outputEncoding));

	    String line;
	    while ((line = reader.readLine()) != null) {
		writer.write(line);
		writer.newLine();
		if (!matched && insertPointPattern.matcher(line).matches()) {
		    matched = true;
			
		    String tag;
		    if (opt.autoSize)
		        tag = String.format(UML_AUTO_SIZED_DIV_TAG, className);
		    else
                tag = String.format(UML_DIV_TAG, className);
		    if (opt.collapsibleDiagrams)
		    	tag = String.format(EXPANDABLE_UML, tag, "Show UML class diagram", "Hide UML class diagram");
		    writer.write("<!-- UML diagram added by UMLGraph version " +
		    		Version.VERSION + 
				" (http://www.spinellis.gr/umlgraph/) -->");
		    writer.newLine();
		    writer.write(tag);
		    writer.newLine();
		}
	    }
	} finally {
	    if (writer != null)
		writer.close();
	    if (reader != null)
		reader.close();
	}

	// if altered, delete old file and rename new one to the old file name
	if (matched) {
	    htmlFile.delete();
	    alteredFile.renameTo(htmlFile);
	} else {
	    root.printNotice("Warning, could not find a line that matches the pattern '" + insertPointPattern.pattern() 
		    + "'.\n Class diagram reference not inserted");
	    alteredFile.delete();
	}
    }
169522
function (name, data) {
            switch (name) {
                case 'beforezoom':
                    this.handleBeforeZoom(data);
                    break;
                case 'pageavailable':
                    this.handlePageAvailable(data);
                    break;
                case 'pagefocus':
                    this.handlePageFocus(data);
                    break;
                case 'ready':
                    this.handleReady();
                    break;
                case 'scroll':
                    this.handleScroll();
                    break;
                case 'scrollend':
                    this.handleScrollEnd();
                    break;
                case 'zoom':
                    this.handleZoom(data);
                    break;
                // no default
            }
        }
208805
function parsePagesList(book) {
    var summary = book.getSummary();
    var glossary = book.getGlossary();
    var map = Immutable.OrderedMap();

    // Parse pages from summary
    return timing.measure(
        'parse.listPages',
        walkSummary(summary, function(article) {
            if (!article.isPage()) return;

            var filepath = article.getPath();

            // Is the page ignored?
            if (book.isContentFileIgnored(filepath)) return;

            return parseFilePage(book, filepath)
            .then(function(page) {
                // file doesn't exist
                if (!page) {
                    return;
                }

                map = map.set(filepath, page);
            });
        })
    )

    // Parse glossary
    .then(function() {
        var file = glossary.getFile();

        if (!file.exists()) {
            return;
        }

        return parseFilePage(book, file.getPath())
        .then(function(page) {
            // file doesn't exist
            if (!page) {
                return;
            }

            map = map.set(file.getPath(), page);
        });
    })

    .then(function() {
        return map;
    });
}
583034
function(){
                /*
                 * page:
                 *    PAGE_SYM S* IDENT? pseudo_page? S*
                 *    '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
                 *    ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col,
                    identifier  = null,
                    pseudoPage  = null;

                //look for @page
                tokenStream.mustMatch(Tokens.PAGE_SYM);
                var node = this.startNode('Page', tokenStream.curr().range[0], 'body'); //ORION AST generation
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;

                this._readWhitespace();

                if (tokenStream.match(Tokens.IDENT)){
                    identifier = tokenStream.token().value;
                    //The value 'auto' may not be used as a page name and MUST be treated as a syntax error.
                    if (identifier.toLowerCase() === "auto"){
                        this._unexpectedToken(tokenStream.token());
                    }
                }

                //see if there's a colon upcoming
                if (tokenStream.peek() === Tokens.COLON){
                    pseudoPage = this._pseudo_page();
                }

                this._readWhitespace();

                this.fire({
                    type:   "startpage",
                    id:     identifier,
                    pseudo: pseudoPage,
                    line:   line,
                    col:    col
                });

                this._readDeclarations(true, true);

                this.fire({
                    type:   "endpage",
                    id:     identifier,
                    pseudo: pseudoPage,
                    line:   line,
                    col:    col
                });
                
                if (identifier){
                	node.id = identifier; //ORION AST generation
            	}
                var rbraceRange = this.findLastTokenRange('RBRACE', node.range[0]); // ORION AST Generation select the RBRACE token
            	this.endNode(node, rbraceRange[1]); //ORION AST Generation
            }
846099
function getModifiers(output, page) {
    var book = output.getBook();
    var plugins = output.getPlugins();
    var glossary = book.getGlossary();
    var file = page.getFile();

    // Glossary entries
    var entries = glossary.getEntries();
    var glossaryFile = glossary.getFile();
    var glossaryFilename = fileToOutput(output, glossaryFile.getPath());

    // Current file path
    var currentFilePath = file.getPath();

    // Get TemplateBlock for highlighting
    var blocks = Plugins.listBlocks(plugins);
    var code = blocks.get(CODEBLOCK) || defaultBlocks.get(CODEBLOCK);

    // Current context
    var context = Api.encodeGlobal(output);

    return [
        // Normalize IDs on headings
        Modifiers.addHeadingId,

        // Annotate text with glossary entries
        Modifiers.annotateText.bind(null, entries, glossaryFilename),

        // Resolve images
        Modifiers.resolveImages.bind(null, currentFilePath),

        // Resolve links (.md -> .html)
        Modifiers.resolveLinks.bind(null,
            currentFilePath,
            resolveFileToURL.bind(null, output)
        ),

        // Highlight code blocks using "code" block
        Modifiers.highlightCode.bind(null, function(lang, source) {
            return Promise(code.applyBlock({
                body: source,
                kwargs: {
                    language: lang
                }
            }, context))
            .then(function(result) {
                if (result.html === false) {
                    return { text: result.body };
                } else {
                    return { html: result.body };
                }
            });
        })
    ];
}
1310930
def _hook(self, hook_name, doc_uri=None, **kwargs):
        """"""
        doc = self.workspace.get_document(doc_uri) if doc_uri else None
        hook_handlers = self.config.plugin_manager.subset_hook_caller(hook_name, self.config.disabled_plugins)
        return hook_handlers(config=self.config, workspace=self.workspace, document=doc, **kwargs)
268962
function() {
		var item = mfp.items[mfp.index];

		// Detach and perform modifications
		mfp.contentContainer.detach();

		if(mfp.content)
			mfp.content.detach();

		if(!item.parsed) {
			item = mfp.parseEl( mfp.index );
		}

		var type = item.type;

		_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
		// BeforeChange event works like so:
		// _mfpOn('BeforeChange', function(e, prevType, newType) { });

		mfp.currItem = item;

		if(!mfp.currTemplate[type]) {
			var markup = mfp.st[type] ? mfp.st[type].markup : false;

			// allows to modify markup
			_mfpTrigger('FirstMarkupParse', markup);

			if(markup) {
				mfp.currTemplate[type] = $(markup);
			} else {
				// if there is no markup found we just define that template is parsed
				mfp.currTemplate[type] = true;
			}
		}

		if(_prevContentType && _prevContentType !== item.type) {
			mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
		}

		var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
		mfp.appendContent(newContent, type);

		item.preloaded = true;

		_mfpTrigger(CHANGE_EVENT, item);
		_prevContentType = item.type;

		// Append container back after its content changed
		mfp.container.prepend(mfp.contentContainer);

		_mfpTrigger('AfterChange');
	}
1090248
function(markup) {
		markup = markup || "";
		return gui.Guide.suspend(function() {
			var doc = document.implementation.createHTMLDocument("");
			if (markup.toLowerCase().contains("<!doctype")) {
				try {
					doc.documentElement.innerHTML = markup;
				} catch (ie9exception) {
					doc = new ActiveXObject("htmlfile");
					doc.open();
					doc.write(markup);
					doc.close();
				}
			} else {
				doc.body.innerHTML = markup;
			}
			return doc;
		});
	}
47387
function updateTextArea(editor, checkForChange) {

    var html = $(editor.doc.body).html(),
      options = editor.options,
      updateTextAreaCallback = options.updateTextArea,
      $area = editor.$area;

    // Check for iframe change to avoid unnecessary firing
    // of potentially heavy updateTextArea callbacks.
    if (updateTextAreaCallback) {
      var sum = checksum(html);
      if (checkForChange && editor.frameChecksum == sum)
        return;
      editor.frameChecksum = sum;
    }

    // Convert the iframe html into textarea source code
    var code = updateTextAreaCallback ? updateTextAreaCallback(html) : html;

    // Update the textarea checksum
    if (options.updateFrame)
      editor.areaChecksum = checksum(code);

    // Update the textarea and trigger the change event
    if (code != $area.val()) {
      $area.val(code);
      $(editor).triggerHandler(CHANGE);
    }

  }
956248
def prepare(self):

        self.body_html = markdown(
            codecs.open(self.abspath, 'r').read(),
            extras=['fenced-code-blocks', 'hilite', 'tables', 'metadata'])

        self.header = self.body_html.metadata
        """"""
        if 'tags' in self.header:  # pages can lack tags
            self.header['tags'] = [t.strip().lower() for t in
                                   self.header['tags'].split(',')]

        else:
            self.header['tags'] = ("",)

        self.date = self.header.get('published', datetime.datetime.now())

        if isinstance(self.date, str):
            self.date = datetime.datetime.strptime(self.date, "%Y-%m-%d")

        for k, v in self.header.items():
            try:
                setattr(self, k, v)
            except AttributeError:
                pass

        if self.id:
            return

        rec = {'filename': self.path,
               'mtime': int(os.path.getmtime(self.abspath))}

        if self.header['kind'] == 'writing':
            _id = Entry.db.posts.insert(rec)

        elif self.header['kind'] == 'page':
            _id = Entry.db.pages.insert(rec)

        self.id = _id