text: const {Schema} = require("prosemirror-model")
  
  // :: Object
  //
  //   doc:: NodeSpec The top level document node.
  //
  //   paragraph:: NodeSpec A plain paragraph textblock.
  //
  //   blockquote:: NodeSpec A blockquote wrapping one or more blocks.
  //
  //   horizontal_rule:: NodeSpec A horizontal rule.
  //
  //   heading:: NodeSpec A heading textblock, with a `level`
  //   attribute that should hold the number 1 to 6.
  //
  //   code_block:: NodeSpec A code listing. Disallows marks or
  //   non-text inline nodes by default.
  //
  //   text:: NodeSpec The text node.
  //
  //   image:: NodeSpec An inline image node. Supports `src`, `alt`, and
  //   `href` attributes. The latter two default to the empty string.
  //
  //   hard_break:: NodeSpec A hard line break.
  const nodes = {
    doc: {
      content: "block+"
    },
  
    paragraph: {
      content: "inline<_>*",
      group: "block",
      parseDOM: [{tag: "p"}],
      toDOM() { return ["p", 0] }
    },
  
    blockquote: {
      content: "block+",
      group: "block",
      defining: true,
      parseDOM: [{tag: "blockquote"}],
      toDOM() { return ["blockquote", 0] }
    },
  
    horizontal_rule: {
      group: "block",
      parseDOM: [{tag: "hr"}],
      toDOM() { return ["hr"] }
    },
  
    heading: {
      attrs: {level: {default: 1}},
      content: "inline<_>*",
      group: "block",
      defining: true,
      parseDOM: [{tag: "h1", attrs: {level: 1}},
                 {tag: "h2", attrs: {level: 2}},
                 {tag: "h3", attrs: {level: 3}},
                 {tag: "h4", attrs: {level: 4}},
                 {tag: "h5", attrs: {level: 5}},
                 {tag: "h6", attrs: {level: 6}}],
      toDOM(node) { return ["h" + node.attrs.level, 0] }
    },
  
    code_block: {
      content: "text*",
      group: "block",
      code: true,
      defining: true,
      parseDOM: [{tag: "pre", preserveWhitespace: true}],
      toDOM() { return ["pre", ["code", 0]] }
    },
  
    text: {
      group: "inline",
      toDOM(node) { return node.text }
    },
  
    image: {
      inline: true,
      attrs: {
        src: {},
        alt: {default: null},
        title: {default: null}
      },
      group: "inline",
      draggable: true,
      parseDOM: [{tag: "img[src]", getAttrs(dom) {
        return {
          src: dom.getAttribute("src"),
          title: dom.getAttribute("title"),
          alt: dom.getAttribute("alt")
        }
      }}],
      toDOM(node) { return ["img", node.attrs] }
    },
  
    hard_break: {
      inline: true,
      group: "inline",
      selectable: false,
      parseDOM: [{tag: "br"}],
      toDOM() { return ["br"] }
    }
  }
  exports.nodes = nodes
  
  // :: Object
  //
  //  em:: MarkSpec An emphasis mark.
  //
  //  strong:: MarkSpec A strong mark.
  //
  //  link:: MarkSpec A link. Has `href` and `title` attributes.
  //  `title` defaults to the empty string.
  //
  //  code:: MarkSpec Code font mark.
  const marks = {
    em: {
      parseDOM: [{tag: "i"}, {tag: "em"},
                 {style: "font-style", getAttrs: value => value == "italic" && null}],
      toDOM() { return ["em"] }
    },
  
    strong: {
      parseDOM: [{tag: "strong"},
                 // This works around a Google Docs misbehavior where
                 // pasted content will be inexplicably wrapped in `<b>`
                 // tags with a font-weight normal.
                 {tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null},
                 {style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null}],
      toDOM() { return ["strong"] }
    },
  
    link: {
      attrs: {
        href: {},
        title: {default: null}
      },
      parseDOM: [{tag: "a[href]", getAttrs(dom) {
        return {href: dom.getAttribute("href"), title: dom.getAttribute("title")}
      }}],
      toDOM(node) { return ["a", node.attrs] }
    },
  
    code: {
      parseDOM: [{tag: "code"}],
      toDOM() { return ["code"] }
    }
  }
  exports.marks = marks
  
  // :: Schema
  // This schema rougly corresponds to the document schema used by
  // CommonMark, minus the list elements, which are defined in the
  // [schema-list](#schema-list) module.
  //
  // To reuse elements from this schema, extend or read from its
  // [`nodeSpec`](#model.Schema.nodeSpec) and
  // [`markSpec`](#model.Schema.markSpec) properties.
  const schema = new Schema({nodes, marks})
  exports.schema = schema
  