diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..41476a3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +# This action is used to perform a test build of the document that includes +# performing spell checking. + +name: ci + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + ############################################################ + - name: Prepare to build the document. + shell: bash + run: tools/build/prebuild + ############################################################ + - name: Build the document. + shell: bash + run: | + tools/build/build \ + -d ${{runner.temp}}/output \ + -z ${{github.ref}} \ + -s + ############################################################ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..3db1cda --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,79 @@ +# This is an action that builds the document and deploys the build document +# to its associated GitHub pages site. + +name: release + +on: + push: + tags: + - 'v*.*.*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + ############################################################ + - name: Prepare to build the document. + shell: bash + run: tools/build/prebuild + ############################################################ + # The following builds the document in multiple formats for deployment. + - name: Build the document. + shell: bash + run: | + tools/build/build \ + -d ${{runner.temp}}/output \ + -z ${{github.ref}} + ############################################################ + # The following deploys to a different branch of the same repository + # using an access token for authentication. + # Note: It is recommended that this approach not be used. + #- name: Deploy the built document to a GitHub Pages branch. + # env: + # DEPLOY_TOKEN: ${{secrets.DEPLOY_TOKEN}} + # shell: bash + # run: | + # tools/build/deploy \ + # -f \ + # -m token \ + # -t ${{runner.temp}}/deploy_tmp \ + # -i ${{runner.temp}}/output \ + # -r mdadams/SG20 \ + # -b gh-pages \ + # -z ${{github.ref}} + ############################################################ + # The following deploys to a different branch of the same repository + # using a deploy (i.e., SSH) key for authentication. + - name: Deploy the built document to a GitHub Pages branch. + env: + DEPLOY_KEY: ${{secrets.DEPLOY_KEY}} + shell: bash + run: | + tools/build/deploy \ + -f \ + -m key \ + -t ${{runner.temp}}/deploy_tmp \ + -i ${{runner.temp}}/output \ + -r mdadams/SG20 \ + -b gh-pages \ + -z ${{github.ref}} + ############################################################ + # The following deploys to a branch of a different repository + # using a deploy (i.e., SSH) key authentication. + - name: Deploy the built document to a GitHub Pages branch. + env: + DEPLOY_KEY: ${{secrets.ALT_DEPLOY_KEY}} + shell: bash + run: | + tools/build/deploy \ + -f \ + -m key \ + -t ${{runner.temp}}/deploy_tmp_2 \ + -i ${{runner.temp}}/output \ + -r mdadams/sg20_guidelines_for_teaching_cpp \ + -b gh-pages \ + -z ${{github.ref}} + ############################################################ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..2427faf --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,41 @@ +Copyright (c) Standard C++ Foundation and its contributors + +Standard C++ Foundation grants you a worldwide, nonexclusive, royalty-free, +perpetual license to copy, use, modify, and create derivative works from this +project for your personal or internal business use only. The above copyright +notice and this permission notice shall be included in all copies or +substantial portions of the project. This license does not grant permission +to use the trade names, trademarks, service marks, or product names of the +licensor, except as required for reasonable and customary use in describing +the origin of the project. + +Standard C++ Foundation reserves the right to accept contributions to the +project at its discretion. + +By contributing material to this project, you grant Standard C++ Foundation, +and those who receive the material directly or indirectly from Standard C++ +Foundation, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable, +transferrable license to reproduce, prepare derivative works of, publicly +display, publicly perform, and distribute your contributed material and such +derivative works, and to sublicense any or all of the foregoing rights to third +parties for commercial or non-commercial use. You also grant Standard C++ +Foundation, and those who receive the material directly or indirectly from +Standard C++ Foundation, a perpetual, worldwide, non-exclusive, royalty-free, +irrevocable license under your patent claims that directly read on your +contributed material to make, have made, use, offer to sell, sell and import +or otherwise dispose of the material. You warrant that your material is your +original work, or that you have the right to grant the above licenses. + +THE PROJECT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE PROJECT OR THE USE OR OTHER DEALINGS IN THE +PROJECT. + +If you believe that anything in the project infringes your copyright, please +contact us at admin@isocpp.org with your contact information and a detailed +description of your intellectual property, including a specific URL where you +believe your intellectual property is being infringed. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ee6116 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +SUBDIRS = \ + sources \ + +.PHONY: all world clean install +all world clean install: + for subdir in $(SUBDIRS); do \ + ( cd $$subdir && make -$(MAKEFLAGS) $@ ) || exit 1; \ + done diff --git a/README.md b/README.md new file mode 100644 index 0000000..e8799f5 --- /dev/null +++ b/README.md @@ -0,0 +1,112 @@ +Guidelines for Teaching C++ +=========================== + +This repository contains the source for the document: + + - Guidelines for Teaching C++ + +When the repository is tagged, this document is automatically built +and made available via GitHub Pages at: + + - (soon) + - + (currently) + - (currently) + +# Prerequisites for Building the Document + +The following software is needed to build the document: + + - pandoc + - aspell + - various basic POSIX utilities, including (amongst others): + - make + - awk + - sed + +If one would like to build the document in PDF format, the +following software is also required: + + - LaTex + +# Building the Document + +To build the document, simply type: + + 1. make clean + 2. make all + 3. make install + +(Strictly speaking, step 2 can be skipped, since the install target +has a dependency on the all target.) + +The above commands will build the document in several formats: + + - HTML format as a single HTML document: + install/html/index.html + - EPUB format: + guidelines.epub + - HTML format split across multiple HTML documents: + install/html_split/index.html + +A make target called world is also defined. Building this target (i.e., +"make world") will generate the document in additional formats, including +PDF format, but requires that LaTeX be installed. + +The build process performs spell checking. +The build will fail if any spelling errors are detected. + +# Spell Checking + +Words that are flagged as having spelling errors can be classified +into two categories: + + 1. valid English words (such as technical terms) that are not in + the spell checker's dictionary + 2. words that are not really "proper" English words but are also not + really errors either (e.g., people's names) + +Words in category 1 should be added to the file +config/spellcheck/wordlist. +Words in category 2 should be added to the file +config/spellcheck/ignored_words.txt + +# Repository Organization + +The files in this repository are organized into directories as follows: + +- config: + This directory contains configuration files that control various + aspects of how the guidelines document is built. + - pandoc_templates: + This directory contains document templates used by pandoc during + the document build process. + - spellcheck: + The directory contains lists of additional words and ignorable errors + for spell checking. +- sources: + This directory hierarchy contains the source files for the document. + - css: + This directory contains CSS files used by the document when built + in HTML format. + - images: + This directory contains images used in the document. + - modules: + The directory hierarchy contains the information for individual modules + and topics. There is one directory per module and one file per topic. +- tools: + The directory hierarchy contains various scripts and other tools used for + building and deploying the document to GitHub pages site. + - build: + This directory contains scripts used for building and deploying the + document. + - old: + This directory hierachy needs to be reorganized. This directory + should probably be renamed and its contents possibly reorganized + or relocated elsewhere. + - tools + - tests + - TEST_INPUTS + - pandoc_filters: + This directory contains various filters needed for pandoc. These + filters do things such as allow markdown-aware spell checking. diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..58e34e9 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,7 @@ +Some topics listed on GitHub are unclear as to their meaning. +e.g. Heterogeneous Compiling +[Is "Heterogeneous Computing" intended or "Cross Compiling"?] +There are others too. + +More thought is needed on naming conventions for labels for +knowledge areas/units. diff --git a/config/pandoc_templates/bootstrap_menu.html b/config/pandoc_templates/bootstrap_menu.html new file mode 100644 index 0000000..ff41b51 --- /dev/null +++ b/config/pandoc_templates/bootstrap_menu.html @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ + +$if(quotes)$ + +$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + + + + $if(title)$ + + $endif$ +
+
+ $if(toc)$ +
+
+ + $toc$ + +
+
+ $endif$ +
+ $for(include-before)$ + $include-before$ + $endfor$ + $body$ + $for(include-after)$ + $include-after$ + $endfor$ +
+
+
+$if(analytics)$ + + + + diff --git a/config/pandoc_templates/clean_menu.html b/config/pandoc_templates/clean_menu.html new file mode 100644 index 0000000..9848be5 --- /dev/null +++ b/config/pandoc_templates/clean_menu.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ + + +$if(quotes)$ + +$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + + + + $if(title)$ + +
+ $else$ +
+ $endif$ +
+ $if(toc)$ +
+
+ + $toc$ + +
+
+ $endif$ +
+ $for(include-before)$ + $include-before$ + $endfor$ + $body$ + $for(include-after)$ + $include-after$ + $endfor$ +
+
+
+$if(analytics)$ + + + + diff --git a/config/pandoc_templates/easy_template.html b/config/pandoc_templates/easy_template.html new file mode 100644 index 0000000..e0ce071 --- /dev/null +++ b/config/pandoc_templates/easy_template.html @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ + +$if(quotes)$ + +$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + + + + $if(title)$ + + $endif$ +
+
+ $if(toc)$ +
+
+ + $toc$ + +
+
+ $endif$ +
+ $for(include-before)$ + $include-before$ + $endfor$ + $body$ + $for(include-after)$ + $include-after$ + $endfor$ +
+
+
+$if(analytics)$ + + + + diff --git a/config/pandoc_templates/elegant_bootstrap_menu.html b/config/pandoc_templates/elegant_bootstrap_menu.html new file mode 100644 index 0000000..e0ce071 --- /dev/null +++ b/config/pandoc_templates/elegant_bootstrap_menu.html @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ + +$if(quotes)$ + +$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + + + + $if(title)$ + + $endif$ +
+
+ $if(toc)$ +
+
+ + $toc$ + +
+
+ $endif$ +
+ $for(include-before)$ + $include-before$ + $endfor$ + $body$ + $for(include-after)$ + $include-after$ + $endfor$ +
+
+
+$if(analytics)$ + + + + diff --git a/config/pandoc_templates/uikit.html b/config/pandoc_templates/uikit.html new file mode 100644 index 0000000..c1d6bb2 --- /dev/null +++ b/config/pandoc_templates/uikit.html @@ -0,0 +1,122 @@ + + + + + + + $if(title)$$title$$endif$ + + + +$if(template_css)$ + +$else$ + +$endif$ + + + + + + + + + + + + + + $for(author-meta)$ + + $endfor$ + $if(date-meta)$ + + $endif$ + + $if(version-meta)$ + + $endif$ + + $if(title-prefix)$$title-prefix$ - $endif$$pagetitle$ + + $if(quotes)$ + + $endif$ + $if(highlighting-css)$ + + $endif$ + $for(css)$ + + $endfor$ + $if(math)$ + $math$ + $endif$ + $for(header-includes)$ + $header-includes$ + $endfor$ + + + + + +
+ + $if(title)$ +
+ + $if(version)$ +
+ +
+ $endif$ + +
+

$title$

+ $if(date)$ +

$date$

+ $endif$ + + $if(version)$ +

Version $version$

+ $endif$ + + $for(author)$ +

$author$

+ $endfor$ +
+
+ $endif$ + +
+
+
+ +
+
+ +
+$body$ +
+
+$if(analytics)$ + +
+ + diff --git a/config/spellcheck/ignored_words.txt b/config/spellcheck/ignored_words.txt new file mode 100644 index 0000000..1694cd3 --- /dev/null +++ b/config/spellcheck/ignored_words.txt @@ -0,0 +1,27 @@ +args +Bjarne +checkmark +constexpr +cppreference +Engelhart +EPUB +errno +expr +Florian +func +Furst +Hyland +JC +Krathwohl +ness +NRVO +req +RVO +Sattler +SG +Stroustrup +udl +ver +Winkel +Hinnant +Vandevoorde diff --git a/config/spellcheck/wordlist b/config/spellcheck/wordlist new file mode 100644 index 0000000..a36f99f --- /dev/null +++ b/config/spellcheck/wordlist @@ -0,0 +1,17 @@ +personal_ws-1.1 en 14 +destructors +invariants +metaprogramming +namespace +namespaces +preprocessor +redeclarations +toolchains +toolchain +boolean +lawyering +computable +UDL +UDLs +IDEs +SFINAE diff --git a/sources/Makefile b/sources/Makefile new file mode 100644 index 0000000..b3a5121 --- /dev/null +++ b/sources/Makefile @@ -0,0 +1,185 @@ +#TOP_DIR = $(realpath ..) +TOP_DIR = .. + +# Specify the document version. +# This can be overridden when invoked from the automated build process. +DOC_VERSION = X.Y.Z + +# Specify whether a spelling error is an error (as opposed to a warning). +# This can be overridden when invoked from the automated build process. +# Please resist the temptation to set this variable to zero. ;-) +# DOC_SPELLCHECK_MUST_PASS = 0 +DOC_SPELLCHECK_MUST_PASS = 1 + +# This can be overridden when invoked from the automated build process. +INSTALL_DIR = $(TOP_DIR)/install + +# All of the Markdown source files (that are not generated during build). +SOURCES = \ + modules/compile-time-programming/requires-expressions.md \ + modules/functions/defaulted-parameters.md \ + modules/functions/user-defined-literals.md \ + modules/object-model/copy-semantics.md \ + course_examples.md \ + disclaimer.md \ + glossary.md \ + contributing.md \ + introduction.md \ + main.md \ + obtaining_document.md \ + references.md \ + +# The Markdown files that are generated during the build process. +GENERATED_MARKDOWN = \ + knowledge_areas_summary.md \ + main.gen.md \ + contributors.md \ + +################################################################################ +# Define primary targets. +################################################################################ + +# The all target builds the document in a minimal set of formats and +# performs a spell check. +.PHONY: all +all: documents spellcheck + +# The world target is similar to the all target except that it builds the +# document in some additional formats. +.PHONY: world +world: all documents_extra + +# The documents target builds the document in a minimal set of formats. +.PHONY: documents +documents: guidelines.html guidelines_html guidelines.epub + +# The documents_extra target builds the document in a few extra formats. +.PHONY: world +documents_extra: guidelines.pdf + +# The spellcheck format performs a spell check on the document. +.PHONY: spellcheck +spellcheck: spellcheck_result.txt + +# The clean target removes all files generated during the build process. +.PHONY: clean +clean: + rm -f $(GENERATED_MARKDOWN) + rm -f guidelines.html guidelines.pdf guidelines.epub guidelines.tex + rm -rf guidelines.texi + rm -rf guidelines_html + rm -f spellcheck_result.txt + rm -f spellcheck_expected_sorted.txt + rm -f missfont.log + +# The install target installs the build document (in various formats) +# in the directory $(INSTALL_DIR). +.PHONY: install +install: all + if [ ! -d "$(INSTALL_DIR)" ]; then \ + mkdir -p "$(INSTALL_DIR)" || exit 1; \ + fi + for dir in html html/images; do \ + if [ ! -d "$(INSTALL_DIR)/$$dir" ]; then \ + mkdir -p "$(INSTALL_DIR)/$$dir" || exit 1; \ + fi; \ + done + cp -f images/cpp_logo.png "$(INSTALL_DIR)/html/images" + cp -f guidelines.html "$(INSTALL_DIR)/html/index.html" + cp -r -f guidelines_html "$(INSTALL_DIR)/html_split" + cp -f guidelines.epub "$(INSTALL_DIR)" + if [ -f guidelines.pdf ]; then \ + cp -f guidelines.pdf "$(INSTALL_DIR)"; \ + fi + +################################################################################ +# Some additional configuration. +################################################################################ + +MD_PREPROCESSOR = $(TOP_DIR)/tools/build/preprocessor +MAKE_MARKDOWN = $(TOP_DIR)/tools/build/make_markdown +SPELLCHECK_DIR = $(TOP_DIR)/config/spellcheck + +################################################################################ +# Preprocessing setup. +################################################################################ + +main.gen.md: $(SOURCES) contributors.md main.md + $(MD_PREPROCESSOR) -v $(DOC_VERSION) < main.md > main.gen.md + +knowledge_areas_summary.md: $(SOURCES) knowledge_areas.dat + $(MAKE_MARKDOWN) < knowledge_areas.dat > knowledge_areas_summary.md + +contributors.md: + git log --all --pretty="%an" | sort | uniq > contributors.md + +################################################################################ +# Establish Pandoc settings. +################################################################################ + +PANDOC_OPTIONS += --toc --toc-depth 3 +PANDOC_OPTIONS += --number-sections +PANDOC_OPTIONS += --standalone +PANDOC_OPTIONS += --pdf-engine=xelatex +#PANDOC_OPTIONS += --lua-filter=tools/pandoc_filters/meta_vars.lua +#PANDOC_OPTIONS += --metadata date="`date +%Y-%m-%d`" +PANDOC_OPTIONS += --metadata version=$(DOC_VERSION) + +INPUT_FORMAT = markdown+header_attributes+multiline_tables + +EPUB_CSS_FILE = css/default-pandoc.css + +#HTML_TEMPLATE = templates/bootstrap_menu.html +HTML_TEMPLATE = $(TOP_DIR)/config/pandoc_templates/uikit.html + +################################################################################ +# Rules for generating the document in various formats. +################################################################################ + +guidelines.html: $(GENERATED_MARKDOWN) + pandoc $(PANDOC_OPTIONS) --template $(HTML_TEMPLATE) --from $(INPUT_FORMAT) -o $@ main.gen.md + +guidelines.epub: $(GENERATED_MARKDOWN) + pandoc $(PANDOC_OPTIONS) -c $(EPUB_CSS_FILE) --from $(INPUT_FORMAT) -o $@ main.gen.md + +guidelines.pdf: $(GENERATED_MARKDOWN) + pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md + +guidelines.texi: $(GENERATED_MARKDOWN) + pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md + +guidelines.docbook: $(GENERATED_MARKDOWN) + pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) -o $@ main.gen.md + +guidelines_html: guidelines.texi + makeinfo --no-validate --force --html -o guidelines_html guidelines.texi + +guidelines.tex: + pandoc $(PANDOC_OPTIONS) --from $(INPUT_FORMAT) --to latex -o $@ main.gen.md + +################################################################################ +# Rule for spellchecking. +################################################################################ + +spellcheck_result.txt: guidelines.html + rm -f $@ + rm -f spellcheck_expected_sorted.txt + sort $(SPELLCHECK_DIR)/ignored_words.txt | \ + uniq > spellcheck_expected_sorted.txt + PATH="$(TOP_DIR)/tools/build:$$PATH" pandoc --from $(INPUT_FORMAT) \ + --lua-filter $(TOP_DIR)/tools/pandoc_filters/spellcheck.lua \ + main.gen.md | sort | uniq > $@ + @status=0; \ + diff -q spellcheck_expected_sorted.txt $@ || \ + status=1; \ + if [ $$status -ne 0 ]; then \ + echo "SPELLING ERRORS DETECTED:"; \ + diff -u spellcheck_expected_sorted.txt $@ | \ + grep '^[+-]'; \ + if [ $(DOC_SPELLCHECK_MUST_PASS) -ne 0 ]; then \ + echo "ERROR: spelling errors detected"; \ + exit 1; \ + else \ + echo "WARNING: spelling errors detected"; \ + fi; \ + fi diff --git a/sources/contributing.md b/sources/contributing.md new file mode 100644 index 0000000..9f66514 --- /dev/null +++ b/sources/contributing.md @@ -0,0 +1,38 @@ +# How To Contribute {#contributing} + +Before attempting to contribute any content for consideration for +inclusion in this document, please read the information below and +and the referenced documents as appropriate. + +All contributions to this project must be made in accordance with the +license in section [License](#license). +This teaching-guidelines document only offers guidance on teaching C++ +as it is specified in the current version of the C++ standard. +So, content should be presented relative to the most-recently +ratified version of the standard. +A detailed explanation of how to present the material for a topic is given in: + +- JC van Winkel, Bjarne Stroustrup, and Florian Sattler. + P2193 --- + How to structure a teaching topic. + . + +Any potential contributors should ensure that they read this document. +The following document may also be helpful in providing some general +background on the modular approach to teaching followed herein: + +- Christopher Di Bella. + P1725R0 --- + Modular Topic Design. + . + +In order to prepare content, it is important to understand what learning +outcomes are, and how to prepare good ones. +Some information on learning outcomes can be found in the +[References](#references) section. +The following document offers a concise introduction to learning outcomes: + +- Effective Use of Performance Objectives for Learning and Assessment + (For Use With Fink’s and Bloom’s Taxonomies), + University of New Mexico, School of Medicine, Teaching and Educational Development, + . diff --git a/sources/course_examples.md b/sources/course_examples.md new file mode 100644 index 0000000..2d078cc --- /dev/null +++ b/sources/course_examples.md @@ -0,0 +1,5 @@ +# Examples of Course Curricula + +[**NOTE**: Anyone have any suggestions of items to add here?] +The following are examples of curricula for course on C++: +... diff --git a/sources/css/default-pandoc.css b/sources/css/default-pandoc.css new file mode 100644 index 0000000..9703d63 --- /dev/null +++ b/sources/css/default-pandoc.css @@ -0,0 +1,327 @@ +html { + font-size: 100%; + overflow-y: scroll; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + color: #444; + font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; + font-size: 12px; + line-height: 1.7; + padding: 1em; + margin: auto; +/* + max-width: 42em; +*/ + max-width: 50em; + background: #fefefe; +} + +a { + color: #0645ad; + text-decoration: none; +} + +a:visited { + color: #0b0080; +} + +a:hover { + color: #06e; +} + +a:active { + color: #faa700; +} + +a:focus { + outline: thin dotted; +} + +*::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +*::selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +a::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +a::selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +p { + margin: 1em 0; +} + +img { + max-width: 100%; +} + +h1, h2, h3, h4, h5, h6 { + color: #111; + line-height: 125%; + margin-top: 2em; + font-weight: normal; +} + +h4, h5, h6 { + font-weight: bold; +} + +h1 { + font-size: 2.5em; +} + +h2 { + font-size: 2em; +} + +h3 { + font-size: 1.5em; +} + +h4 { + font-size: 1.2em; +} + +h5 { + font-size: 1em; +} + +h6 { + font-size: 0.9em; +} + +blockquote { + color: #666666; + margin: 0; + padding-left: 3em; + border-left: 0.5em #EEE solid; +} + +hr { + display: block; + height: 2px; + border: 0; + border-top: 1px solid #aaa; + border-bottom: 1px solid #eee; + margin: 1em 0; + padding: 0; +} + +pre, code, kbd, samp { + color: #000; + font-family: monospace, monospace; + _font-family: 'courier new', monospace; + font-size: 0.98em; +} + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +b, strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +ins { + background: #ff9; + color: #000; + text-decoration: none; +} + +mark { + background: #ff0; + color: #000; + font-style: italic; + font-weight: bold; +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +ul, ol { + margin: 1em 0; + padding: 0 0 0 2em; +} + +li p:last-child { + margin-bottom: 0; +} + +ul ul, ol ol { + margin: .3em 0; +} + +dl { + margin-bottom: 1em; +} + +dt { + font-weight: bold; + margin-bottom: .8em; +} + +dd { + margin: 0 0 .8em 2em; +} + +dd:last-child { + margin-bottom: 0; +} + +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; +} + +figure { + display: block; + text-align: center; + margin: 1em 0; +} + +figure img { + border: none; + margin: 0 auto; +} + +figcaption { + font-size: 0.8em; + font-style: italic; + margin: 0 0 .8em; +} + +table { + margin-bottom: 2em; + border-bottom: 1px solid #ddd; + border-right: 1px solid #ddd; + border-spacing: 0; + border-collapse: collapse; +} + +table th { + padding: .2em 1em; + background-color: #eee; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; +} + +table td { + padding: .2em 1em; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; + vertical-align: top; +} + +.author { + font-size: 1.2em; + text-align: center; +} + +@media only screen and (min-width: 480px) { + body { + font-size: 14px; + } +} +@media only screen and (min-width: 768px) { + body { + font-size: 16px; + } +} +@media print { + * { + background: transparent !important; + color: black !important; + filter: none !important; + -ms-filter: none !important; + } + + body { + font-size: 12pt; + max-width: 100%; + } + + a, a:visited { + text-decoration: underline; + } + + hr { + height: 1px; + border: 0; + border-bottom: 1px solid black; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { + content: ""; + } + + pre, blockquote { + border: 1px solid #999; + padding-right: 1em; + page-break-inside: avoid; + } + + tr, img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page :left { + margin: 15mm 20mm 15mm 10mm; +} + + @page :right { + margin: 15mm 10mm 15mm 20mm; +} + + p, h2, h3 { + orphans: 3; + widows: 3; + } + + h2, h3 { + page-break-after: avoid; + } +} diff --git a/sources/css/elegant_bootstrap.css b/sources/css/elegant_bootstrap.css new file mode 100644 index 0000000..d62d6df --- /dev/null +++ b/sources/css/elegant_bootstrap.css @@ -0,0 +1,329 @@ +/* + * I add this to html files generated with pandoc. + */ + +html { + font-size: 100%; + overflow-y: scroll; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + color: #444; + font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; + font-size: 12px; + line-height: 1.8; + background: #fefefe; +} + +a { + color: #0645ad; + text-decoration: none; +} + +a:visited { + color: #0b0080; +} + +a:hover { + color: #06e; +} + +a:active { + color: #faa700; +} + +a:focus { + outline: thin dotted; +} + +*::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +*::selection { + background: rgba(255, 255, 0, 0.3); + color: #000; +} + +a::-moz-selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +a::selection { + background: rgba(255, 255, 0, 0.3); + color: #0645ad; +} + +p { + margin: 1em 0; +} + +img { + max-width: 100%; +} + +h1, h2, h3, h4, h5, h6 { + color: #111; + line-height: 125%; + /* margin-top: 2em; */ + font-weight: normal; +} + +h4, h5, h6 { + font-weight: bold; +} + +h1 { + font-size: 2.5em; +} + +h2 { + font-size: 2em; +} + +h3 { + font-size: 1.5em; +} + +h4 { + font-size: 1.2em; +} + +h5 { + font-size: 1em; +} + +h6 { + font-size: 0.9em; +} + +blockquote { + color: #666666; + margin: 0; + padding-left: 3em; + border-left: 0.5em #EEE solid; +} + +hr { + display: block; + height: 2px; + border: 0; + border-top: 1px solid #aaa; + border-bottom: 1px solid #eee; + margin: 1em 0; + padding: 0; +} + +pre, code, kbd, samp { + color: #000; + font-family: monospace, monospace; + _font-family: 'courier new', monospace; + font-size: 0.98em; +} + +pre { + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; +} + +b, strong { + font-weight: bold; +} + +dfn { + font-style: italic; +} + +ins { + background: #ff9; + color: #000; + text-decoration: none; +} + +mark { + background: #ff0; + color: #000; + font-style: italic; + font-weight: bold; +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +ul, ol { + margin: 1em 0; + padding: 0 0 0 2em; +} + +li { + line-height: inherit; +} + +li p:last-child { + margin-bottom: 0; +} + +ul ul, ol ol { + margin: .3em 0; +} + +dl { + margin-bottom: 1em; +} + +dt { + font-weight: bold; + margin-bottom: .8em; +} + +dd { + margin: 0 0 .8em 2em; +} + +dd:last-child { + margin-bottom: 0; +} + +img { + border: 0; + -ms-interpolation-mode: bicubic; + vertical-align: middle; +} + +figure { + display: block; + text-align: center; + margin: 1em 0; +} + +figure img { + border: none; + margin: 0 auto; +} + +figcaption { + font-size: 0.8em; + font-style: italic; + margin: 0 0 .8em; +} + +table { + margin-bottom: 2em; + border-bottom: 1px solid #ddd; + border-right: 1px solid #ddd; + border-spacing: 0; + border-collapse: collapse; +} + +table th { + padding: .2em 1em; + background-color: #eee; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; +} + +table td { + padding: .2em 1em; + border-top: 1px solid #ddd; + border-left: 1px solid #ddd; + vertical-align: top; +} + +.author { + font-size: 1.2em; + text-align: center; +} + +@media only screen and (min-width: 480px) { + body { + font-size: 14px; + } +} +@media only screen and (min-width: 768px) { + body { + font-size: 16px; + } +} +@media print { + * { + background: transparent !important; + color: black !important; + filter: none !important; + -ms-filter: none !important; + } + + body { + font-size: 12pt; + max-width: 100%; + } + + a, a:visited { + text-decoration: underline; + } + + hr { + height: 1px; + border: 0; + border-bottom: 1px solid black; + } + + a[href]:after { + content: " (" attr(href) ")"; + } + + abbr[title]:after { + content: " (" attr(title) ")"; + } + + .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { + content: ""; + } + + pre, blockquote { + border: 1px solid #999; + padding-right: 1em; + page-break-inside: avoid; + } + + tr, img { + page-break-inside: avoid; + } + + img { + max-width: 100% !important; + } + + @page :left { + margin: 15mm 20mm 15mm 10mm; +} + + @page :right { + margin: 15mm 10mm 15mm 20mm; +} + + p, h2, h3 { + orphans: 3; + widows: 3; + } + + h2, h3 { + page-break-after: avoid; + } +} diff --git a/sources/css/epub.css b/sources/css/epub.css new file mode 100644 index 0000000..d07c53f --- /dev/null +++ b/sources/css/epub.css @@ -0,0 +1,1540 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + learnbyexample.github.io/epub.css at master · learnbyexample/learnbyexample.github.io · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + +
+ + + + + + + + + +
+
+
+ + + + + + + + + + + + + +
+
+ + + + +
+ + + + Permalink + + + +
+ +
+
+ + + master + + + + +
+
+
+ Switch branches/tags + +
+ + + +
+ +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+ +
+ + + + Go to file + + +
+ + +
+
+
+ + + +
+ +
+
+
 
+
+ +
+
 
+ Cannot retrieve contributors at this time +
+
+ + + + + + + + +
+ + +
+
+ + 108 lines (93 sloc) + + 2.15 KB +
+ +
+ +
+ Raw + Blame +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/* This defines styles and classes used in the book */
/* body { margin: 5%; text-align: justify; font-size: medium; }
code { font-family: monospace; }
h1 { text-align: left; }
h2 { text-align: left; }
h3 { text-align: left; } */
h4 { text-align: left; }
h5 { text-align: left; }
h6 { text-align: left; }
h1.title { }
h2.author { }
h3.date { }
nav#toc ol,
nav#landmarks ol { padding: 0; margin-left: 1em; }
nav#toc ol li,
nav#landmarks ol li { list-style-type: none; margin: 0; padding: 0; }
a.footnote-ref { vertical-align: super; }
em, em em em, em em em em em { font-style: italic;}
em em, em em em em { font-style: normal; }
/* code{ white-space: pre-wrap; } */
span.smallcaps{ font-variant: small-caps; }
span.underline{ text-decoration: underline; }
q { quotes: "“" "”" "‘" "’"; }
div.column{ display: inline-block; vertical-align: top; width: 50%; }
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
+
body {
font-family: "DejaVu Serif", serif;
margin: 5% 5% 20% 5%;
text-align: justify;
font-size: 0.75em;
line-height: 1.5;
}
+
h1 {
text-align: left;
font-size: 2em;
}
+
h2 {
text-align: left;
}
+
h3 {
text-align: left;
}
+
h1.title {
text-align: center;
}
+
p.author {
text-align: center;
}
+
code {
font-family: "DejaVu Sans Mono", monospace;
background-color: #ebebeb;
font-size: 100%;
line-height: inherit;
white-space: pre-wrap;
}
+
pre {
font-family: "DejaVu Sans Mono", monospace;
padding: 1em;
overflow: auto;
font-size: 100%;
line-height: inherit;
border-radius: 0.25em;
background-color: #ebebeb;
white-space: pre-wrap;
}
+
table {
border-collapse: collapse;
font-size: 100%;
}
+
th, td {
padding: 0.8em;
}
+
table, th, td {
border: 0.06em solid black;
}
+
a {
text-decoration: none;
}
+
blockquote {
border-style: solid solid solid solid;
border-color: #a41434;
border-width: medium;
border-radius: 0.5em;
padding-left: 1em;
padding-right: 1em;
background-color: #fcecf4;
}
+
@media screen { /* Workaround for iBooks issue; see #6242 */
.sourceCode {
overflow: visible !important;
white-space: pre-wrap !important;
}
}
+ + + +
+ + +
+ + + +
+ + +
+ + +
+
+ + +
+ + + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + diff --git a/sources/css/github-pandoc.css b/sources/css/github-pandoc.css new file mode 100644 index 0000000..0607023 --- /dev/null +++ b/sources/css/github-pandoc.css @@ -0,0 +1,424 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +/** + * Correct `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9. + * Hide the `template` element in IE, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background: transparent; +} + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Correct font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/** + * Improve readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre-wrap; +} + +/** + * Set consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/** + * Correct overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * 1. Correct font family not being inherited in all browsers. + * 2. Correct font size not being inherited in all browsers. + * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 8/9. + * 2. Improve readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +.go-top { +position: fixed; +bottom: 2em; +right: 2em; +text-decoration: none; +background-color: #E0E0E0; +font-size: 12px; +padding: 1em; +display: inline; +} + +/* Github css */ + +html,body{ margin: auto; + padding-right: 1em; + padding-left: 1em; + max-width: 44em; color:black;}*:not('#mkdbuttons'){margin:0;padding:0}body{font:13.34px helvetica,arial,freesans,clean,sans-serif;-webkit-font-smoothing:subpixel-antialiased;line-height:1.4;padding:3px;background:#fff;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}p{margin:1em 0}a{color:#4183c4;text-decoration:none}body{background-color:#fff;padding:30px;margin:15px;font-size:14px;line-height:1.6}body>*:first-child{margin-top:0!important}body>*:last-child{margin-bottom:0!important}@media screen{body{box-shadow:0 0 0 1px #cacaca,0 0 0 4px #eee}}h1,h2,h3,h4,h5,h6{margin:20px 0 10px;padding:0;font-weight:bold;-webkit-font-smoothing:subpixel-antialiased;cursor:text}h1{font-size:28px;color:#000}h2{font-size:24px;border-bottom:1px solid #ccc;color:#000}h3{font-size:18px;color:#333}h4{font-size:16px;color:#333}h5{font-size:14px;color:#333}h6{color:#777;font-size:14px}p,blockquote,table,pre{margin:15px 0}ul{padding-left:30px}ol{padding-left:30px}ol li ul:first-of-type{margin-top:0}hr{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;border:0 none;color:#ccc;height:4px;padding:0}body>h2:first-child{margin-top:0;padding-top:0}body>h1:first-child{margin-top:0;padding-top:0}body>h1:first-child+h2{margin-top:0;padding-top:0}body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child{margin-top:0;padding-top:0}a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6{margin-top:0;padding-top:0}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p,ul li>:first-child,ol li>:first-child{margin-top:0}dl{padding:0}dl dt{font-size:14px;font-weight:bold;font-style:italic;padding:0;margin:15px 0 5px}dl dt:first-child{padding:0}dl dt>:first-child{margin-top:0}dl dt>:last-child{margin-bottom:0}dl dd{margin:0 0 15px;padding:0 15px}dl dd>:first-child{margin-top:0}dl dd>:last-child{margin-bottom:0}blockquote{border-left:4px solid #DDD;padding:0 15px;color:#777}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}table{border-collapse:collapse;border-spacing:0;font-size:100%;font:inherit}table th{font-weight:bold;border:1px solid #ccc;padding:6px 13px}table td{border:1px solid #ccc;padding:6px 13px}table tr{border-top:1px solid #ccc;background-color:#fff}table tr:nth-child(2n){background-color:#f8f8f8}img{max-width:100%}code,tt{margin:0 2px;padding:0 5px;white-space:nowrap;border:1px solid #eaeaea;background-color:#f8f8f8;border-radius:3px;font-family:Consolas,'Liberation Mono',Courier,monospace;font-size:12px;color:#333}pre>code{margin:0;padding:0;white-space:pre;border:0;background:transparent}.highlight pre{background-color:#f8f8f8;border:1px solid #ccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre{background-color:#f8f8f8;border:1px solid #ccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre code,pre tt{background-color:transparent;border:0}.poetry pre{font-family:Georgia,Garamond,serif!important;font-style:italic;font-size:110%!important;line-height:1.6em;display:block;margin-left:1em}.poetry pre code{font-family:Georgia,Garamond,serif!important;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto;white-space:pre-wrap}sup,sub,a.footnote{font-size:1.4ex;height:0;line-height:1;vertical-align:super;position:relative}sub{vertical-align:sub;top:-1px}@media print{body{background:#fff}img,pre,blockquote,table,figure{page-break-inside:avoid}body{background:#fff;border:0}code{background-color:#fff;color:#333!important;padding:0 .2em;border:1px solid #dedede}pre{background:#fff}pre code{background-color:white!important;overflow:visible}}@media screen{body.inverted{color:#eee!important;border-color:#555;box-shadow:none}.inverted body,.inverted hr .inverted p,.inverted td,.inverted li,.inverted h1,.inverted h2,.inverted h3,.inverted h4,.inverted h5,.inverted h6,.inverted th,.inverted .math,.inverted caption,.inverted dd,.inverted dt,.inverted blockquote{color:#eee!important;border-color:#555;box-shadow:none}.inverted td,.inverted th{background:#333}.inverted h2{border-color:#555}.inverted hr{border-color:#777;border-width:1px!important}::selection{background:rgba(157,193,200,0.5)}h1::selection{background-color:rgba(45,156,208,0.3)}h2::selection{background-color:rgba(90,182,224,0.3)}h3::selection,h4::selection,h5::selection,h6::selection,li::selection,ol::selection{background-color:rgba(133,201,232,0.3)}code::selection{background-color:rgba(0,0,0,0.7);color:#eee}code span::selection{background-color:rgba(0,0,0,0.7)!important;color:#eee!important}a::selection{background-color:rgba(255,230,102,0.2)}.inverted a::selection{background-color:rgba(255,230,102,0.6)}td::selection,th::selection,caption::selection{background-color:rgba(180,237,95,0.5)}.inverted{background:#0b2531;background:#252a2a}.inverted body{background:#252a2a}.inverted a{color:#acd1d5}}.highlight .c{color:#998;font-style:italic}.highlight .err{color:#a61717;background-color:#e3d2d2}.highlight .k,.highlight .o{font-weight:bold}.highlight .cm{color:#998;font-style:italic}.highlight .cp{color:#999;font-weight:bold}.highlight .c1{color:#998;font-style:italic}.highlight .cs{color:#999;font-weight:bold;font-style:italic}.highlight .gd{color:#000;background-color:#fdd}.highlight .gd .x{color:#000;background-color:#faa}.highlight .ge{font-style:italic}.highlight .gr{color:#a00}.highlight .gh{color:#999}.highlight .gi{color:#000;background-color:#dfd}.highlight .gi .x{color:#000;background-color:#afa}.highlight .go{color:#888}.highlight .gp{color:#555}.highlight .gs{font-weight:bold}.highlight .gu{color:#800080;font-weight:bold}.highlight .gt{color:#a00}.highlight .kc,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr{font-weight:bold}.highlight .kt{color:#458;font-weight:bold}.highlight .m{color:#099}.highlight .s{color:#d14}.highlight .na{color:#008080}.highlight .nb{color:#0086b3}.highlight .nc{color:#458;font-weight:bold}.highlight .no{color:#008080}.highlight .ni{color:#800080}.highlight .ne,.highlight .nf{color:#900;font-weight:bold}.highlight .nn{color:#555}.highlight .nt{color:#000080}.highlight .nv{color:#008080}.highlight .ow{font-weight:bold}.highlight .w{color:#bbb}.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:#099}.highlight .sb,.highlight .sc,.highlight .sd,.highlight .s2,.highlight .se,.highlight .sh,.highlight .si,.highlight .sx{color:#d14}.highlight .sr{color:#009926}.highlight .s1{color:#d14}.highlight .ss{color:#990073}.highlight .bp{color:#999}.highlight .vc,.highlight .vg,.highlight .vi{color:#008080}.highlight .il{color:#099}.highlight .gc{color:#999;background-color:#eaf2f5}.type-csharp .highlight .k,.type-csharp .highlight .kt{color:#00F}.type-csharp .highlight .nf{color:#000;font-weight:normal}.type-csharp .highlight .nc{color:#2b91af}.type-csharp .highlight .nn{color:#000}.type-csharp .highlight .s,.type-csharp .highlight .sc{color:#a31515} diff --git a/sources/disclaimer.md b/sources/disclaimer.md new file mode 100644 index 0000000..c2be6f6 --- /dev/null +++ b/sources/disclaimer.md @@ -0,0 +1,6 @@ +# Disclaimer + +This document is intended as a proof of concept to solicit feedback +from others. +This document is incomplete. +This document likely has at least a few errors. diff --git a/sources/glossary.md b/sources/glossary.md new file mode 100644 index 0000000..dc2fe30 --- /dev/null +++ b/sources/glossary.md @@ -0,0 +1,6 @@ +# Glossary + +Some possible terms to include in the glossary: + + - learning objective + - learning outcome diff --git a/sources/images/cpp_logo.png b/sources/images/cpp_logo.png new file mode 100644 index 0000000..780e8a3 Binary files /dev/null and b/sources/images/cpp_logo.png differ diff --git a/sources/index.html b/sources/index.html new file mode 100644 index 0000000..604b236 --- /dev/null +++ b/sources/index.html @@ -0,0 +1,6 @@ + + + + +

If you are not redirected in five seconds, click here.

+ diff --git a/sources/introduction.md b/sources/introduction.md new file mode 100644 index 0000000..196ef89 --- /dev/null +++ b/sources/introduction.md @@ -0,0 +1,93 @@ +# Context and Aim of This Guide + +This document is intended to serve as a resource for instructors +to assist in the preparation of courses on C++ in a variety of +settings, including university, college, and industry environments. +The main objectives of this document are as follows: + + - to provide guidelines for content to be covered by courses of various + difficulty levels on C++ (e.g., topics and learning outcomes) + - to note some common misunderstandings and problematic points that may + be encountered when teaching particular topics + - to suggest resources useful for teaching C++ + - to present examples of curriculum for specific courses + +This document does not itself provide a curriculum for a single specific +course, but is rather a set of guidelines that can be used to prepare +curricula for a wide variety of courses that differ in focus and level +of sophistication. +(This said, however, some links to other documents with examples of +curricula for specific courses may be included herein.) +This document only intends to target the teaching of the +most recently ratified version of the C++ standard. +(This said, however, since older versions of this document are also +available, these older versions may be of some use to those who need +guidance in older versions of the standard, at least versions that +do not predate C++20.) + +# Use of This Document + +**[NOTE: This document follows the same license model as the C++ Core +Guidelines. The LICENSE document is taken verbatim from the C++ Core +Guidelines.]** +This document is made available under a MIT-style license. +In simple terms, this license permits copying, use, modification, +and creation of derivative works. +A copy of the license is included in the section [LICENSE](#license). + +# Contributing to This Document + +Contributions to this document are welcome. +If you would like to help with this project as a contributor, +please read the section [How to Contribute](#contributing). + +# Organization of This Document + +The various concepts (i.e., ideas) to potentially be covered +are partitioned into modules. +A module is very broad in scope and consists of numerous topics. +**[Note: Can I suggest that we use the term "area" or "unit" instead of +"module"? I think that these other choices are better and also +avoid any potential confusion over what is meant by "module" +(i.e., C++ term versus plain English term).]** + +For each module, topics related to the module are identified. +Then, for each topic, learning outcomes are specified. +In order to address a wide variety of courses on C++, each topic +is addressed at three proficiency levels. +These proficiency levels allow each topic to be covered at more than +one level of detail. +This allows target audiences with different background and learning +objectives to be accommodated. +The three proficiency levels are as follows: + + - foundational. This level gives the learner the idea that a + facility exists, what benefits it offers, and the basic ways of using it. + **[Note: Isn't this just "novice"/"beginner"?]** + + - main. This level shows mainstream uses and techniques. + For abstraction and organizational mechanisms it also demonstrates how to + build them. + This level should also give the learner a basic (but not detailed) + understanding of how a + facility might be implemented so that the learner can have a first-order + understanding of any costs involved. + **[Note: The term "main" is not very descriptive/helpful. Could I suggest + using "intermediate"?]** + + - advanced. This level gives information suitable for an expert. + For most topics there is an expert level of knowledge that most + programmers rarely need and techniques that require detailed understanding + of language rules or library implementation. + +The remainder of this document is organized as follows. +The various topics are listed grouped by module. +In cases where a topic might be classified into more +than one module, the topic is listed under the module of most direct +relevance. +This is done in order to avoid duplication of content. +(In the case that a topic is equally relevant to multiple modules, +the decision of which to select is made by a proverbial coin toss.) +The order in which modules and topics are presented +is not meant to imply any order of coverage in a course. +The order in which items are listed is essentially arbitrary. diff --git a/sources/knowledge_areas.dat b/sources/knowledge_areas.dat new file mode 100644 index 0000000..f3566a8 --- /dev/null +++ b/sources/knowledge_areas.dat @@ -0,0 +1,75 @@ +CM Compilation Model + ? ? ? ? Translation Units + ? ? ? ? Headers + ? ? ? ? Modules + ? ? ? ? Name Mangling + ? ? ? ? Phases of Translation + ? ? ? ? Separate Compilation + ? ? ? ? Linkage +P Preprocessor + ? ? ? ? Preprocessor Metaprogramming + ? ? ? ? Inclusion + ? ? ? ? Macros +B Basics Types, Objects, Values, Expressions, Statements, and Control-Flow Constructs + ? ? ? ? Constant Objects + ? ? ? ? Declarations and Definitions + ? ? ? ? Selection Constructs (e.g., if, ternary) + ? ? ? ? Looping Constructs (e.g., for, while, etc.) +F Functions + ? ? ? ? Calling Functions + ? ? ? ? Parameter Passing (e.g., Passing By Value and Reference) + func-args y n n Default Arguments + ? ? ? ? Returning Multiple Values + ? ? ? ? Overloading + udl y y n User-Defined Literals +C User-Defined Types (Classes) + ? ? ? ? Special Member Functions + ? ? ? ? Types + ? ? ? ? Conversions + ? ? ? ? Constructors and Destructors + ? ? ? ? Move/Copy Constructors and Assignment Operators + ? ? ? ? Member Functions + ? ? ? ? Sum Types + ? ? ? ? User-Defined Literals + ? ? ? ? Special Member Functions + ? ? ? ? Guidelines for Special Member Functions (e.g., Rule of Five, Rule of Zero) + copy y y n Copy Semantics + ? ? ? ? Moving and Copying + ? ? ? ? Lambdas +I Inheritance and Class Hierarchies + ? ? ? ? Virtual Functions + ? ? ? ? Run-Time Type Information +CT Compile-Time Computation + ? ? ? ? Constant Expressions and Constant Evaluation + static-assert y y n `static_assert` +T Generic Programming (Templates) + ? ? ? ? Concepts + ? ? ? ? SFINAE + ? ? ? ? Template Metaprogramming + ? ? ? ? Function Templates + ? ? ? ? Requires Clauses + req-expr y y n Requires Expressions +EH Error Handling + ? ? ? ? Classes of Errors + ? ? ? ? errno + ? ? ? ? Error Codes + ? ? ? ? Exception Handling +SL Standard Library + ? ? ? ? Input/Output (I/O) + ? ? ? ? Containers, Iterators, and Algorithms +EL External (i.e., Non Standard) Libraries + ? ? ? ? Graphical User Interfaces +BLD Building + ? ? ? ? Software Build Tools + ? ? ? ? Strategies for Handling Build Problems +TD Testing and Debugging + ? ? ? ? Source-Level Debuggers + ? ? ? ? Code Sanitizers + ? ? ? ? Test Frameworks + ? ? ? ? Debugging Strategies +TOOL Tooling + ? ? ? ? Compiler Toolchains + ? ? ? ? IDEs +SD Software Design + ? ? ? ? Design by Contract + diff --git a/sources/main.md b/sources/main.md new file mode 100644 index 0000000..71e462d --- /dev/null +++ b/sources/main.md @@ -0,0 +1,76 @@ +--- +title_logo: images/cpp_logo.png +title: Guidelines for Teaching C++ +author: SG20 (ISO C++ Study Group on Education) +geometry: margin=1in +output: pdf_document +--- + +__INCLUDE__(obtaining_document.md) + +__INCLUDE__(disclaimer.md) + +__INCLUDE__(introduction.md) + +# Summary of Modules and Topics + +In the sections that follow, the various modules and topics +are presented. +There is one section per module. +For each module, a table listing the various topics in that module +is provided. +The ID for a topic is linked to the detailed coverage of that +topic that comes later in the document. +If a topic has any learning outcomes at a given proficiency level, this is +indicated by a checkmark ("✔️"). +If a topic has no learning outcomes +(simply because there +are not any, not because the information is missing), +this is indicated by an em dash ("—"). +In the case that the information for a topic is completely +missing, a question mark ("?") symbol is used. + +[**NOTE**: These topics are taken mostly from the SG20 GitHub repository. +They are not intended to be complete in any sense. +In fact, by gathering together all topics in one place where they are +easily viewed, it is hoped that missing and unbalanced items will be more +obvious.] + +__INCLUDE__(knowledge_areas_summary.md) + +# Detailed Information for Modules and Topics + +[//]: # ( ********** START OF DETAILED TOPIC DOCUMENTS ********** ) + +__INCLUDE__(modules/object-model/copy-semantics.md) + +__INCLUDE__(modules/functions/user-defined-literals.md) + +__INCLUDE__(modules/functions/defaulted-parameters.md) + +__INCLUDE__(modules/compile-time-programming/requires-expressions.md) + +__INCLUDE__(modules/meta-error-handling/static_assert.md) + +[//]: # ( ********** END OF DETAILED TOPIC DOCUMENTS ********** ) + +__INCLUDE__(course_examples.md) + +# License {#license} + +**[NOTE: This license is copied verbatim from the C++ Core Guidelines.]** +``` +__INCLUDE__(../LICENSE.txt) +``` + +# Contributors + +``` +__INCLUDE__(contributors.md) +``` + +__INCLUDE__(contributing.md) + +__INCLUDE__(glossary.md) + +__INCLUDE__(references.md) diff --git a/sources/modules/compile-time-programming/requires-expressions.md b/sources/modules/compile-time-programming/requires-expressions.md index b6599a0..577430a 100644 --- a/sources/modules/compile-time-programming/requires-expressions.md +++ b/sources/modules/compile-time-programming/requires-expressions.md @@ -1,30 +1,22 @@ -# Module name: Requires Expressions - +## Module name: Requires Expressions {#req-expr} _Skeleton descriptions are typeset in italic text,_ _so please don't remove these descriptions when editing the topic._ -## Overview - - - - - - - - - - - - - - - - - - -
LevelObjectives
FoundationalDefine and use requires-expressions to check satisfaction of expressions by given parameters
MainDefine and use requires-expressions to check properties of expressions
Advanced
- -## Motivation +### Overview + +------------------------------------------------------------------------- +Level Objectives +------------------ ------------------------------------------------------ +Foundational Define and use requires-expressions to check + satisfaction of expressions by given parameters + +Main Define and use requires-expressions to check + properties of expressions + +Advanced --- +------------------------------------------------------------------------- + +### Motivation Requires-expressions allow a developer to perform compile-time evaluation on the validity of other expressions. These are fundamental to the ability @@ -36,9 +28,9 @@ Requires-expressions are compile-time predicates which evaluate to true when their specified set of expressions are all valid for a given set of inputs. -## Foundational: Writing requires-expressions +### Foundational: Writing requires-expressions {#req-expr-basic} -### Background/Required Knowledge +#### Background/Required Knowledge A student is able to: @@ -49,7 +41,7 @@ It is helpful if: * The student is aware that attempting to specialize the template with types or values which do not match otherwise unstated assumptions will cause errors within the template. -### Student outcomes +#### Student outcomes A student should be able to: @@ -59,7 +51,7 @@ A student should be able to: 4. Write a nested-requirement to test the constexpr value of an operation, as opposed to just the syntactic validity 5. Use a requires-expression within a concept, requires-clause, or `if constexpr` condition -### Caveats +#### Caveats To require that expressions, which evaluate to a boolean value like `sizeof(t) == 4`, evaluate to `true` a nested-requirement is needed @@ -67,7 +59,7 @@ like `sizeof(t) == 4`, evaluate to `true` a nested-requirement is needed simple-requirement, which is satisfied based purely on syntactic validity, not on the result of the operation. -### Points to cover +#### Points to cover * All requires-expression requirements terminate with a semicolon. * simple-requirements are used to check that an expression is well-formed. @@ -77,9 +69,9 @@ not on the result of the operation. * Checks are performed by the compiler, not at run time. * If covering usage of requires-expression with requires-clause, [[Compile-time programming: requires clause]][3] demonstrate `requires requires` and show how to ever avoid writing it by using a concept. [[Compile-time programming: concepts]][1] -## Main: Advanced requirements +### Main: Advanced requirements {#req-expr-intermediate} -### Background/required knowledge +#### Background/required knowledge * All of the above. * Knowledge of `noexcept` @@ -88,16 +80,16 @@ A student is able to: * Write a concept [[Compile-time programming: concepts]][1] -### Student outcomes +#### Student outcomes A student should be able to: 1. Write compound-requirements which test the `noexcept`ness of an expression. 2. Use a concept as the target of a compound-requirement. -### Caveats +#### Caveats -### Points to cover +#### Points to cover * Compound-requirements allow the optional ability to test whether an expression is marked as `noexcept`, by using a trailing `noexcept` keyword. @@ -114,7 +106,7 @@ static_assert(requires(S s) { { s.bar() } noexcept; } ); // Fails. s.bar() is no * If the return-type-requirement of a compound-requirement is a concept, that concept is given the resulting type as the first parameter, followed by the specified parameters in the compound-requirement. `{ ++x } -> C` would substitute `C` and check that concept C is satisfied for those parameters. -## Advanced +### Advanced {#req-expr-advanced} [1]: ../compile-time-programming/concepts.md [2]: ../compile-time-programming/function-templates.md diff --git a/sources/modules/functions/defaulted-parameters.md b/sources/modules/functions/defaulted-parameters.md index 575e410..1e0ec3b 100644 --- a/sources/modules/functions/defaulted-parameters.md +++ b/sources/modules/functions/defaulted-parameters.md @@ -1,9 +1,8 @@ -# Functions: default argument - +## Functions: default argument {#func-args} _Skeleton descriptions are typeset in italic text,_ _so please don't remove these descriptions when editing the topic._ -## Overview +### Overview Functions in C++ may be overloaded with different numbers and types of parameters. It may be of value to specify default arguments for some number @@ -11,38 +10,30 @@ of parameters, to allow a caller to avoid specifying arguments that rarely change, or to enable expanding the set of parameters while maintaining backward compatibility with existing callers. - - - - - - - - - - - - - - - - - -
LevelObjectives
FoundationalDefine and use functions with default arguments
Main
Advancedrefinement of default arguments through multiple declarations
- -## Motivation +------------------------------------------------------------------------ +Level Objective +----------------- ------------------------------------------------------ +Foundational Define and use functions with default arguments + +Main --- + +Advanced refinement of default arguments through multiple + declarations +------------------------------------------------------------------------ + +### Motivation Default arguments allow the omission of arguments with obvious or common values. Also may be utilized to extend an existing function signature without forcing changes to existing calling code. -## Topic introduction +### Topic introduction Explain how default arguments work and how to define them. -## Foundational: Using and defining functions with default arguments +### Foundational: Using and defining functions with default arguments {#func-args-basic} -### Background/Required Knowledge +#### Background/Required Knowledge A student is able to: @@ -51,7 +42,7 @@ A student is able to: * Define member and non-member functions [[Functions: member functions]][2] * Explain what a default constructor is and does [[C++ object model: constructors]][3] -### Student outcomes +#### Student outcomes A student should be able to: @@ -60,35 +51,34 @@ A student should be able to: 3. Explain when the lifetime of a default argument begins and ends -### Caveats +#### Caveats * When no forward-declaration exists, the definition serves as the declaration * When multiple declarations exist, only one may specify the default for any particular parameter, but multiple declarations may specify the defaults for different parameters. * Additional default values may be specified for other parameters in repeat declarations * Calling an overloaded function with fewer arguments may be ambiguous with regard to an overload with default arguments -### Points to cover +#### Points to cover * Default value may only be specified once for each parameter among all declarations * Default values must start from the rightmost parameter and continue leftward without gaps * Considerations of when to use default arguments vs overload set -## Main: implementing * +### Main: implementing * {#func-args-intermediate} -### Background/required knowledge +#### Background/required knowledge * All of the above. -### Student outcomes +#### Student outcomes A student should be able to: -### Caveats - +#### Caveats -### Points to cover +#### Points to cover -## Advanced +### Advanced {#func-args-advanced} Subsequent redeclarations of the same function may add default argument values, which are then usable by callers. diff --git a/sources/modules/functions/user-defined-literals.md b/sources/modules/functions/user-defined-literals.md index 8a342d8..22d32ed 100644 --- a/sources/modules/functions/user-defined-literals.md +++ b/sources/modules/functions/user-defined-literals.md @@ -1,33 +1,24 @@ -# Functions: user-defined literals +## Functions: user-defined literals {#udl} _Skeleton descriptions are typeset in italic text,_ _so please don't remove these descriptions when editing the topic._ -## Overview +### Overview _Provides a short natural language abstract of the module’s contents._ _Specifies the different levels of teaching._ - - - - - - - - - - - - - - - - - -
LevelObjectives
Foundationalusing and understanding UDLs
Mainimplementing your own UDLs
AdvancedAdvanced use ("{}, {}!"_fmt("Hello", "World"))
- -## Motivation +------------------------------------------------------------------------- +Level Objectives +---------------- -------------------------------------------------------- +Foundational using and understanding UDLs + +Main implementing your own UDLs + +Advanced Advanced use (```"{}, {}!"_fmt("Hello", "World")```) +------------------------------------------------------------------------- + +### Motivation _Why is this important?_ _Why do we want to learn/teach this topic?_ @@ -36,17 +27,17 @@ _Why do we want to learn/teach this topic?_ * `std::string`: `"Hello, world!"s` * `std::chrono`: `3h + 10min + 5s` -## Topic introduction +### Topic introduction _Very brief introduction to the topic._ * Explain the existence of user defined literals. Example: `12min + 17s` is terse, expressive and type safe. -## Foundational: Using UDLs +### Foundational: Using UDLs {#udl-basic} -### Background/Required Knowledge +#### Background/Required Knowledge A student: @@ -60,7 +51,7 @@ A student: * knows that namespaces exist, and namespace `std`. * knows what using-declarations and using-directives are. [[C++ object model: declarations]][2] -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -79,7 +70,7 @@ A student should be able to: \[1]: explain that it's okay to use a using-directive to "activate" UDLs. -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ @@ -89,19 +80,19 @@ implementation-defined, unspecified, or undefined behavior._ * A student "activates" two suffixes with the same signature from different namespaces. -### Points to cover +#### Points to cover _This section lists important details for each point._ -## Main: implementing UDLs +### Main: implementing UDLs {#udl-intermediate} -### Background/Required Knowledge +#### Background/Required Knowledge * All of the above. -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -112,18 +103,18 @@ A student should be able to: 1. write a UDL operator of their own. 2. separate unrelated UDLs into distinct namespaces. -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ No caveats at present. -### Points to cover +#### Points to cover _This section lists important details for each point._ No caveats at present. -## Advanced +### Advanced {#udl-advanced} _These are important topics that are not expected to be covered but provide guidance where one can continue to investigate this topic in more depth._ diff --git a/sources/modules/meta-error-handling/static_assert.md b/sources/modules/meta-error-handling/static_assert.md index dc56cae..b82e12f 100644 --- a/sources/modules/meta-error-handling/static_assert.md +++ b/sources/modules/meta-error-handling/static_assert.md @@ -1,33 +1,25 @@ -# Meta-error handling: `static_assert` +## Meta-error handling: `static_assert` {#static-assert} _Skeleton descriptions are typeset in italic text,_ _so please don't remove these descriptions when editing the topic._ -## Overview +### Overview _Provides a short natural language abstract of the module’s contents._ _Specifies the different levels of teaching._ - - - - - - - - - - - - - - - - - -
LevelObjectives
FoundationalCalling static_assert with a constant expression
MainUsing static_assert to detect contract violations and improve error messages
Advanced
- -## Motivation +---------------------------------------------------------------------------- +Level Objectives +---------------- ----------------------------------------------------------- +Foundational Calling ```static_assert``` with a constant expression + +Main Using ```static_assert``` to detect contract violations + and improve error messages + +Advanced --- +---------------------------------------------------------------------------- + +### Motivation _Why is this important?_ _Why do we want to learn/teach this topic?_ @@ -35,10 +27,10 @@ _Why do we want to learn/teach this topic?_ `static_assert` allows the developer to enforce that conditions which can be checked during compilation will force build errors when violated. Additionally, they are the best mechanism by which a developer can pass -useful information to other developers regarding what violation occured or +useful information to other developers regarding what violation occurred or what must be done, instead. -## Topic introduction +### Topic introduction _Very brief introduction to the topic._ @@ -46,16 +38,16 @@ _Very brief introduction to the topic._ truth of a supplied predicate, issuing an optional user-supplied error message if the predicate is `false`. -## Foundational: Calling `static_assert` with a constant expression +### Foundational: Calling `static_assert` with a constant expression {#static-assert-basic} -### Background/Required Knowledge +#### Background/Required Knowledge A student: * Should be able to explain the difference between code evaluated at compile-time and run-time * Should be able to cite some examples of compile-time known information, such as `sizeof(T)` -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -65,26 +57,26 @@ A student should be able to: 1. Assert the expected size of a structure using `static_assert` -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ -### Points to cover +#### Points to cover _This section lists important details for each point._ * X * In addition to what is wrong, a good error message will inform the user of how to correct it -## Main: Contracts and `static_assert` +### Main: Contracts and `static_assert` {#static-assert-intermediate} -### Background/Required Knowledge +#### Background/Required Knowledge * All of the above. * General understanding of compile-time requirements -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -92,15 +84,15 @@ _Max 5 items._ A student should be able to: -1. Utilize `static_assert` to verify pre-conditions of a meta-function +1. Utilize `static_assert` to verify preconditions of a meta-function 2. Utilize `static_assert` to verify the results of meta-functions for known values -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ -### Points to cover +#### Points to cover _This section lists important details for each point._ @@ -139,7 +131,7 @@ container c; // If Test #1 was omitted, this would succeed c.add(42, NoDefCtor(1.0)); ``` -## Advanced +### Advanced {#static-assert-advanced} _These are important topics that are not expected to be covered but provide guidance where one can continue to investigate this topic in more depth._ diff --git a/sources/modules/object-model/copy-semantics.md b/sources/modules/object-model/copy-semantics.md index f06fda7..9036df2 100644 --- a/sources/modules/object-model/copy-semantics.md +++ b/sources/modules/object-model/copy-semantics.md @@ -1,49 +1,39 @@ -# C++ object model: copy semantics +## C++ object model: copy semantics {#copy} _Skeleton descriptions are typeset in italic text,_ _so please don't remove these descriptions when editing the topic._ -## Overview +### Overview _Provides a short natural language abstract of the module’s contents._ _Specifies the different levels of teaching._ - - - - - - - - - - - - - - - - - -
LevelObjectives
Foundationalunderstanding how and when are copies made
Mainimplementing user-defined copy operations
Advancedspecial cases: copy elision
- -## Motivation +--------------------------------------------------------- +Level Objectives +------------- ------------------------------------------- +Foundational understanding how and when are copies made + +Main implementing user-defined copy operations + +Advanced special cases: copy elision +--------------------------------------------------------- + +### Motivation _Why is this important?_ _Why do we want to learn/teach this topic?_ Copy semantics allows the user to define how objects of a class get replicated and interact on a value level. -## Topic introduction +### Topic introduction _Very brief introduction to the topic._ Explains when and how objects are copied. -## Foundational: How and when are copies made - +### Foundational: How and when are copies made {#copy-basic} -### Background/Required Knowledge +#### Background/Required Knowledge A student is able to: @@ -55,7 +45,7 @@ It helps when a student is able to: * use move semantics [[C++ object model: move semantics]][4] * explain special member functions [[C++ object model: special member functions]][5] -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -70,14 +60,14 @@ A student should be able to: \* In other languages these differences are sometimes referred to as shallow and deep copy. -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ * Compiler-provided copy operations may result in ownership problems (e.g., `char*`). These ownership problems can generally be solved by using types whose copy operations have the appropriate semantics, e.g., `std::string` instead of `char*` to hold string values. -### Points to cover +#### Points to cover _This section lists important details for each point._ @@ -90,10 +80,10 @@ _This section lists important details for each point._ * Strings (copies the value) -## Main: Implementing user-defined copy operations +### Main: Implementing user-defined copy operations {#copy-intermediate} -### Background/Required Knowledge +#### Background/Required Knowledge A student is able to: @@ -104,7 +94,7 @@ It helps when a student is able to: * explain the rule of zero [[C++ object model: rule-of-zero]][7] * explain the rule of five [[C++ object model: rule-of-five]][6] -### Student outcomes +#### Student outcomes _A list of things "a student should be able to" after the curriculum._ _The next word should be an action word and testable in an exam._ @@ -117,7 +107,7 @@ A student should be able to: * implement copy operations for their own types * _Optional_: explain when copying with basic and strong exception guarantees is useful -### Caveats +#### Caveats _This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior._ @@ -125,7 +115,7 @@ implementation-defined, unspecified, or undefined behavior._ * Intricacies when implementing copy operations: * Examples of how _not_ to write copy operations (e.g., C++03 `std::auto_ptr`) -### Points to cover +#### Points to cover _This section lists important details for each point._ @@ -136,7 +126,7 @@ _This section lists important details for each point._ * Rule-of-five * Copy assignment operators can be ref-qualified to avoid assigning into temporary objects. -## Advanced +### Advanced {#copy-advanced} _These are important topics that are not expected to be covered but provide guidance where one can continue to investigate this topic in more depth._ diff --git a/sources/obtaining_document.md b/sources/obtaining_document.md new file mode 100644 index 0000000..b4d2a34 --- /dev/null +++ b/sources/obtaining_document.md @@ -0,0 +1,30 @@ +# Obtaining This Document: The Most Recent Version and Alternate Formats + +The most recent version of this document is available as an online +HTML document at: +. + +The version of the document that you are currently reading is available in the +following formats: + + 1. online (HTML) format as a single large HTML document: + + [later to be ?] + + 2. EPUB format: + + [later to be ?] + + 3. online (HTML) format, split across multiple HTML documents: + + [later to be ?] + **[Note: The support for this format needs more work (in order to beautify + and fix linking issues).]** + +Older versions of this document are also available. +In general version _ver_ is available at +https://mdadams.github.io/sg20_guidelines_for_teaching_cpp/_ver_. +For example, version v0.1.0 (assuming that this version exists) would be +available at +[later to be +?]. diff --git a/sources/references.md b/sources/references.md new file mode 100644 index 0000000..903e2b5 --- /dev/null +++ b/sources/references.md @@ -0,0 +1,46 @@ +# References + +## References on Learning Outcomes + +- D. Kennedy, A. Hyland, and N. Ryan. + Writing and Using Learning Outcomes: A Practical Guide, 2007. + . + +- B. S. Bloom, M. D. Engelhart, E. J. Furst, W. H. Hill, and D. R. Krathwohl. + Taxonomy of educational objectives: The classification of educational goals. + Handbook I: Cognitive domain. New York: David McKay Company, 1956. + +- Bloom's Taxonomy. + . + +- Effective Use of Performance Objectives for Learning and Assessment + (For Use With Fink’s and Bloom’s Taxonomies), + University of New Mexico, School of Medicine, Teaching and Educational Development, + . + +## Working Group Documents Related to C++ Teaching Guidelines + +- Christopher Di Bella, Simon Brand, and Michael Adams. + P1389R0 --- + Standing Document for SG20: Guidelines for Teaching C++ to Beginners. + . + +- Christopher Di Bella. + P1725R0 --- + Modular Topic Design. + . + +- JC van Winkel, Bjarne Stroustrup, and Florian Sattler. + P2193 --- + How to structure a teaching topic. + . + +- JC van Winkel and Christopher Di Bella. + P1231 --- + Proposal for Study Group: C++ Education. + . + +- H. Hinnant, R. Orr, B. Stroustrup, D. Vandevoorde, and M. Wong. + P2000 --- + Direction for ISO C++, Section 5.1. + . diff --git a/tools/build/aspell_frontend b/tools/build/aspell_frontend new file mode 100755 index 0000000..a949b08 --- /dev/null +++ b/tools/build/aspell_frontend @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +# Michael Adams (mdadams@ece.uvic.ca) + +cmd_dir="$(dirname "$0")" || exit 1 + +# Get an absolute pathname. +#cmd_dir=$(realpath "$cmd_dir") || exit 1 + +top_dir="$cmd_dir/../.." +spellcheck_dir="$top_dir/config/spellcheck" +wordlist="wordlist" +if [ ! -f "$spellcheck_dir/$wordlist" ]; then + echo "ERROR" + exit 1 +fi +exec aspell --home-dir="$spellcheck_dir" --personal "$wordlist" "$@" diff --git a/tools/build/build b/tools/build/build new file mode 100755 index 0000000..1c4363b --- /dev/null +++ b/tools/build/build @@ -0,0 +1,101 @@ +#! /usr/bin/env bash + +################################################################################ +# Some helper functions. +################################################################################ + +# Terminate with error. +panic() +{ + echo "ERROR: $@" 1>&2 + exit 1 +} + +# Print usage information. +usage() +{ + echo "bad usage: $@" + cat <<- EOF + build - Build the document. + + Usage + ===== + + $0 -d \$install_dir -z \$github_ref + + Options + ======= + + -d \$install_dir + Set the installation directory for the built release to \$install_dir. + + -z \$github_ref + Set the GitHub ref to $\github_ref. + (This is used to determine the version of the document being released.) + + Examples + ======== + + $0 -d /tmp/sg20_test/install -z refs/tags/v0.0.1 + EOF + exit 2 +} + +################################################################################ +# Perform some basic initialization. +################################################################################ + +cmd_dir=$(dirname "$0") || panic "cannot determine directory name" +source_dir="$cmd_dir/../.." + +################################################################################ +# Parse command line. +################################################################################ + +install_dir= +github_ref= +spellcheck=0 + +while getopts d:z:s opt; do + case $opt in + d) + install_dir="$OPTARG";; + z) + github_ref="$OPTARG";; + s) + spellcheck=1;; + \?) + usage + break;; + esac +done +shift $((OPTIND - 1)) + +if [ -z "$install_dir" ]; then + usage "no output directory specified" +fi +if [ -z "$github_ref" ]; then + usage "no github ref specified" +fi + +################################################################################ +# Build the document. +################################################################################ + +version="$(awk -v FS="/" '{print $3;}' <<< "$github_ref")" || \ + panic "cannot determine document version" + +if [ ! -d "$install_dir" ]; then + mkdir -p "$install_dir" || \ + panic "cannot make installation directory $install_dir" +fi + +(cd "$source_dir" && make clean) || \ + panic "cannot make clean" + +(cd "$source_dir" && \ + make DOC_VERSION="$version" DOC_SPELLCHECK_MUST_PASS="$spellcheck" all) || \ + panic "cannot build document" + +make INSTALL_DIR="$install_dir" install || \ + panic "cannot install release" diff --git a/tools/build/deploy b/tools/build/deploy new file mode 100755 index 0000000..d88de76 --- /dev/null +++ b/tools/build/deploy @@ -0,0 +1,312 @@ +#! /usr/bin/env bash + +################################################################################ +# Some helper functions. +################################################################################ + +# Terminate with error. +panic() +{ + echo "ERROR: $@" 1>&2 + exit 1 +} + +join_by() +{ + local IFS="$1" + shift + echo "$*" +} + + +# Print usage information and exit. +usage() +{ + echo "bad usage: $@" + cat <<- EOF + deploy - deploy new release of document to GitHub Pages repository + + Usage + ===== + + $0 [options] + + Options + ======= + + -b \$branch + Set the deployment branch to \$branch. + -t \$tmp_dir + Set the temporary directory to $\tmp_dir. + -i \$in_dir + Set the input directory to \$in_dir. + This is the directory containing the output of the document build + process. + -r \$repo_name + Set the deployment repository to \$repo_name. + This includes both the user/organization and repository name. + -z \$github_ref + Set the GitHub ref to \$github_ref. + -f + Allow private key file to be overwritten. + -n + Prepare to push to deployment repository but do not actually + push the changes. (This is only for testing purposes.) + + Examples + ======== + + export DEPLOY_KEY=.... # set DEPLOY_KEY to private SSH key + $0 -n -f -r mdadams/sg20 -b gh-pages \\ + -t /tmp/sg20_test/tmp -i /tmp/sg20_test/install -z refs/tags/v1.0.0 + EOF + exit 2 +} + +################################################################################ +# Parse command line. +################################################################################ + +branch="gh-pages" +in_dir= +repo_name= +tmp_dir="${TMPDIR:-/tmp}" +github_ref= +force=0 +prepare_only=0 +verbose=1 +deploy_mode= + +while getopts b:i:r:t:z:fnvqm: opt; do + case $opt in + m) + deploy_mode="$OPTARG";; + v) + verbose=$((verbose + 1));; + q) + verbose=$((verbose - 1));; + b) + branch="$OPTARG";; + t) + tmp_dir="$OPTARG";; + i) + in_dir="$OPTARG";; + r) + repo_name="$OPTARG";; + z) + github_ref="$OPTARG";; + f) + force=1;; + n) + prepare_only=1;; + \?) + usage + break;; + esac +done +shift $((OPTIND - 1)) + +if [ -z "$github_ref" ]; then + usage "no github ref specified" +fi +if [ -z "$tmp_dir" ]; then + usage "no temporary directory specified" +fi +if [ -z "$in_dir" ]; then + usage "no input directory specified" +fi +if [ -z "$repo_name" ]; then + usage "no repository name specified" +fi + +case "$deploy_mode" in +key) + if [ -z "$DEPLOY_KEY" ]; then + usage "DEPLOY_KEY environment variable not set" + fi + ;; +token) + if [ -z "$DEPLOY_TOKEN" ]; then + usage "DEPLOY_TOKEN environment variable not set" + fi + ;; +*) + usage "bad deployment mode specified $deploy_mode" + ;; +esac + +if [ "$verbose" -ge 1 ]; then + echo "temporary directory $tmp_dir" + echo "input directory $in_dir" + echo "repository name $repo_name" + echo "GitHub ref $github_ref" +fi + +################################################################################ +# Perform some basic initialization. +################################################################################ + +if [ "$verbose" -ge 3 ]; then + set -xv +fi + +cmd_dir=$(dirname "$0") || \ + panic "cannot determine directory" +top_dir="$cmd_dir/../.." + +version="$(awk -v FS="/" '{print $3;}' <<< "$github_ref")" || \ + panic "cannot determine document version" +if [ "$verbose" -ge 1 ]; then + echo "version $version" +fi + +tmp_dir="$tmp_dir/deploy" + +git_dir="$tmp_dir/git" +version_dir="$git_dir/$version" +github_host="github.com" +github_user="git" + +################################################################################ +# Setup SSH client configuration if needed. +################################################################################ + +case "$deploy_mode" in + +key) + + ssh_dir="$HOME/.ssh" + private_key_file="$ssh_dir/private_key" + + repo_url="ssh://git@$github_host/$repo_name.git" + + if [ "$force" -eq 0 -a -e "$private_key_file" ]; then + panic "private key file already exists" + fi + + if [ ! -d "$ssh_dir" ]; then + mkdir -p "$ssh_dir" || \ + panic "cannot make directory $ssh_dir" + fi + if [ ! -d "$tmp_dir" ]; then + mkdir -p "$ssh_dir" || \ + panic "cannot make directory $ssh_dir" + fi + + echo "$DEPLOY_KEY" > "$private_key_file" || \ + panic "cannot create private key file" + chmod u+rw,g=,o= "$private_key_file" || \ + panic "cannot set permissions for private key file" + + if [ -z "$SSH_AGENT_PID" ]; then + eval $(ssh-agent) || \ + panic "cannot start ssh-agent" + fi + ssh-add "$private_key_file" || \ + panic "ssh-add failed" + ;; + +token) + + git config --global credential.helper 'cache --timeout=86400' || \ + panic "cannot set credential helper" + cred_info=() + cred_info+=("protocol=https") + cred_info+=("host=$github_host") + cred_info+=("username=$github_user") + cred_info+=("password=$DEPLOY_TOKEN") + cred_string="$(join_by $'\n' "${cred_info[@]}")" || \ + panic "string processing failed" + cred_string="$(git credential fill <<< "$cred_string")" || \ + panic "git credential fill failed" + + git credential approve <<< "$cred_string" || \ + panic "git credential approve failed" + + repo_url="https://$github_user@$github_host/$repo_name.git" + ;; + +*) + + panic "unexpected case" + ;; + +esac + +if [ "$verbose" -ge 1 ]; then + echo "repository URL: $repo_url" +fi + +################################################################################ +# Add new release to GitHub pages repository. +################################################################################ + +git_push_extra_args=() + +# Clone the repository. +git clone "$repo_url" "$git_dir" || \ + panic "cannot clone repository $repo_url" + +# Create an orphaned branch for the web site content if the branch does +# not already exist. +git -C "$git_dir" ls-remote --exit-code --heads "$repo_url" "$branch" \ + > /dev/null +status=$? +if [ "$status" -ne 0 -a "$status" -ne 2 ]; then + panic "git ls-remote failed" +fi +if [ "$status" -eq 2 ]; then + git -C "$git_dir" checkout --orphan "$branch" || \ + panic "cannot create orphan branch $branch" + git_push_extra_args=(-u origin "$branch") +else + git -C "$git_dir" checkout "$branch" || \ + panic "cannot checkout branch $branch" +fi + +# Set the Git user. +git -C "$git_dir" config --local user.name "Michael Adams" || \ + panic "cannot set Git user name" +git -C "$git_dir" config --local user.email "mdadams@ece.uvic.ca" || \ + panic "cannot set Git user email" + +# Add the content for the new release. +if [ -e "$version_dir" ]; then + panic "directory already exist for $version" +fi +mkdir -p "$version_dir" || \ + panic "cannot make directory $version_dir" +(cd "$in_dir" && tar -cf - .) | (cd "$version_dir" && tar -xf -) || \ + panic "tar failed" + +# Update the symlink for the latest release. +target="$git_dir/latest" +if [ -h "$target" -o -e "$target" ]; then + rm -f "$target" || panic "rm failed" +fi +ln -s "$version/html" "$target" || \ + panic "ln failed" + +# Add a top-level index.html file to redirect to the latest release. +target="$git_dir/index.html" +if [ -e "$target" ]; then + rm -f "$target" || panic "cannot remove $target" +fi +cp "$top_dir/sources/index.html" "$target" || panic "cannot copy $target" + +if [ "$verbose" -ge 2 ]; then + ls -al "$git_dir"/* +fi + +# Commit and push all of the changes. +git -C "$git_dir" add . || \ + panic "git add failed" +git -C "$git_dir" commit -m "Deploying release $version" || \ + panic "git commit failed" +if [ "$prepare_only" -eq 0 ]; then + if [ "$verbose" -ge 1 ]; then + echo "Pushing changes." + fi + git -C "$git_dir" push "${git_push_extra_args[@]}" || \ + panic "git push failed" +fi diff --git a/tools/build/make_markdown b/tools/build/make_markdown new file mode 100755 index 0000000..e584380 --- /dev/null +++ b/tools/build/make_markdown @@ -0,0 +1,115 @@ +#! /usr/bin/env bash +# Michael Adams (mdadams@ece.uvic.ca) + +awk ' +function output(level, old_level, label, basic, intermediate, advanced, text) { + #bad_char = "🤢"; + #bad_char = "❌"; + bad_char = "?"; + #check_char = "✓" + check_char = "✔️"; + emdash = "—"; + + if (level == 1) { + if (label == "?") { + label = bad_char; + #basic = emdash; + #intermediate = emdash; + #advanced = emdash; + } else { + if (basic == "y") { + #basic = sprintf("%s", label, check_char); + basic = sprintf("[%s](#%s-basic)", check_char, label); + } else if (basic == "n") { + basic = emdash; + } + if (intermediate == "y") { + #intermediate = sprintf("%s", label, check_char); + intermediate = sprintf("[%s](#%s-intermediate)", check_char, label); + } else if (intermediate == "n") { + intermediate = emdash; + } + if (advanced == "y") { + #advanced = sprintf("%s", label, check_char); + advanced = sprintf("[%s](#%s-advanced)", check_char, label); + } else if (advanced == "n") { + advanced = emdash; + } + } + #label = sprintf("%s", label, label); + label = sprintf("[%s](#%s)", label, label); + } + + if (level == 1 && old_level < 1) { + printf "\n| ID | Unit | Foundational | Main | Advanced |\n"; + printf "|---|----------|---|---|---|\n"; + } + if (level == 1) { + printf "| [%s] | %s | %s | %s | %s |\n", label, text, basic, intermediate, advanced; + } + if ((level == 0 || level == -1) && old_level > 0) { + printf "\n\n"; + #printf "Note: %s indicates no entry yet available\n\n", bad_char; + #printf "Note: The IDs and checkmarks (%s) are linked to the corresponding sections.\n\n", check_char; + } + if (level == 0) { + printf "\n"; + #printf "## [%s] %s {#%s}\n", label, text, label; + printf "## %s {#%s}\n", text, label; + } +} + +BEGIN { + old_level = -1; +} + +(NF > 0) { + line = $0; + level = 0; + while (substr(line, level + 1, 1) == "\t") { + ++level; + } + + label = ""; + basic = ""; + intermediate = ""; + advanced = ""; + text = ""; + + if (level == 0) { + + label = $1; + text = substr($0, index($0, $2)); + output(level, old_level, label, basic, intermediate, advanced, text); + + } else if (level == 1) { + + label = $1; + basic = $2; + intermediate = $3; + advanced = $4; + text = substr($0, index($0, $5)); + + output(level, old_level, label, basic, intermediate, advanced, text); + + } + + old_level = level; + +} + +END { + + level = -1; + + label = ""; + basic = ""; + intermediate = ""; + advanced = ""; + text = ""; + + output(level, old_level, label, basic, intermediate, advanced, text); + +} + +' - diff --git a/tools/build/prebuild b/tools/build/prebuild new file mode 100755 index 0000000..4fccda3 --- /dev/null +++ b/tools/build/prebuild @@ -0,0 +1,19 @@ +#! /usr/bin/env bash + +# Terminate with error. +panic() +{ + echo "ERROR: $@" 1>&2 + exit 1 +} + +# Initialize the list of required packages. +packages=() +packages+=(pandoc) +packages+=(texinfo) +packages+=(aspell) +#packages+=(hunspell) + +# Install the packages. +sudo apt-get install -y "${packages[@]}" || \ + panic "unable to install packages" diff --git a/tools/build/preprocessor b/tools/build/preprocessor new file mode 100755 index 0000000..ee857e3 --- /dev/null +++ b/tools/build/preprocessor @@ -0,0 +1,69 @@ +#! /usr/bin/env bash +# Michael Adams (mdadams@ece.uvic.ca) + +program_dir="$(dirname "$0")" || exit 1 +program_pathname="$0" + +panic() +{ + echo "ERROR: $@" + exit 1 +} + +usage() +{ + echo "bad usage: $@" + exit 2 +} + +level=0 +version= + +while getopts v:l: opt; do + case $opt in + v) + version="$OPTARG";; + l) + level="$OPTARG";; + \?) + usage + break;; + esac +done +shift $((OPTIND - 1)) + +if [ -z "$version" ]; then + usage "no version specified" +fi +if [ "$level" -gt 10 ]; then + panic "recursion too deep" +fi + +awk -v program="$program_pathname" -v level="$level" -v version="$version" ' + /^__INCLUDE__(.*)/ { + i = length("__INCLUDE__("); + start = i + 1; + while (substr($0, i, 1) != ")") { + ++i; + } + end = i; + path = substr($0, start, end - start); + result = system(sprintf("cat %s | %s -l %d -v %s", path, program, level + 1, version)); + if (result) { + printf "error processing %s\n", path > "/dev/stderr"; + exit 1; + } + next; + } + { + print $0; + } +' - | \ + sed -e 's/__VERSION__/'"$version"'/g' + +status=("${PIPESTATUS[@]}") +for i in "${status[@]}"; do + if [ "$i" -ne 0 ]; then + panic "preprocessor failed" + fi +done diff --git a/Readme.md b/tools/old/Readme.md similarity index 100% rename from Readme.md rename to tools/old/Readme.md diff --git a/skeleton.md b/tools/old/skeleton.md similarity index 100% rename from skeleton.md rename to tools/old/skeleton.md diff --git a/tools/pandoc_filters/meta_vars.lua b/tools/pandoc_filters/meta_vars.lua new file mode 100644 index 0000000..0a39558 --- /dev/null +++ b/tools/pandoc_filters/meta_vars.lua @@ -0,0 +1,19 @@ +local vars = {} + +function get_vars (meta) + for k, v in pairs(meta) do + if type(v) == 'table' and v.t == 'MetaInlines' then + vars["%" .. k .. "%"] = {table.unpack(v)} + end + end +end + +function replace (el) + if vars[el.text] then + return pandoc.Span(vars[el.text]) + else + return el + end +end + +return {{Meta = get_vars}, {Str = replace}} diff --git a/tools/pandoc_filters/spellcheck.lua b/tools/pandoc_filters/spellcheck.lua new file mode 100644 index 0000000..dd723cb --- /dev/null +++ b/tools/pandoc_filters/spellcheck.lua @@ -0,0 +1,70 @@ +-- lua filter for spell checking: requires 'aspell'. +-- Copyright (C) 2017-2020 John MacFarlane, released under MIT license + +local text = require('text') +local words = {} +local deflang + +local function add_to_dict(lang, t) + if not words[lang] then + words[lang] = {} + end + if not words[lang][t] then + words[lang][t] = (words[lang][t] or 0) + 1 + end +end + +local function get_deflang(meta) + deflang = (meta.lang and meta.lang[1] and meta.lang[1].c) or 'en' + -- the following is better but won't work in pandoc 2.0.6. + -- it requires pandoc commit ecc46e229fde934f163d1f646383d24bfe2039e1: + -- deflang = (meta.lang and pandoc.utils.stringify(meta.lang)) or 'en' + return {} -- eliminate meta so it doesn't get spellchecked +end + +local function run_spellcheck(lang) + local keys = {} + local wordlist = words[lang] + for k,_ in pairs(wordlist) do + keys[#keys + 1] = k + end + local inp = table.concat(keys, '\n') + local outp = pandoc.pipe('aspell_frontend', {'list','-l',lang}, inp) + for w in string.gmatch(outp, "([%S]+)\n") do + io.write(w) + if lang ~= deflang then + io.write("\t[" .. lang .. "]") + end + io.write("\n") + end +end + +local function results(el) + pandoc.walk_block(pandoc.Div(el.blocks), {Str = function(e) add_to_dict(deflang, e.text) end}) + for lang,v in pairs(words) do + run_spellcheck(lang) + end + os.exit(0) +end + +local function checkstr(el) + add_to_dict(deflang, el.text) +end + +local function checkspan(el) + local lang = el.attributes.lang + if not lang then return nil end + pandoc.walk_inline(el, {Str = function(e) add_to_dict(lang, e.text) end}) + return {} -- remove span, so it doesn't get checked again +end + +local function checkdiv(el) + local lang = el.attributes.lang + if not lang then return nil end + pandoc.walk_block(el, {Str = function(e) add_to_dict(lang, e.text) end}) + return {} -- remove div, so it doesn't get checked again +end + +return {{Meta = get_deflang}, + {Div = checkdiv, Span = checkspan}, + {Str = function(e) add_to_dict(deflang, e.text) end, Pandoc = results}}