<!-- ********************************************************************* -->
<!-- Copyright 2016                                                        -->
<!-- Robert A. Beezer                                                      -->
<!--                                                                       -->
<!-- This file is part of PreTeXt.                                    -->
<!--                                                                       -->
<!-- PreTeXt is free software: you can redistribute it and/or modify  -->
<!-- it under the terms of the GNU General Public License as published by  -->
<!-- the Free Software Foundation, either version 2 or version 3 of the    -->
<!-- License (at your option).                                             -->
<!--                                                                       -->
<!-- PreTeXt is distributed in the hope that it will be useful,       -->
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of        -->
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         -->
<!-- GNU General Public License for more details.                          -->
<!--                                                                       -->
<!-- You should have received a copy of the GNU General Public License     -->
<!-- along with PreTeXt.  If not, see <http://www.gnu.org/licenses/>. -->
<!-- ********************************************************************* -->

<!-- XSLT Cookbook, 2nd Edition                                     -->
<!-- Copyright 2006, O'Reilly Media, Inc.                           -->
<!-- Declaration and entity definition format from Recipe 2.8       -->
<!-- Unicode strings from http://stackoverflow.com/questions/586231 -->
<!ENTITY UPPERCASE "'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'">
<!ENTITY LOWERCASE "'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'">

<!-- Some more of our own design -->
<!ENTITY DIGIT "'0123456789'">
<!ENTITY ALPHABET "'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'">
<!ENTITY SIMPLECHAR "concat(&DIGIT;,&ALPHABET;)">

<!-- for match/select -->
<!ENTITY STRUCTURAL "book|article|slideshow|letter|memo|frontmatter|part|chapter|appendix|index|preface|acknowledgement|biography|foreword|dedication|colophon|section|subsection|subsubsection|slide|exercises|worksheet|handout|reading-questions|solutions|references|glossary|backmatter">

<!ENTITY TRADITIONAL-DIVISION "book|article|part|chapter|section|subsection|subsubsection|appendix">

<!ENTITY SPECIALIZED-DIVISION "exercises|worksheet|handout|reading-questions|references|glossary|solutions">

<!-- A "printout" is a specialized division whose content is laid out  -->
<!-- for printing, with workspace for a reader to write.  A collection -->
<!-- of nothing but printouts is a "workbook".                         -->
<!ENTITY PRINTOUT "worksheet|handout">

<!-- "Division companions" are the non-structural companions of a      -->
<!-- structured traditional division: they may earn their own page    -->
<!-- (and links) when their parent is realized as a summary page in   -->
<!-- a chunked conversion (HTML and derivatives).  The schema only    -->
<!-- allows these four elements, division-flavored, in the parents    -->
<!-- listed.  The filter form presumes context has qualified parents. -->
<!ENTITY DIVISION-COMPANION "introduction[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|conclusion[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|objectives[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]|outcomes[parent::article or parent::chapter or parent::appendix or parent::section or parent::subsection]">

<!-- for filtering nodes, eg *[&STRUCTURAL-FILTER;], *[not(&STRUCTURAL-FILTER;)] -->
<!ENTITY STRUCTURAL-FILTER "self::book or self::article or self::slideshow or self::letter or self::memo or self::frontmatter or self::part or self::chapter or self::appendix or self::index or self::preface or self::acknowledgement or self::biography or self::foreword or self::dedication or self::colophon or self::section or self::subsection or self::subsubsection or self::slide or self::exercises or self::worksheet or self::handout or self::reading-questions or self::solutions or self::references or self::glossary or self::backmatter">

<!ENTITY TRADITIONAL-DIVISION-FILTER "self::book or self::article or self::part or self::chapter or self::section or self::subsection or self::subsubsection or self::appendix">

<!ENTITY SPECIALIZED-DIVISION-FILTER "self::exercises or self::worksheet or self::handout or self::reading-questions or self::references or self::glossary or self::solutions">

<!ENTITY PRINTOUT-FILTER "self::worksheet or self::handout">

<!ENTITY DIVISION-COMPANION-FILTER "self::introduction or self::conclusion or self::objectives or self::outcomes">

<!-- NB: (2019-06-12)  Only the two metadata "filters" seem to          -->
<!-- be in use, so only those are being maintained.  grep'ing on        -->
<!-- METADATA v. METADATA-FILTER, and applying "wc" makes this evident. -->
<!-- (Include this comment in count!)                                   -->

<!-- typical items in blocks that get special treatment -->
<!ENTITY METADATA "title|subtitle|caption|idx|index">
<!ENTITY METADATA-FILTER "self::title or self::subtitle or self::caption or self::idx or self::index[not(index-list)]">

<!-- Subdivisions and runs of paragraphs (like in a proof)  -->
<!-- contain "invisible" items that get killed  and then    -->
<!-- used/accessed other ways.  To see if something  is     -->
<!--first, last, preceded, or followed by other significant -->
<!-- items requires filtering out these items in forming a  -->
<!-- node-set (so as to not be confused by their presence)  -->
<!-- A super-lightweight "article" might have "frontmatter" -->
<!-- and "backmatter" as peers of content elements, and in  -->
<!-- other cases it should not be a problem                 -->
<!-- Typical use:  *[not(&SUBDIVISION-METADATA-FILTER;)]    -->
<!ENTITY SUBDIVISION-METADATA "title|subtitle|index|notation|todo|frontmatter|backmatter">
<!ENTITY SUBDIVISION-METADATA-FILTER "self::title or self::subtitle or self::idx or self::index[not(index-list)] or self::notation or self::todo or self::frontmatter or self::backmatter">

<!-- To implement a new category of blocks, search on    -->
<!-- "PROJECT-" (case-sensitive) since we will mark      -->
<!-- non-obvious locations with the string PROJECT-LIKE  -->
<!-- as we immplement this on 2016-07-17, other entities -->
<!-- below will also match this short form               -->

<!-- definition, just a plain statement, but logically distinct -->
<!ENTITY DEFINITION-LIKE "definition">
<!ENTITY DEFINITION-FILTER "self::definition">

<!-- statement + proof -->
<!ENTITY THEOREM-LIKE "theorem|corollary|lemma|algorithm|proposition|claim|fact|identity">
<!ENTITY THEOREM-FILTER "self::theorem or self::corollary or self::lemma or self::algorithm or self::proposition or self::claim or self::fact or self::identity">

<!-- varieties of proofs -->
<!ENTITY PROOF-LIKE "proof|argument|justification|reasoning|explanation">
<!ENTITY PROOF-FILTER "self::proof or self::argument or self::justification or self::reasoning or self::explanation">

<!-- three types of PROOF-LIKE -->
<!-- in THEOREM-LIKE, detached/standalone, in solutions                                  -->
<!-- INNER-PROOF-FILTER only used where heading levels are controlled                    -->
<!-- SOLUTION-PROOF-FILTER used extensively to control LaTeX environments/macros/styling -->
<!-- standalone/detached is just everything else (in division, or paragraphs, or...)     -->
<!ENTITY INNER-PROOF-FILTER "(&PROOF-FILTER;) and (parent::theorem or parent::corollary or parent::lemma or parent::algorithm or parent::proposition or parent::claim or parent::fact or parent::identity)">
<!ENTITY SOLUTION-PROOF-FILTER "(&PROOF-FILTER;) and (ancestor::hint or ancestor::answer or ancestor::solution)">

<!-- a mathematical statement, but never with a proof -->
<!ENTITY AXIOM-LIKE "axiom|conjecture|principle|heuristic|hypothesis|assumption">
<!ENTITY AXIOM-FILTER "self::axiom or self::conjecture or self::principle or self::heuristic or self::hypothesis or self::assumption">

<!-- narrative, set off for structure, reference -->
<!ENTITY REMARK-LIKE "remark|convention|note|observation|warning|insight">
<!ENTITY REMARK-FILTER "self::remark or self::convention or self::note or self::observation or self::warning or self::insight">

<!-- about computations or technology -->
<!ENTITY COMPUTATION-LIKE "computation|technology|data">
<!ENTITY COMPUTATION-FILTER "self::computation or self::technology or self::data">

<!-- incidental, skippable, lightweight -->
<!ENTITY ASIDE-LIKE "aside|biographical|historical">
<!ENTITY ASIDE-FILTER "self::aside or self::biographical or self::historical">

<!-- blocks, or statement + solution -->
<!ENTITY EXAMPLE-LIKE "example|question|problem">
<!ENTITY EXAMPLE-FILTER "self::example or self::question or self::problem">

<!-- blocks, or statement + solution -->
<!-- save off lab, laboratory, experiment for science -->
<!-- NB: update comprehensive list in the Guide with any additions -->
<!ENTITY PROJECT-LIKE "project|activity|exploration|investigation">
<!ENTITY PROJECT-FILTER "self::project or self::activity or self::exploration or self::investigation">

<!-- blocks with meta-information in lists -->
<!-- TODO: add in "standards", "goals"     -->
<!-- NB: update comprehensive list in the Guide with any additions -->
<!ENTITY GOAL-LIKE "objectives|outcomes">
<!ENTITY GOAL-FILTER "self::objectives or self::outcomes">

<!-- Open = research question/problem/conjecture -->
<!ENTITY OPENPROBLEM-LIKE "openproblem|openquestion|openconjecture">
<!ENTITY OPENPROBLEM-FILTER "self::openproblem or self::openquestion or self::openconjecture">

<!-- displays with captions -->
<!ENTITY FIGURE-LIKE "figure|table|listing|list">
<!ENTITY FIGURE-FILTER "self::figure or self::table or self::listing or self::list">

<!-- Composite filters for the numbering "serial-stamp" pass.  The      -->
<!-- "fundamental" blocks always share the overall blocks counter; a    -->
<!-- "top" figure-like is a captioned display that earns a number (a    -->
<!-- panel inside a captioned side-by-side earns a letter instead).     -->
<!ENTITY FUNDAMENTAL-BLOCK-FILTER "(&DEFINITION-FILTER;) or (&THEOREM-FILTER;) or (&AXIOM-FILTER;) or (&REMARK-FILTER;) or (&COMPUTATION-FILTER;) or (&EXAMPLE-FILTER;)">
<!ENTITY TOP-FIGURE-FILTER "(&FIGURE-FILTER;) and not(parent::sidebyside/parent::figure or parent::sidebyside/parent::sbsgroup/parent::figure)">

<!-- Panels of a "sidebyside", and content of a "stack" panel.  The   -->
<!-- lists mirror the schema, plus grandfathered items the code still -->
<!-- tolerates: "audio", "video", "interactive" (precluded            -->
<!-- 2026-07-22, may someday be removed).  An "exercise" panel        -->
<!-- (worksheet or handout only) and a "slate" panel (within an       -->
<!-- "interactive" only) are policed by the validation-plus           -->
<!-- stylesheet.                                                      -->
<!ENTITY SBSPANEL "p|pre|ol|ul|dl|program|console|poem|audio|video|interactive|slate|exercise|image|figure|table|listing|list|tabular|stack">
<!ENTITY STACKABLE "tabular|image|p|pre|ol|ul|dl|audio|video|interactive|slate|program|console">

<!-- appendages of examples, exercises, tasks -->
<!ENTITY SOLUTION-LIKE "hint|answer|solution">
<!ENTITY SOLUTION-FILTER "self::hint or self::answer or self::solution">

<!-- appendages of OPENPROBLEM-LIKE -->
<!ENTITY DISCUSSION-LIKE "context|discussion|opinion|status|suggestion">
<!ENTITY DISCUSSION-FILTER "self::context or self::discussion or self::opinion or self::status or self::suggestion">

<!-- Elements the schema gives text-only content: no PreTeXt markup is   -->
<!-- permitted inside them, whether because they are verbatim (code, a   -->
<!-- graphics language, a LaTeX fragment) or because the element is a    -->
<!-- plain string (a "shortdescription", a bibliography field).  Advice  -->
<!-- to replace a stray character with an element cannot be followed in  -->
<!-- these, so the validation-plus stylesheet withholds it there.        -->
<!-- Every name below is text-only in EVERY declaration in the schema.   -->
<!-- Deliberately absent: "author", "editor", "page" and "year", each of -->
<!-- which is text in one context and markup in another.                 -->
<!ENTITY TEXT-ONLY-FILTER "self::DOI or self::ISBN or self::ISSN or self::URL or self::asymptote or self::asymptote-preamble or self::attr or self::blurb or self::c or self::cd or self::cline or self::code or self::document-id or self::dropping-particle or self::edition or self::email or self::family or self::genre or self::genus or self::given or self::holder or self::initialism or self::input or self::issue or self::kbd or self::latex-image or self::latex-image-preamble or self::literal or self::macro-file or self::macros or self::mag or self::mermaid or self::non-dropping-particle or self::number or self::number-of-pages or self::output or self::page-first or self::pages or self::pf or self::pg-code or self::plaintitle or self::postamble or self::pre or self::preamble or self::publisher or self::rename or self::sageplot or self::series or self::shortdescription or self::species or self::static-ordering or self::stdin or self::suffix or self::tag or self::tage or self::volume">

<!-- When context is an inline "exercise", then this condition is      -->
<!-- true. We are positive, so as new locations of "exercise"          -->
<!-- are added, then this need not change                              -->
<!-- Typical use: self::exercise and boolean(&INLINE-EXERCISE-FILTER;) -->
<!ENTITY INLINE-EXERCISE-FILTER "parent::article|parent::paragraphs|parent::chapter|parent::appendix|parent::section|parent::subsection|parent::subsubsection|parent::handout">
