Skip to content

Instantly share code, notes, and snippets.

@philschatz
Last active December 29, 2015 08:38
Show Gist options
  • Save philschatz/7644288 to your computer and use it in GitHub Desktop.
Save philschatz/7644288 to your computer and use it in GitHub Desktop.
Ideas for Parameterizing Content slots
// Take a look at the generated CSS (they are equivalent)
// Uncomment the .preface and .appendix lines to see why the @part is necessary.
#part {
// The Part>content-counter prefixes any labels you want to number depending on
// which part of the book they occur in.
// For example: "Table 4.3" in a chapter and "Table A3" in an appendix
.content-counter(preface; @before; @after) { content: @before @after; }
.content-counter(chapter; @before; @after) { content: @before counter(chapter) '.' @after; }
.content-counter(appendix; @before; @after) { content: @before counter(appendix, upper-alpha) @after; }
}
@Example: 'Example';
@Exercise: 'Exercise';
@Figure: 'Figure';
@Note: 'Note';
// # Slots relating to counting:
// - `.counter-increment` specifies which counter should be incremented for this "element"
// - `.counter-reset` specifies which counter(s) should be reset (ie subfigure counter should be reset for each figure)
// - `.number` specifies the `content: ...` part
// For figures in an appendix : `content: 'Figure ' counter(appendix, upper-alpha) '.' counter(figure)`.
// For figures in a chapter : `content: 'Figure ' counter(chapter) '.' counter(figure)`.
// For subfigures in a chapter: `content: 'Figure ' counter(chapter) '.' counter(figure) counter(subfigure, lower-alpha)`.
// Explanation of variables:
//
// `@part`: Which part of the book this "element" is in
// - default
// - preface
// - chapter
// - appendix
// `@context`: Alternate styling if this "element" occurs in another "element" (ie exercise inside an example)
// - default
// - note
// - example
// - exercise
// - table
// - ...
// # Motivation for using `default`
// ------
// 1. This would eventually go away
// 2. Currently, CSS files do provide less-precise selectors that apply to
// content regardless of which part of the book they are in or what their parent is.
// To keep the CSS identical, distinguishing `default` as separate from `@variable-name` is important.
// Using `@variable-name` means the CSS rules will be duplicated for all the `@part` and `@context` permutations
/* --------- Option 1 ------- */
// "Slots" Code
#content {
#note {
.counter-reset(@context) {}
.counter-increment(default) { counter-increment: note; }
.number(@part; default) { #part>.content-counter(@part; @Note ' '; counter(note)); }
}
#example {
.counter-reset(@context) {}
.counter-increment(default) { counter-increment: example; }
.number(@part; default) { #part>.content-counter(@part; @Exercise ' '; counter(exercise)); }
}
#exercise {
.counter-reset(@context) {}
.counter-increment(@context) {}
.counter-increment(default) { counter-increment: exercise; }
// do not increment Exercises inside an example
.counter-increment(example) { }
.number(@part; @context) {}
.number(@part; default) { #part>.content-counter(@part; @Exercise ' '; counter(exercise)); }
// do not number Exercises inside an example
.number(@part; example) { content: @Exercise }
}
#figure {
.counter-reset(@context) {}
.counter-reset(default) { counter-reset: subfigure; }
// Do not reset the subfigure counter when this is a subfigure
.counter-reset(figure) {}
.counter-increment(@context) {}
.counter-increment(default) { counter-increment: figure; counter-reset: subfigure; }
.counter-increment(figure) { counter-increment: subfigure; }
.number(@part; @context) { #part>.content-counter(@part; @Figure ' '; counter(figure)); }
// For subfigures add a letter representing the figure
.number(@part; figure) { #part>.content-counter(@part; @Figure ' '; counter(figure) counter(subfigure, lower-alpha)); }
}
}
// Skeleton code
.build-part(@part) {
@context: default;
.note {
#content>#note>.counter-reset(@context);
#content>#note>.counter-increment(@context);
#content>#note>.number(@part; @context);
}
.example {
#content>#example>.counter-reset(@context);
#content>#example>.counter-increment(@context);
#content>#example>.number(@part; @context);
}
.exercise {
#content>#exercise>.counter-reset(@context);
#content>#exercise>.counter-increment(@context);
#content>#exercise>.number(@part; @context);
}
.figure {
#content>#figure>.counter-reset(@context);
#content>#figure>.counter-increment(@context);
#content>#figure>.number(@part; @context);
}
// ... More elements removed for brevity
// Style an exercise inside an example
.example {
@context: example;
.exercise {
#content>#exercise>.counter-reset(@context);
#content>#exercise>.counter-increment(@context);
#content>#exercise>.number(@part; @context);
}
// ... More elements removed for brevity
}
// Style a subfigure inside a figure
.figure {
@context: figure;
.figure {
#content>#figure>.counter-reset(@context);
#content>#figure>.counter-increment(@context);
#content>#figure>.number(@part; @context);
}
// ... More elements removed for brevity
}
}
//.preface { .build-part(preface); }
.chapter { .build-part(chapter); }
//.appendix { .build-part(appendix); }
// # Observations
// ----------
// **Note:** in order to style the nesting in the skeleton file
// we have to duplicate and nest the selectors.
// This would have to be done for all possible permutations
/* --------- Option 2 ------- */
// Strategy: instead of enumerating all possible combinations, add a parameter to the mixin
// that contains the `@context` and `@element`.
// Enumerating all the possible combinations is done by the `.x-produce-children`
// which basically "loops" over all the possible element types.
// Adding a new "element" only involves overriding the definition of `.x-produce-children`.
// All the content mixins require an additional 1st argument describing which "element" they apply to.
// "Slots" Code
#content {
// Empty Defaults
.counter-reset(@element; @context) {}
.counter-increment(@element; @context) {}
.number(@element; @part; @context) {}
.note() {
.counter-increment(note; default) { counter-increment: note; }
.number(note; @part; default) { #part>.content-counter(@part; @Note ' '; counter(note)); }
}
.example() {
.counter-increment(example; default) { counter-increment: example; }
.number(example; @part; default) { #part>.content-counter(@part; @Example ' '; counter(example)); }
}
.exercise() {
.counter-increment(exercise; default) { counter-increment: exercise; }
// do not increment Exercises inside an example
.counter-increment(exercise; example) { counter-increment: none; }
.number(exercise; @part; default) { #part>.content-counter(@part; @Exercise ' '; counter(exercise)); }
// do not number Exercises inside an example
.number(exercise; @part; example) { content: @Exercise }
}
.figure() {
.counter-reset(figure; default) { counter-reset: subfigure; }
// Do not reset the subfigure counter when this is a subfigure
.counter-reset(figure; figure) { counter-reset: none; }
.counter-increment(figure; default) { counter-increment: figure; counter-reset: subfigure; }
.counter-increment(figure; figure) { counter-increment: subfigure; }
.number(figure; @part; default) { #part>.content-counter(@part; @Figure ' '; counter(figure)); }
// For subfigures add a letter representing the figure
.number(figure; @part; figure) { #part>.content-counter(@part; @Figure ' '; counter(figure) counter(subfigure, lower-alpha)); }
}
// Unlock the types
.note();
.example();
.exercise();
.figure();
}
// Skeleton code
.build-part(@part) {
.x-produce-children(@element; false; false) {}
.x-produce-children(@element; true; @includeChildren) {
.x-produce-all(example; @element; @includeChildren);
.x-produce-all(exercise; @element; @includeChildren);
.x-produce-all(figure; @element; @includeChildren);
.x-produce-all(note; @element; @includeChildren);
// ... More elements removed for brevity
}
// Customize these for different elements
.x-produce-all(@element; @context; @includeChildren) {
.@{type} {
#content>.counter-reset(@element; @context);
#content>.counter-increment(@element; @context);
#content>.number(@element; @part; @context);
.x-produce-children(@element; @includeChildren; false);
}
}
.x-produce-children(default; true; true);
}
//.preface { .build-part(preface); }
.chapter { .build-part(chapter); }
//.appendix { .build-part(appendix); }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment