New Schema expressions

+1 for the new schema syntax. I believe it expresses everything I need in a much cleaner way.

I am now upgrading from 0.6.1 to 0.7 and have run into a couple problems. Here is the current schema:

export const widgetSchema = new Schema({
    nodes: {
        doc: {type: Doc, content: "(block | question | content)+"},
        blockquote: {type: BlockQuote, content: "block+"},
        ordered_list: {type: OrderedList, content: "list_item+"},
        bullet_list: {type: BulletList, content: "list_item+"},
        list_item: {type: ListItem, content: "block+"},
        horizontal_rule: {type: HorizontalRule},

        // blocks
        paragraph: {type: Paragraph, content: "(inline[_]* | input)+"},
        heading: {type: Heading, content: "inline[_]*"},
        question: {type: Question},
        textbox: {type: TextBox},
        choice: {type: Choice, content: "radiobutton textbox"},
        multiplechoice: {type: MultipleChoice, content: "paragraph+ choice+"},
        scaledisplay: {type: ScaleDisplay},
        scale: {type: Scale, content: "paragraph+ scaledisplay"},
        checkitem: {type: CheckItem, content: "checkbox textbox"},
        checklist: {type: CheckList, content: "paragraph+ checkitem+"},
        shortanswer: {type: ShortAnswer, content: "paragraph+ textfield"},
        essay: {type: Essay, content: "paragraph+ textarea"},
        selection: {type: Selection, content: "paragraph+ select"},
        blockmath: {type: BlockMath},
        website: {type: Website},
        spreadsheet: {type: SpreadSheet},
        graph: {type: Graph},

        // inline
        text: {type: Text},
        image: {type: Image},
        hard_break: {type: HardBreak},
        inlinemath: {type: InlineMath},
        carryforward: {type: CarryForward},

        // form elements
        input: {type: Input},
        checkbox: {type: CheckBox},
        radiobutton: {type: RadioButton},
        select: {type: Select},
        textfield: {type: TextField},
        textarea: {type: TextArea},

        // alignment
        leftalign: {type: LeftAlign},
        centeralign: {type: CenterAlign},
        rightalign: {type: RightAlign}

    groups: {
        block: ["paragraph", "blockquote", "ordered_list", "bullet_list", "heading", "horizontal_rule"],
        content: ["blockmath", "website", "spreadsheet", "graph"],
        question: ["multiplechoice", "checklist", "essay", "shortanswer", "scale", "selection"],
        input: ["checkbox", "radiobutton", "select", "textfield", "textarea"],
        inline: ["text", "image", "hard_break", "inlinemath", "carryforward"]

    marks: {
        em: EmMark,
        strong: StrongMark,
        link: LinkMark,
        code: CodeMark,
        underline: UnderlineMark,
        strikethrough: StrikeThroughMark

I get an error “SyntaxError: Invalid content expression ‘(inline[_]* | input)+’ at 0” for

paragraph: {type: Paragraph, content: "(inline[_]* | input)+"}

What am I missing? I could add input to the inline group but I really don’t want input elements in headings.

Also, I have a couple super classes (Input and Question) which are not visible parts of the document. Do I need to include them in the schema?

You can’t apply the | operator to anything except node or group names. These are not nestable expressions, in other words.

You could define a simple_inline group and then have inline: ["simple_inline", "input"], or just define the paragraph rule as content: "(inline | input)[_]*".

Ok, that makes sense. However, (inline | input)[_]* wouldn’t work because it specifies only one-of inline/input rather than one or more, doesn’t it?

Right, if you need one or more the + operator is what you want. However, for inline content, which I assume includes text, I think zero or more is usually the right thing – you don’t want to force some placeholder node in every empty paragraph.