/* Type definitions */ struct position { int x; int y; } enum orientation in {horizontalLeft, horizontalRight, verical}; struct dimension { int width; int height; } /* Feature Model */ root Document { group allof { Sheet, opt SpineCaption } enum type in {normal, booklet, perfectBinding}; enum binding in {top, left, right}; enum stackMethod in {none, offset, mixed}; enum sheetOrder in {normal, reverse}; int numberOfSheets; Document.type in {booklet, perfectBinding} -> Sheet.folding==none; Document.type in {booklet, perfectBinding} -> !Sheet.Tab; Document.type in {booklet, perfectBinding} -> !Media.tab; Document.type in {booklet, perfectBinding} -> !Sheet.Staple; Document.type==booklet -> !Sheet.Hole; Document.type==booklet -> !Media.Hole; Document.type in {booklet, perfectBinding} -> !Media.cyclic; (Sheet.paperPass==sef && Document.binding==top) || (Sheet.paperPass==lef && Document.binding==left) -> !Media.tab; } SpineCaption { enum alignment in {top, middle, bottom}; orientation orient; int margin in [0..*]; int lineCount in [0..*]; bool textColor; bool backgroundColor; ifin: Document.type in {booklet, perfectBinding}; } Sheet { group allof { opt Tab, Page, opt Hole, Media, opt Staple, opt NumberingMethod } int section; enum paperPass in {sef, lef, mixed}; int side in {1,2}; enum folding in {none, z_fold, half_fold, gate_fold, parallel_fold, tri_fold_in, tri_fold_out, simple_gate_fold, multi_half_fold, multi_tri_fold_in, mixed}; //optional folding replaced by "none" Staple.location==left -> Document.binding==left; Staple.location==top -> Document.binding==top; enum faceDirection in {up, down}; enum headerDirection in {up, down}; Sheet.folding !=none -> !Tab; Sheet.folding !=none -> !Media.tab; !(Sheet.folding in {none,z_fold}) -> Page.bindingMargin==-1; Sheet.folding==z_fold -> Document.binding==top; } Sheet.Hole { position pos; dimension dim; enum location in {top, left, right, bottom}; } Staple { position pos; enum location in {none, top, left, right, bottom, center, top_left, top_right, left_top, left_bottom, right_top, right_bottom, bottom_left, bottom_right, mixed}; } Tab { group allof { VerticalAlignment, HorizontalAlignment, opt Text } orientation orient; int groupe; ifin: Media.tab; } HorizontalAlignment { enum pos in {left, right, center}; real margin; (pos==center) -> (margin == -1); } VerticalAlignment { enum pos in {top, bottom, center}; real margin; (pos==center) -> (margin == -1); } Text { int lineCount in [0..*]; bool backSide; bool rotate; //optional attribute bool color; (rotate==true) -> (backSide==true); Text.backSide -> !Media.singleSided; } Page { bool color; enum side in {recto, verso}; real bindingMargin; //Optional attribute enum orient in {portrait, landscape}; int page; position pos; dimension dim; bool cover; enum force in {none, front, back}; //Optional attribute -> none value Page.force in {front, back} -> Sheet.side==2; Page.force==back -> Page.side==verso; Page.force==front -> Page.side==recto; Document.type==perfectBinding && Page.cover -> Page.bindingMargin==-1; //Exclude an optional attribute Document.type==perfectBinding && Page.cover -> !Sheet.Hole; Document.type==perfectBinding && Page.cover -> Sheet.folding==none; Document.type==perfectBinding && Page.cover -> Sheet.side==2; Document.type==perfectBinding && Page.cover -> Page.force==none; Document.type==perfectBinding && Page.cover -> !Sheet.NumberingMethod; } Media { group allof { opt Hole } dimension dim; bool insert; bool tab; real tabIndent; //optional attribute (tab==false) -> (tabIndent==-1); bool cyclic; int cycleLength; (cyclic==false) -> (cycleLength==0); real weight; enum type in {plain, glossy, coated, stationary, transparent, plasticSheet, colorCopy, custom, none}; //optional attribute -> none value enum color in {none, white, red, green, blue, cyan, magenta, yellow,pink, grey, black, purple, orange, buff, goldenrod, clear, ivory, custom}; //optional attribute -> none value bool singleSided; bool prePrinted; real thickness; singleSided -> Sheet.side==1; } Media.Hole { position pos; dimension size; } NumberingMethod { group allof { Side } real horizontalMargin; //Optional attribute real verticalMargin; Side.pos==center -> NumberingMethod.horizontalMargin==-1; bool color; } Side { enum side in {recto, verso}; enum alignment in {top, bottom}; enum pos in {left, center, right}; Side.side==verso -> Sheet.side==2; }