merge styles v9.5.2
authorFrançois Michonneau <francois.michonneau@gmail.com>
Tue, 19 Jun 2018 19:08:03 +0000 (15:08 -0400)
committerFrançois Michonneau <francois.michonneau@gmail.com>
Tue, 19 Jun 2018 19:08:03 +0000 (15:08 -0400)
120 files changed:
.gitignore
CODE_OF_CONDUCT.md [new file with mode: 0644]
LICENSE.md
Makefile
_includes/favicons.html [new file with mode: 0644]
_includes/lc/intro.html
_includes/lesson_footer.html
_includes/links.md
_includes/navbar.html
_includes/workshop_footer.html
_layouts/base.html
_layouts/workshop.html
assets/css/bootstrap.css
assets/css/lesson.scss
assets/favicons/cp/apple-touch-icon-114x114.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-120x120.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-144x144.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-152x152.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-57x57.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-60x60.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-72x72.png [new file with mode: 0644]
assets/favicons/cp/apple-touch-icon-76x76.png [new file with mode: 0644]
assets/favicons/cp/favicon-128.png [new file with mode: 0644]
assets/favicons/cp/favicon-16x16.png [new file with mode: 0644]
assets/favicons/cp/favicon-196x196.png [new file with mode: 0644]
assets/favicons/cp/favicon-32x32.png [new file with mode: 0644]
assets/favicons/cp/favicon-96x96.png [new file with mode: 0644]
assets/favicons/cp/favicon.ico [new file with mode: 0644]
assets/favicons/cp/mstile-144x144.png [new file with mode: 0644]
assets/favicons/cp/mstile-150x150.png [new file with mode: 0644]
assets/favicons/cp/mstile-310x150.png [new file with mode: 0644]
assets/favicons/cp/mstile-310x310.png [new file with mode: 0644]
assets/favicons/cp/mstile-70x70.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-114x114.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-120x120.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-144x144.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-152x152.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-57x57.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-60x60.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-72x72.png [new file with mode: 0644]
assets/favicons/dc/apple-touch-icon-76x76.png [new file with mode: 0644]
assets/favicons/dc/favicon-128.png [new file with mode: 0644]
assets/favicons/dc/favicon-16x16.png [new file with mode: 0644]
assets/favicons/dc/favicon-196x196.png [new file with mode: 0644]
assets/favicons/dc/favicon-32x32.png [new file with mode: 0644]
assets/favicons/dc/favicon-96x96.png [new file with mode: 0644]
assets/favicons/dc/favicon.ico [new file with mode: 0644]
assets/favicons/dc/mstile-144x144.png [new file with mode: 0644]
assets/favicons/dc/mstile-150x150.png [new file with mode: 0644]
assets/favicons/dc/mstile-310x150.png [new file with mode: 0644]
assets/favicons/dc/mstile-310x310.png [new file with mode: 0644]
assets/favicons/dc/mstile-70x70.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-114x114.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-120x120.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-144x144.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-152x152.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-57x57.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-60x60.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-72x72.png [new file with mode: 0644]
assets/favicons/lc/apple-touch-icon-76x76.png [new file with mode: 0644]
assets/favicons/lc/favicon-128.png [new file with mode: 0644]
assets/favicons/lc/favicon-16x16.png [new file with mode: 0644]
assets/favicons/lc/favicon-196x196.png [new file with mode: 0644]
assets/favicons/lc/favicon-32x32.png [new file with mode: 0644]
assets/favicons/lc/favicon-96x96.png [new file with mode: 0644]
assets/favicons/lc/favicon.ico [new file with mode: 0644]
assets/favicons/lc/mstile-144x144.png [new file with mode: 0644]
assets/favicons/lc/mstile-150x150.png [new file with mode: 0644]
assets/favicons/lc/mstile-310x150.png [new file with mode: 0644]
assets/favicons/lc/mstile-310x310.png [new file with mode: 0644]
assets/favicons/lc/mstile-70x70.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-114x114.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-120x120.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-144x144.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-152x152.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-57x57.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-60x60.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-72x72.png [new file with mode: 0644]
assets/favicons/swc/apple-touch-icon-76x76.png [new file with mode: 0644]
assets/favicons/swc/favicon-128.png [new file with mode: 0644]
assets/favicons/swc/favicon-16x16.png [new file with mode: 0644]
assets/favicons/swc/favicon-196x196.png [new file with mode: 0644]
assets/favicons/swc/favicon-32x32.png [new file with mode: 0644]
assets/favicons/swc/favicon-96x96.png [new file with mode: 0644]
assets/favicons/swc/favicon.ico [new file with mode: 0644]
assets/favicons/swc/mstile-144x144.png [new file with mode: 0644]
assets/favicons/swc/mstile-150x150.png [new file with mode: 0644]
assets/favicons/swc/mstile-310x150.png [new file with mode: 0644]
assets/favicons/swc/mstile-310x310.png [new file with mode: 0644]
assets/favicons/swc/mstile-70x70.png [new file with mode: 0644]
assets/img/cp-logo-blue.svg [new file with mode: 0644]
assets/img/dc-logo-black.svg [new file with mode: 0644]
assets/img/lc-icon-black.svg
assets/img/lc-logo-black.png [new file with mode: 0644]
assets/img/lc-logo-black.svg [new file with mode: 0644]
bin/boilerplate/.travis.yml [new file with mode: 0644]
bin/boilerplate/AUTHORS [new file with mode: 0644]
bin/boilerplate/CITATION [new file with mode: 0644]
bin/boilerplate/CODE_OF_CONDUCT.md [new file with mode: 0644]
bin/boilerplate/CONTRIBUTING.md [new file with mode: 0644]
bin/boilerplate/README.md [new file with mode: 0644]
bin/boilerplate/_config.yml [new file with mode: 0644]
bin/boilerplate/_episodes/01-introduction.md [new file with mode: 0644]
bin/boilerplate/_extras/about.md [new file with mode: 0644]
bin/boilerplate/_extras/discuss.md [new file with mode: 0644]
bin/boilerplate/_extras/figures.md [new file with mode: 0644]
bin/boilerplate/_extras/guide.md [new file with mode: 0644]
bin/boilerplate/aio.md [new file with mode: 0644]
bin/boilerplate/index.md [new file with mode: 0644]
bin/boilerplate/reference.md [new file with mode: 0644]
bin/boilerplate/setup.md [new file with mode: 0644]
bin/lesson_check.py
bin/lesson_initialize.py
bin/repo_check.py
bin/test_lesson_check.py
bin/util.py
bin/workshop_check.py
favicon-dc.ico [deleted file]
favicon-lc.ico [deleted file]
favicon-swc.ico [deleted file]

index cf3b859e9a74035ba5f583a71418db2bff78b389..128437da45e107d9c7e14e943c29e84cb723065c 100644 (file)
@@ -5,3 +5,7 @@
 .sass-cache
 __pycache__
 _site
+.Rproj.user
+.Rhistory
+.RData
+
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644 (file)
index 0000000..c3b9669
--- /dev/null
@@ -0,0 +1,11 @@
+---
+layout: page
+title: "Contributor Code of Conduct"
+---
+As contributors and maintainers of this project,
+we pledge to follow the [Carpentry Code of Conduct][coc].
+
+Instances of abusive, harassing, or otherwise unacceptable behavior
+may be reported by following our [reporting guidelines][coc-reporting].
+
+{% include links.md %}
index 39131e4d1d34fa2096bf0a6ddee5d9da03e3eed1..e53782773bc9e3ab26a2565fd4554a1e7206aa50 100644 (file)
@@ -71,10 +71,10 @@ CON EL SOFTWARE O EL USO U OTROS TRATOS EN EL SOFTWARE.
 ## Marca registrada
 
 "Software Carpentry" y "Data Carpentry" y sus respectivos logos
-son marcas registradas de [NumFOCUS][numfocus].
+son marcas registradas de [Community Initiatives][ci].
 
 [cc-por-humano]: https://creativecommons.org/licenses/by/4.0/
 [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode
 [mit-license]: https://opensource.org/licenses/mit-license.html
-[numfocus]: https://numfocus.org/
+[ci]: http://communityin.org/
 [osi]: https://opensource.org
index df31f00cfc7ad62b0afc849061a287392998f06c..f0b73e6064bf52e64c6c27967a70c81a21cc2d89 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@
 # Settings
 MAKEFILES=Makefile $(wildcard *.mk)
 JEKYLL=jekyll
+JEKYLL_VERSION=3.7.3
 PARSER=bin/markdown_ast.rb
 DST=_site
 
@@ -16,6 +17,10 @@ all : commands
 commands :
        @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g'
 
+## docker-serve     : use docker to build the site
+docker-serve :
+       docker run --rm -it -v ${PWD}:/srv/jekyll -p 127.0.0.1:4000:4000 jekyll/jekyll:${JEKYLL_VERSION} make serve
+
 ## serve            : run a local server.
 serve : lesson-md
        ${JEKYLL} serve
@@ -63,7 +68,7 @@ RMD_DST = $(patsubst _episodes_rmd/%.Rmd,_episodes/%.md,$(RMD_SRC))
 # Lesson source files in the order they appear in the navigation menu.
 MARKDOWN_SRC = \
   index.md \
-  CONDUCT.md \
+  CODE_OF_CONDUCT.md \
   setup.md \
   $(sort $(wildcard _episodes/*.md)) \
   reference.md \
@@ -88,16 +93,16 @@ ${RMD_DST} : ${RMD_SRC}
        @bin/knit_lessons.sh ${RMD_SRC}
 
 ## lesson-check     : validate lesson Markdown.
-lesson-check :
+lesson-check : lesson-fixme
        @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md
 
 ## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace.
 lesson-check-all :
-       @bin/lesson_check.py -s . -p ${PARSER} -l -w
+       @bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive
 
 ## unittest         : run unit tests on checking tools.
 unittest :
-       python bin/test_lesson_check.py
+       @bin/test_lesson_check.py
 
 ## lesson-files     : show expected names of generated files for debugging.
 lesson-files :
diff --git a/_includes/favicons.html b/_includes/favicons.html
new file mode 100644 (file)
index 0000000..4ea6742
--- /dev/null
@@ -0,0 +1,33 @@
+{% assign favicon_url = site.baseurl | append: '/assets/favicons/' | append: site.carpentry | prepend: site.url %}
+
+{% if site.carpentry == 'swc' %}
+{% assign carpentry = 'Software Carpentry' %}
+{% elsif site.carpentry == 'dc' %}
+{% assign carpentry = 'Data Carpentry' %}
+{% elsif site.carpentry == 'lc' %}
+{% assign carpentry = 'Library Carpentry' %}
+{% elsif site.carpentry == 'cp' %}
+{% assign carpentry = 'The Carpentries' %}
+{% endif %}
+
+    <!-- Favicons for everyone -->
+    <link rel="apple-touch-icon-precomposed" sizes="57x57" href="{{ favicon_url }}/apple-touch-icon-57x57.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="{{ favicon_url }}/apple-touch-icon-114x114.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="{{ favicon_url }}/apple-touch-icon-72x72.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{ favicon_url }}/apple-touch-icon-144x144.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="60x60" href="{{ favicon_url }}/apple-touch-icon-60x60.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="120x120" href="{{ favicon_url }}/apple-touch-icon-120x120.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="76x76" href="{{ favicon_url }}/apple-touch-icon-76x76.png" />
+    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="{{ favicon_url }}/apple-touch-icon-152x152.png" />
+    <link rel="icon" type="image/png" href="{{ favicon_url }}/favicon-196x196.png" sizes="196x196" />
+    <link rel="icon" type="image/png" href="{{ favicon_url }}/favicon-96x96.png" sizes="96x96" />
+    <link rel="icon" type="image/png" href="{{ favicon_url }}/favicon-32x32.png" sizes="32x32" />
+    <link rel="icon" type="image/png" href="{{ favicon_url }}/favicon-16x16.png" sizes="16x16" />
+    <link rel="icon" type="image/png" href="{{ favicon_url }}/favicon-128.png" sizes="128x128" />
+    <meta name="application-name" content="{{ carpentry }} - {{ site.title }}"/>
+    <meta name="msapplication-TileColor" content="#FFFFFF" />
+    <meta name="msapplication-TileImage" content="{{ favicon_url }}/mstile-144x144.png" />
+    <meta name="msapplication-square70x70logo" content="{{ favicon_url }}/mstile-70x70.png" />
+    <meta name="msapplication-square150x150logo" content="{{ favicon_url }}/mstile-150x150.png" />
+    <meta name="msapplication-wide310x150logo" content="{{ favicon_url }}/mstile-310x150.png" />
+    <meta name="msapplication-square310x310logo" content="{{ favicon_url }}/mstile-310x310.png" />
index 56aae5a1dceaedf7f396bdef39195e176ccd9082..e49bac0f47e2b3903b21abd60732f2498d90b04e 100644 (file)
@@ -10,7 +10,6 @@
     </ul>
 <p align = "center">
     <em>
-        Library Carpentry te presenta los fundamentos de la informática y le proporciona una plataforma para un mayor aprendizaje autodirigido. Para obtener más información sobre lo que enseñamos y por qué consulte nuestro documento
-         "<a href="http://doi.org/10.18352/lq.10176"> Library Carpentry: software skills training for library professionals</a>".
+      Library Carpentry te presenta los fundamentos de la informática y le proporciona una plataforma para un mayor aprendizaje autodirigido. Para obtener más información sobre lo que enseñamos y por qué consulte nuestro documento "<a href="http://doi.org/10.18352/lq.10176"> Library Carpentry: software skills training for library professionals</a>".
     </em>
-</p>
\ No newline at end of file
+</p>
index 200068d2f8b4d911e5435fa10aeea3fb242af193..1d82a80904e92e0ac0d9d16023eddbffb6d07b21 100644 (file)
@@ -3,20 +3,28 @@
 {% endcomment %}
 <footer>
   <div class="row">
-    <div class="col-md-6" align="left">
-      <h4>
-       Copyright &copy; 2016–{{ 'now' | date: "%Y" }}
+    <div class="col-md-6 copyright" align="left">
        {% if site.carpentry == "swc" %}
+       Copyright &copy; 2018–{{ 'now' | date: "%Y" }}
+       <a href="{{ site.carpentries_site }}">The Carpentries</a>
+        <br>
+        Copyright &copy; 2016–2018
        <a href="{{ site.swc_site }}">Software Carpentry Foundation</a>
        {% elsif site.carpentry == "dc" %}
+       Copyright &copy; 2018–{{ 'now' | date: "%Y" }}
+       <a href="{{ site.carpentries_site }}">The Carpentries</a>
+        <br>
+        Copyright &copy; 2016–2018
        <a href="{{ site.dc_site }}">Data Carpentry</a>
        {% elsif site.carpentry == "lc" %}
+       Copyright &copy; 2016–{{ 'now' | date: "%Y" }}
        <a href="{{ site.lc_site }}">Library Carpentry</a>
+       {% elsif site.carpentry == "cp" %}
+       Copyright &copy; 2018–{{ 'now' | date: "%Y" }}
+       <a href="{{ site.carpentries_site }}">The Carpentries</a>
        {% endif %}
-      </h4>
     </div>
-    <div class="col-md-6" align="right">
-      <h4>
+    <div class="col-md-6 help-links" align="right">
        {% if page.source %}
        {% if page.source == "Rmd" %}
        <a href="{{site.github.repository_url}}/edit/gh-pages/{{page.path|replace: "_episodes", "_episodes_rmd" | replace: ".md", ".Rmd"}}">Editar en GitHub</a>
        /
        <a href="{{ site.github.repository_url }}/blob/gh-pages/CITATION">Cita</a>
        /
-
        <a href="mailto:{{ site.email }}">Contacto</a>
-      </h4>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-md-12" align="center">
+      <a href="https://github.com/carpentries/styles/">The Carpentries style</a>
+      version <a href="https://github.com/carpentries/styles/releases/tag/v9.5.2">9.5.2</a>.
     </div>
   </div>
 </footer>
index 273d63ea4dcf836caaaf52639722dc9d11879dcd..e18ce6329b4f29662a8b5aa4d2fcfc8135d7410a 100644 (file)
@@ -1,12 +1,15 @@
 [cc-by-human]: https://creativecommons.org/licenses/by/4.0/
 [cc-by-legal]: https://creativecommons.org/licenses/by/4.0/legalcode
+[ci]: http://communityin.org/
+[coc-reporting]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html#reporting-guidelines
+[coc]: https://docs.carpentries.org/topic_folders/policies/code-of-conduct.html
 [concept-maps]: https://carpentries.github.io/instructor-training/05-memory/
-[email]: mailto:lessons@software-carpentry.org
 [contrib-covenant]: https://contributor-covenant.org/
 [contributing]: {{ site.github.repository_url }}/blob/gh-pages/CONTRIBUTING.md
-[cran-checkpoint]: https://cran.r-project.org/web/packages/checkpoint/index.html
-[cran-knitr]: https://cran.r-project.org/web/packages/knitr/index.html
-[cran-stringr]: https://cran.r-project.org/web/packages/stringr/index.html
+[cran-checkpoint]: https://cran.r-project.org/package=checkpoint
+[cran-knitr]: https://cran.r-project.org/package=knitr
+[cran-stringr]: https://cran.r-project.org/package=stringr
+[email]: mailto:team@carpentries.org
 [github-importer]: https://import.github.com/
 [importer]: https://github.com/new/import
 [jekyll-collection]: https://jekyllrb.com/docs/collections/
@@ -14,6 +17,7 @@
 [jekyll-windows]: http://jekyll-windows.juthilo.com/
 [jekyll]: https://jekyllrb.com/
 [jupyter]: https://jupyter.org/
+[lesson-example]: https://carpentries.github.io/lesson-example/
 [mit-license]: https://opensource.org/licenses/mit-license.html
 [morea]: https://morea-framework.github.io/
 [numfocus]: https://numfocus.org/
 [paper-now]: https://github.com/PeerJ/paper-now
 [python-gapminder]: https://swcarpentry.github.io/python-novice-gapminder/
 [pyyaml]: https://pypi.python.org/pypi/PyYAML
-[r-markdown]: http://rmarkdown.rstudio.com/
+[r-markdown]: https://rmarkdown.rstudio.com/
 [rstudio]: https://www.rstudio.com/
 [ruby-install-guide]: https://www.ruby-lang.org/en/downloads/
 [ruby-installer]: https://rubyinstaller.org/
 [rubygems]: https://rubygems.org/pages/download/
-[styles]: https://github.com/swcarpentry/styles/
-[training]: https://swcarpentry.github.io/instructor-training/
+[styles]: https://github.com/carpentries/styles/
+[swc-releases]: https://github.com/swcarpentry/swc-releases
 [workshop-repo]: {{ site.workshop_repo }}
 [yaml]: http://yaml.org/
-[coc]: https://software-carpentry.org/conduct/
-[coc-reporting]: https://software-carpentry.org/CoC-reporting/
-[lesson-example]: https://swcarpentry.github.io/lesson-example/
index e1f8acfb62c5b079f3661851d97bc7e9fea3fc1f..d7de8e9c415f6bafee914a4ece015545879ff388 100644 (file)
         <span class="icon-bar"></span>
       </button>
 
+
       {% comment %} Seleccione qué logotipo mostrar. {% endcomment %}
       {% if page.carpentry == "swc" %}
       <a href="{{ site.swc_site }}" class="pull-left">
         <img class="navbar-logo" src="{{ page.root }}/assets/img/swc-icon-blue.svg" alt="Software Carpentry logo" />
       </a>
-      {% elsif page.carpentry == "dc" %}
+      {% elsif site.carpentry == "dc" %}
       <a href="{{ site.dc_site }}" class="pull-left">
         <img class="navbar-logo" src="{{ page.root }}/assets/img/dc-icon-black.svg" alt="Data Carpentry logo" />
       </a>
-      {% elsif page.carpentry == "lc" %}
+      {% elsif site.carpentry == "lc" %}
       <a href="{{ site.lc_site }}" class="pull-left">
-        <img class="navbar-logo" src="{{ page.root }}/assets/img/lc-icon-black.png" alt="Library Carpentry logo" />
+        <img class="navbar-logo" src="{{ page.root }}/assets/img/lc-icon-black.svg" alt="Library Carpentry logo" />
+      </a>
+      {% elsif site.carpentry == "cp" %}
+      <a href="{{ site.carpentries_site }}" class="pull-left">
+        <img class="navbar-logo" src="{{ page.root }}/assets/img/cp-logo-blue.svg" alt="The Carpentries logo" />
       </a>
       {% endif %}
 
@@ -34,7 +39,7 @@
       <ul class="nav navbar-nav">
 
        {% comment %} Mostrar siempre el código de conducta. {% endcomment %}
-        <li><a href="{{ page.root }}{% link CONDUCT.md %}">Código de conducta</a></li>
+        <li><a href="{{ page.root }}{% link CODE_OF_CONDUCT.md %}">Code of Conduct</a></li>
 
         {% if site.kind == "lesson" %}
        {% comment %} Muestra las instrucciones de configuración. {% endcomment %}
index e6610e134da3dd49bb3f4170e8855f99387a668f..8ba35975c4ef680b9e7bf27d82b66a125b8f0707 100644 (file)
@@ -7,11 +7,13 @@
       <h4>
        Copyright &copy; 2016–{{ 'now' | date: "%Y" }}
        {% if site.carpentry == "swc" %}
-       <a href="{{ site.swc_site }}">Software Carpentry Foundation</a>
+       <a href="{{ site.swc_site }}">Software Carpentry</a>
        {% elsif site.carpentry == "dc" %}
        <a href="{{ site.dc_site }}">Data Carpentry</a>
        {% elsif site.carpentry == "lc" %}
        <a href="{{ site.lc_site }}">Library Carpentry</a>
+       {% elsif site.carpentry == "cp" %}
+       <a href="{{ site.carpentries_site }}">The Carpentries</a>
        {% endif %}
       </h4>
     </div>
index f1e90d1ad2e958b8eafe5799657a0bb42ea8306d..99d6567434a839aaeb0ad1f08f701c1483098af9 100644 (file)
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/bootstrap-theme.css" />
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/lesson.css" />
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/syntax.css" />
-    {% if site.carpentry == "swc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-swc.ico" />
-    {% elsif site.carpentry == "dc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-dc.ico" />
-    {% elsif site.carpentry == "lc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-lc.ico" />
-    {% endif %}
+
+    {% include favicons.html %}
+
     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
     <!--[if lt IE 9]>
index ccd8747ee6027197b799c3dbfb24327f2f5d14e6..3525da390ded29b56c2c7270038f2a690f553384 100644 (file)
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/bootstrap.css" />
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/bootstrap-theme.css" />
     <link rel="stylesheet" type="text/css" href="{{ page.root }}/assets/css/lesson.css" />
-    {% if site.carpentry == "swc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-swc.ico" />
-    {% elsif site.carpentry == "dc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-dc.ico" />
-    {% elsif site.carpentry == "lc" %}
-    <link rel="shortcut icon" type="image/x-icon" href="/favicon-lc.ico" />
-    {% endif %}
+
+    {% include favicons.html %}
+
     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
     <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
     <!--[if lt IE 9]>
index 0fe7cd5b0691346e33701966678e767200ef9bb9..6704f50ce3857f15a7e05f324e2fd54c468c2267 100644 (file)
@@ -107,6 +107,7 @@ pre,
 samp {
   font-family: monospace, monospace;
   font-size: 1em;
+  hyphens: none;
 }
 button,
 input,
index d2a2f29f6b21d7afccb07ffff29988ab24d481ec..8a7b29548dd218d86ad411a27ecee7b255737f45 100644 (file)
@@ -114,11 +114,24 @@ $codeblock-padding: 5px !default;
 .solution{ @include bkSetup($color-solution, "\e105"); }
 .testimonial{ @include bkSetup($color-testimonial, "\e143"); }
 
+.callout h3,
+.challenge h3,
+.checklist h3,
+.discussion h3,
+.keypoints h3,
+.objectives h3,
+.prereq h3,
+.solution h3,
+.testimonial h3 {
+font-size: 18px;
+}
+
 //----------------------------------------
 // Override Bootstrap settings.
 //----------------------------------------
 
 code {
+  white-space: nowrap;
   padding: 2px 5px;
   color: #3d90d9;
   background-color: #e7e7e7;
@@ -140,6 +153,16 @@ img {
   text-align: center;
 }
 
+footer .copyright,
+footer .help-links
+{
+    font-size: 18px;
+    margin-top: 10px;
+    margin-bottom: 10px;
+    font-weight: 500;
+    line-height: 1.1;
+}
+
 img.navbar-logo {
   height: 40px; // synchronize with height of navbar
   padding-top: 5px;
diff --git a/assets/favicons/cp/apple-touch-icon-114x114.png b/assets/favicons/cp/apple-touch-icon-114x114.png
new file mode 100644 (file)
index 0000000..a60b758
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-114x114.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-120x120.png b/assets/favicons/cp/apple-touch-icon-120x120.png
new file mode 100644 (file)
index 0000000..8f20a8f
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-120x120.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-144x144.png b/assets/favicons/cp/apple-touch-icon-144x144.png
new file mode 100644 (file)
index 0000000..4be151b
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-144x144.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-152x152.png b/assets/favicons/cp/apple-touch-icon-152x152.png
new file mode 100644 (file)
index 0000000..7d1d943
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-152x152.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-57x57.png b/assets/favicons/cp/apple-touch-icon-57x57.png
new file mode 100644 (file)
index 0000000..92309ce
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-57x57.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-60x60.png b/assets/favicons/cp/apple-touch-icon-60x60.png
new file mode 100644 (file)
index 0000000..de8148e
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-60x60.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-72x72.png b/assets/favicons/cp/apple-touch-icon-72x72.png
new file mode 100644 (file)
index 0000000..81d7e3d
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-72x72.png differ
diff --git a/assets/favicons/cp/apple-touch-icon-76x76.png b/assets/favicons/cp/apple-touch-icon-76x76.png
new file mode 100644 (file)
index 0000000..15bca5c
Binary files /dev/null and b/assets/favicons/cp/apple-touch-icon-76x76.png differ
diff --git a/assets/favicons/cp/favicon-128.png b/assets/favicons/cp/favicon-128.png
new file mode 100644 (file)
index 0000000..e612cdc
Binary files /dev/null and b/assets/favicons/cp/favicon-128.png differ
diff --git a/assets/favicons/cp/favicon-16x16.png b/assets/favicons/cp/favicon-16x16.png
new file mode 100644 (file)
index 0000000..65b3311
Binary files /dev/null and b/assets/favicons/cp/favicon-16x16.png differ
diff --git a/assets/favicons/cp/favicon-196x196.png b/assets/favicons/cp/favicon-196x196.png
new file mode 100644 (file)
index 0000000..0da938b
Binary files /dev/null and b/assets/favicons/cp/favicon-196x196.png differ
diff --git a/assets/favicons/cp/favicon-32x32.png b/assets/favicons/cp/favicon-32x32.png
new file mode 100644 (file)
index 0000000..0c1442e
Binary files /dev/null and b/assets/favicons/cp/favicon-32x32.png differ
diff --git a/assets/favicons/cp/favicon-96x96.png b/assets/favicons/cp/favicon-96x96.png
new file mode 100644 (file)
index 0000000..bed74ec
Binary files /dev/null and b/assets/favicons/cp/favicon-96x96.png differ
diff --git a/assets/favicons/cp/favicon.ico b/assets/favicons/cp/favicon.ico
new file mode 100644 (file)
index 0000000..4f2f2f1
Binary files /dev/null and b/assets/favicons/cp/favicon.ico differ
diff --git a/assets/favicons/cp/mstile-144x144.png b/assets/favicons/cp/mstile-144x144.png
new file mode 100644 (file)
index 0000000..4be151b
Binary files /dev/null and b/assets/favicons/cp/mstile-144x144.png differ
diff --git a/assets/favicons/cp/mstile-150x150.png b/assets/favicons/cp/mstile-150x150.png
new file mode 100644 (file)
index 0000000..bf7ad5e
Binary files /dev/null and b/assets/favicons/cp/mstile-150x150.png differ
diff --git a/assets/favicons/cp/mstile-310x150.png b/assets/favicons/cp/mstile-310x150.png
new file mode 100644 (file)
index 0000000..6ac8048
Binary files /dev/null and b/assets/favicons/cp/mstile-310x150.png differ
diff --git a/assets/favicons/cp/mstile-310x310.png b/assets/favicons/cp/mstile-310x310.png
new file mode 100644 (file)
index 0000000..b778147
Binary files /dev/null and b/assets/favicons/cp/mstile-310x310.png differ
diff --git a/assets/favicons/cp/mstile-70x70.png b/assets/favicons/cp/mstile-70x70.png
new file mode 100644 (file)
index 0000000..e612cdc
Binary files /dev/null and b/assets/favicons/cp/mstile-70x70.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-114x114.png b/assets/favicons/dc/apple-touch-icon-114x114.png
new file mode 100644 (file)
index 0000000..edafbda
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-114x114.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-120x120.png b/assets/favicons/dc/apple-touch-icon-120x120.png
new file mode 100644 (file)
index 0000000..ee145ec
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-120x120.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-144x144.png b/assets/favicons/dc/apple-touch-icon-144x144.png
new file mode 100644 (file)
index 0000000..bf50701
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-144x144.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-152x152.png b/assets/favicons/dc/apple-touch-icon-152x152.png
new file mode 100644 (file)
index 0000000..bd596c8
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-152x152.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-57x57.png b/assets/favicons/dc/apple-touch-icon-57x57.png
new file mode 100644 (file)
index 0000000..61c1527
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-57x57.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-60x60.png b/assets/favicons/dc/apple-touch-icon-60x60.png
new file mode 100644 (file)
index 0000000..9daad36
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-60x60.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-72x72.png b/assets/favicons/dc/apple-touch-icon-72x72.png
new file mode 100644 (file)
index 0000000..2069520
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-72x72.png differ
diff --git a/assets/favicons/dc/apple-touch-icon-76x76.png b/assets/favicons/dc/apple-touch-icon-76x76.png
new file mode 100644 (file)
index 0000000..3db01ca
Binary files /dev/null and b/assets/favicons/dc/apple-touch-icon-76x76.png differ
diff --git a/assets/favicons/dc/favicon-128.png b/assets/favicons/dc/favicon-128.png
new file mode 100644 (file)
index 0000000..9e3de2a
Binary files /dev/null and b/assets/favicons/dc/favicon-128.png differ
diff --git a/assets/favicons/dc/favicon-16x16.png b/assets/favicons/dc/favicon-16x16.png
new file mode 100644 (file)
index 0000000..4c9f9b8
Binary files /dev/null and b/assets/favicons/dc/favicon-16x16.png differ
diff --git a/assets/favicons/dc/favicon-196x196.png b/assets/favicons/dc/favicon-196x196.png
new file mode 100644 (file)
index 0000000..588afc2
Binary files /dev/null and b/assets/favicons/dc/favicon-196x196.png differ
diff --git a/assets/favicons/dc/favicon-32x32.png b/assets/favicons/dc/favicon-32x32.png
new file mode 100644 (file)
index 0000000..9c2ecbf
Binary files /dev/null and b/assets/favicons/dc/favicon-32x32.png differ
diff --git a/assets/favicons/dc/favicon-96x96.png b/assets/favicons/dc/favicon-96x96.png
new file mode 100644 (file)
index 0000000..ff13fc0
Binary files /dev/null and b/assets/favicons/dc/favicon-96x96.png differ
diff --git a/assets/favicons/dc/favicon.ico b/assets/favicons/dc/favicon.ico
new file mode 100644 (file)
index 0000000..e4715f3
Binary files /dev/null and b/assets/favicons/dc/favicon.ico differ
diff --git a/assets/favicons/dc/mstile-144x144.png b/assets/favicons/dc/mstile-144x144.png
new file mode 100644 (file)
index 0000000..bf50701
Binary files /dev/null and b/assets/favicons/dc/mstile-144x144.png differ
diff --git a/assets/favicons/dc/mstile-150x150.png b/assets/favicons/dc/mstile-150x150.png
new file mode 100644 (file)
index 0000000..c5844cc
Binary files /dev/null and b/assets/favicons/dc/mstile-150x150.png differ
diff --git a/assets/favicons/dc/mstile-310x150.png b/assets/favicons/dc/mstile-310x150.png
new file mode 100644 (file)
index 0000000..786813a
Binary files /dev/null and b/assets/favicons/dc/mstile-310x150.png differ
diff --git a/assets/favicons/dc/mstile-310x310.png b/assets/favicons/dc/mstile-310x310.png
new file mode 100644 (file)
index 0000000..9580653
Binary files /dev/null and b/assets/favicons/dc/mstile-310x310.png differ
diff --git a/assets/favicons/dc/mstile-70x70.png b/assets/favicons/dc/mstile-70x70.png
new file mode 100644 (file)
index 0000000..9e3de2a
Binary files /dev/null and b/assets/favicons/dc/mstile-70x70.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-114x114.png b/assets/favicons/lc/apple-touch-icon-114x114.png
new file mode 100644 (file)
index 0000000..6c83127
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-114x114.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-120x120.png b/assets/favicons/lc/apple-touch-icon-120x120.png
new file mode 100644 (file)
index 0000000..8334648
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-120x120.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-144x144.png b/assets/favicons/lc/apple-touch-icon-144x144.png
new file mode 100644 (file)
index 0000000..5f32151
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-144x144.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-152x152.png b/assets/favicons/lc/apple-touch-icon-152x152.png
new file mode 100644 (file)
index 0000000..4e5c177
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-152x152.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-57x57.png b/assets/favicons/lc/apple-touch-icon-57x57.png
new file mode 100644 (file)
index 0000000..61f9c9c
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-57x57.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-60x60.png b/assets/favicons/lc/apple-touch-icon-60x60.png
new file mode 100644 (file)
index 0000000..ccb5ada
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-60x60.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-72x72.png b/assets/favicons/lc/apple-touch-icon-72x72.png
new file mode 100644 (file)
index 0000000..517d459
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-72x72.png differ
diff --git a/assets/favicons/lc/apple-touch-icon-76x76.png b/assets/favicons/lc/apple-touch-icon-76x76.png
new file mode 100644 (file)
index 0000000..17454b3
Binary files /dev/null and b/assets/favicons/lc/apple-touch-icon-76x76.png differ
diff --git a/assets/favicons/lc/favicon-128.png b/assets/favicons/lc/favicon-128.png
new file mode 100644 (file)
index 0000000..9d781c9
Binary files /dev/null and b/assets/favicons/lc/favicon-128.png differ
diff --git a/assets/favicons/lc/favicon-16x16.png b/assets/favicons/lc/favicon-16x16.png
new file mode 100644 (file)
index 0000000..3c20abc
Binary files /dev/null and b/assets/favicons/lc/favicon-16x16.png differ
diff --git a/assets/favicons/lc/favicon-196x196.png b/assets/favicons/lc/favicon-196x196.png
new file mode 100644 (file)
index 0000000..46baaf8
Binary files /dev/null and b/assets/favicons/lc/favicon-196x196.png differ
diff --git a/assets/favicons/lc/favicon-32x32.png b/assets/favicons/lc/favicon-32x32.png
new file mode 100644 (file)
index 0000000..ed6701e
Binary files /dev/null and b/assets/favicons/lc/favicon-32x32.png differ
diff --git a/assets/favicons/lc/favicon-96x96.png b/assets/favicons/lc/favicon-96x96.png
new file mode 100644 (file)
index 0000000..bc468c7
Binary files /dev/null and b/assets/favicons/lc/favicon-96x96.png differ
diff --git a/assets/favicons/lc/favicon.ico b/assets/favicons/lc/favicon.ico
new file mode 100644 (file)
index 0000000..5c14e80
Binary files /dev/null and b/assets/favicons/lc/favicon.ico differ
diff --git a/assets/favicons/lc/mstile-144x144.png b/assets/favicons/lc/mstile-144x144.png
new file mode 100644 (file)
index 0000000..5f32151
Binary files /dev/null and b/assets/favicons/lc/mstile-144x144.png differ
diff --git a/assets/favicons/lc/mstile-150x150.png b/assets/favicons/lc/mstile-150x150.png
new file mode 100644 (file)
index 0000000..924953a
Binary files /dev/null and b/assets/favicons/lc/mstile-150x150.png differ
diff --git a/assets/favicons/lc/mstile-310x150.png b/assets/favicons/lc/mstile-310x150.png
new file mode 100644 (file)
index 0000000..e4dcda4
Binary files /dev/null and b/assets/favicons/lc/mstile-310x150.png differ
diff --git a/assets/favicons/lc/mstile-310x310.png b/assets/favicons/lc/mstile-310x310.png
new file mode 100644 (file)
index 0000000..a12c876
Binary files /dev/null and b/assets/favicons/lc/mstile-310x310.png differ
diff --git a/assets/favicons/lc/mstile-70x70.png b/assets/favicons/lc/mstile-70x70.png
new file mode 100644 (file)
index 0000000..9d781c9
Binary files /dev/null and b/assets/favicons/lc/mstile-70x70.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-114x114.png b/assets/favicons/swc/apple-touch-icon-114x114.png
new file mode 100644 (file)
index 0000000..e5125f8
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-114x114.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-120x120.png b/assets/favicons/swc/apple-touch-icon-120x120.png
new file mode 100644 (file)
index 0000000..0f97a0a
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-120x120.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-144x144.png b/assets/favicons/swc/apple-touch-icon-144x144.png
new file mode 100644 (file)
index 0000000..7441446
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-144x144.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-152x152.png b/assets/favicons/swc/apple-touch-icon-152x152.png
new file mode 100644 (file)
index 0000000..45cc338
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-152x152.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-57x57.png b/assets/favicons/swc/apple-touch-icon-57x57.png
new file mode 100644 (file)
index 0000000..e180a4a
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-57x57.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-60x60.png b/assets/favicons/swc/apple-touch-icon-60x60.png
new file mode 100644 (file)
index 0000000..c96fd6c
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-60x60.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-72x72.png b/assets/favicons/swc/apple-touch-icon-72x72.png
new file mode 100644 (file)
index 0000000..aae014a
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-72x72.png differ
diff --git a/assets/favicons/swc/apple-touch-icon-76x76.png b/assets/favicons/swc/apple-touch-icon-76x76.png
new file mode 100644 (file)
index 0000000..2167f94
Binary files /dev/null and b/assets/favicons/swc/apple-touch-icon-76x76.png differ
diff --git a/assets/favicons/swc/favicon-128.png b/assets/favicons/swc/favicon-128.png
new file mode 100644 (file)
index 0000000..f61df62
Binary files /dev/null and b/assets/favicons/swc/favicon-128.png differ
diff --git a/assets/favicons/swc/favicon-16x16.png b/assets/favicons/swc/favicon-16x16.png
new file mode 100644 (file)
index 0000000..2d20a40
Binary files /dev/null and b/assets/favicons/swc/favicon-16x16.png differ
diff --git a/assets/favicons/swc/favicon-196x196.png b/assets/favicons/swc/favicon-196x196.png
new file mode 100644 (file)
index 0000000..2a20d3a
Binary files /dev/null and b/assets/favicons/swc/favicon-196x196.png differ
diff --git a/assets/favicons/swc/favicon-32x32.png b/assets/favicons/swc/favicon-32x32.png
new file mode 100644 (file)
index 0000000..f622b73
Binary files /dev/null and b/assets/favicons/swc/favicon-32x32.png differ
diff --git a/assets/favicons/swc/favicon-96x96.png b/assets/favicons/swc/favicon-96x96.png
new file mode 100644 (file)
index 0000000..5e57f66
Binary files /dev/null and b/assets/favicons/swc/favicon-96x96.png differ
diff --git a/assets/favicons/swc/favicon.ico b/assets/favicons/swc/favicon.ico
new file mode 100644 (file)
index 0000000..f771790
Binary files /dev/null and b/assets/favicons/swc/favicon.ico differ
diff --git a/assets/favicons/swc/mstile-144x144.png b/assets/favicons/swc/mstile-144x144.png
new file mode 100644 (file)
index 0000000..7441446
Binary files /dev/null and b/assets/favicons/swc/mstile-144x144.png differ
diff --git a/assets/favicons/swc/mstile-150x150.png b/assets/favicons/swc/mstile-150x150.png
new file mode 100644 (file)
index 0000000..d1594bc
Binary files /dev/null and b/assets/favicons/swc/mstile-150x150.png differ
diff --git a/assets/favicons/swc/mstile-310x150.png b/assets/favicons/swc/mstile-310x150.png
new file mode 100644 (file)
index 0000000..f7d58b2
Binary files /dev/null and b/assets/favicons/swc/mstile-310x150.png differ
diff --git a/assets/favicons/swc/mstile-310x310.png b/assets/favicons/swc/mstile-310x310.png
new file mode 100644 (file)
index 0000000..b632b42
Binary files /dev/null and b/assets/favicons/swc/mstile-310x310.png differ
diff --git a/assets/favicons/swc/mstile-70x70.png b/assets/favicons/swc/mstile-70x70.png
new file mode 100644 (file)
index 0000000..f61df62
Binary files /dev/null and b/assets/favicons/swc/mstile-70x70.png differ
diff --git a/assets/img/cp-logo-blue.svg b/assets/img/cp-logo-blue.svg
new file mode 100644 (file)
index 0000000..da70d40
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="23.011598587036133 176.38101196289062 76.86479759216309 79.23809814453125" width="76.86479759216309" height="79.23809814453125" xmlns="http://www.w3.org/2000/svg">
+  <path id="path2" style="fill:#071159;fill-rule:evenodd" d="m 60.4089,220.1395 -0.609,-15.6219 13.481,-8.4941 13.6126,7.2951 0.692,16.0431 -13.481,8.4935 z" transform="matrix(1, 0, 0, 1, 3.552713678800501e-15, 0)"/>
+  <path id="path4" style="fill:#071159;fill-rule:evenodd" d="m 33.6628,217.112 -0.0823,-22.4502 29.2906,-18.2808 14.0091,8.3629 c -10.1028,6.5645 -14.7455,9.3309 -24.9875,15.6991 l -0.1926,5.9751 z" transform="matrix(1, 0, 0, 1, 3.552713678800501e-15, 0)"/>
+  <path id="path6" style="fill:#071159;fill-rule:evenodd" d="m 35.0548,248.4071 -12.0432,-19.0814 28.7863,-16.8447 1.1557,12.3346 10.7928,5.589 z" transform="matrix(1, 0, 0, 1, 3.552713678800501e-15, 0)"/>
+  <path id="path8" style="fill:#071159;fill-rule:evenodd" d="m 50.128,245.2642 19.919,10.3549 29.8294,-18.2487 -1.8935,-15.6419 c -10.3375,6.1835 -14.3477,8.7856 -24.6876,14.9664 l -5.3995,-2.5663 z" transform="matrix(1, 0, 0, 1, 3.552713678800501e-15, 0)"/>
+</svg>
\ No newline at end of file
diff --git a/assets/img/dc-logo-black.svg b/assets/img/dc-logo-black.svg
new file mode 100644 (file)
index 0000000..0cef4ee
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1_2_"
+   width="177.26501"
+   height="59.007732"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="dc.svg">
+  <metadata
+     id="metadata3608">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3606" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1088"
+     inkscape:window-height="692"
+     id="namedview3604"
+     showgrid="false"
+     inkscape:zoom="1.2228904"
+     inkscape:cx="53.730618"
+     inkscape:cy="118.68094"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Layer_1_2_"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;stroke:none"
+     d="m 377.18496,-71.886104 0,2 45,0 c 16.6071,0 33.5691,0.30551 49,7.312499 9.35004,4.2457 17.36004,10.6668 22.47504,19.687501 12.397,21.8653 4.995,51.7467998 -16.475,64.5471 -11.73124,6.9939 -24.67714,8.6249 -38.00004,9.5429 -20.5979,1.418 -41.3244,0.91 -62,0.91 l 0,47.000004 c 3.33725,-3.967 5.80744,-8.339 10.0008,-11.606 8.2497,-6.428 20.1709,-6.498 29.9992,-5.343 4.7185,0.554 19.3015,3.864 17.2485,10.953 -0.8017,2.768 -4.2276,6.772 -7.2524,7.035 -2.7517,0.238 -5.4904,-2.322 -7.9961,-3.189 -8.0047,-2.769 -23.6558,-3.279 -26.4128,7.154 -1.8285,6.919 3.1413,11.863 9.4128,13.315 9.0819,2.103 19.2695,0.393 25,-7.319 2.5834,2.638 9.0984,7.685 7.8079,11.96 -1.7806,5.898 -11.6335,8.206 -16.8079,9.116 -14.7799,2.601 -35.06049,-0.446 -40,-17.076 -1.98057,4.72 -1,10.92 -1,16 l 0,32 31,0 0,74 -31,0 0,162 485.00004,0 0,-236 89,0 c 14.402,0 29.704,-1.469 44,0.286 23.229,2.853 46.807,14.301 62.575,31.753 15.726,17.408 26.01,38.469 28.255,61.961 0.723,7.564 0.17,15.404 0.17,23 0,13.504 0.423,26.787 -2.895,40 -8.066,32.114 -31.7,58.372 -62.105,70.988 -10.518,4.365 -21.596,7.004 -33,7.012 3.699,1.552 8.017,1 12,1 l 20,0 74,0 0,-450.000004 -78,0 c 14.746,26.487099 34.719,50.8526 51.67,75.9999998 6.071,9.0075002 14.11,17.9675002 18.33,28.0000002 l -23,0 c -3.419,0 -7.788,0.668 -10.907,-1.028 -6.115,-3.3261 -7.365,-13.6847 -14.277,-15.6541 -5.282,-1.5047 -12.346,-0.3179 -17.816,-0.3179 -11.293,0 -22.704,-0.4819 -33.985,0.0193 -9.728,0.4322 -9.363,13.0897 -17.199,16.3777 -3.129,1.312 -7.496,0.603 -10.816,0.603 l -22,0 c 3.153,-8.1975 9.791,-15.6861 14.667,-23.0000002 10.665,-15.9976 21.04,-32.2397998 32.053,-47.9999998 7.161,-10.248501 16.837,-21.276901 21.28,-33 l -358,0 c 4.985,13.153199 16.243,25.497499 24.28,37 15.481,22.1552 30.605,44.5937998 45.72,67 l -24,0 c -3.359,0 -7.775,0.7 -10.816,-1.028 -7.209,-4.0961 -7.694,-15.5368 -17.188,-15.9527 -10.954,-0.4799 -22.031,-0.0193 -32.996,-0.0193 -5.585,0 -12.539,-1.1105 -17.96,0.3179 -7.241,1.9083 -8.377,12.0616 -14.366,15.6541 -2.937,1.763 -7.397,1.028 -10.674,1.028 l -23,0 c 4.568,-9.6555 11.751,-18.1422 17.667,-27.0000002 l 34,-51.0000008 c 5.767,-8.6466 12.272,-16.90872 17.333,-25.999999 l -257.00004,0 z"
+     id="path3588" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#231f20;stroke:none"
+     d="m 0,0.00761578 0,18.50000022 7.75,0 0,-18.50000022 -7.75,0 m 15.25,0 0,23.50000022 7.75,0 0,-23.50000022 -7.75,0 m 15,0 0,28.50000022 7.75,0 0,-28.50000022 -7.75,0 m 15.25,0 0,33.75000022 7.75,0 0,-33.75000022 -7.75,0 m 15,0 0,38.75000022 7.75,0 0,-38.75000022 -7.75,0 m 15.25,0 0,43.75000022 7.75,0 0,-43.75000022 -7.75,0 m 15.25,0 0,48.75000422 7.75,0 0,-48.75000422 -7.75,0 m 15,0 0,53.75000422 7.75,0 0,-53.75000422 -7.75,0 m 15.25,0 0,59.00000422 22.75,0 c 7.48325,0 14.64825,0.0795 21.25,-4.0165 5.92275,-3.67475 10.22625,-9.880254 11.54875,-16.733504 0.56,-2.901 0.45125,-5.81 0.45125,-8.75 0,-3.015 0.14275,-6.027 -0.452,-9 C 175.29725,13.004866 170.30275,6.3398658 163.5,2.8221158 157.48325,-0.28913422 151.318,0.00761578 144.75,0.00761578 l -23.5,0 z"
+     id="path3598" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;stroke:none"
+     d="m 129,7.7576158 0,43.2500042 17.25,0 c 4.75575,0 9.147,0.227 13.5,-2.02725 4.562,-2.36225 8.00875,-6.703504 9.191,-11.722754 0.6255,-2.656 0.559,-5.29175 0.559,-8 0,-7.52075 -1.64,-14.469 -8.5,-18.7335 -4.72075,-2.9347502 -9.6605,-2.7665002 -15,-2.7665002 l -17,0 z"
+     id="path3600" />
+  <path
+     inkscape:connector-curvature="0"
+     style="fill:#231f20;stroke:none"
+     d="m 136.5,15.257616 0,28.5 10.5,0 c 2.19,0 4.59025,0.27325 6.75,-0.11625 3.7395,-0.674 6.79175,-3.578 7.9775,-7.13375 0.408,-1.224 0.519,-2.46925 0.5225,-3.75 l -7.75,0 c -1.08575,4.51625 -6.67475,3.25 -10.25,3.25 l 0,-13 c 2.356,0 5.49425,-0.54525 7.75,0.16325 1.51175,0.47475 1.6535,2.1015 2.8545,2.686 0.66525,0.3235 1.6775,0.15075 2.3955,0.15075 l 5,0 c -0.0405,-4.8855 -3.1365,-9.344 -8,-10.525 -1.98675,-0.4825 -4.21775,-0.225 -6.25,-0.225 l -11.5,0 z"
+     id="path3602" />
+</svg>
index 3adf606649b0504b94f796d8cc6190b0e2868fc7..d2b5d16a194b0f31d029ca03e8afe6eba0174d49 100644 (file)
    version="1.1"
    id="svg2"
    xml:space="preserve"
-   width="1056"
-   height="816"
-   viewBox="0 0 1056 816"
+   width="885.22382"
+   height="544.16864"
+   viewBox="0 0 885.22382 544.16864"
    sodipodi:docname="lc-icon-black.svg"
-   inkscape:version="0.92.1 r"><metadata
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
      id="metadata8"><rdf:RDF><cc:Work
          rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
      guidetolerance="10"
      inkscape:pageopacity="0"
      inkscape:pageshadow="2"
-     inkscape:window-width="923"
-     inkscape:window-height="480"
+     inkscape:window-width="3840"
+     inkscape:window-height="2031"
      id="namedview4"
      showgrid="false"
-     inkscape:zoom="0.28921569"
-     inkscape:cx="528"
-     inkscape:cy="408"
+     inkscape:zoom="1.1568627"
+     inkscape:cx="1222.0865"
+     inkscape:cy="406.12625"
      inkscape:window-x="0"
-     inkscape:window-y="0"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="g10" /><g
+     inkscape:window-y="55"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g10"
+     fit-margin-top="10"
+     fit-margin-left="10"
+     fit-margin-right="10"
+     fit-margin-bottom="10" /><g
      id="g10"
      inkscape:groupmode="layer"
      inkscape:label="LibraryCarpentryLogo_Draft_04"
-     transform="matrix(1.3333333,0,0,-1.3333333,0,816)"><g
+     transform="matrix(1.3333333,0,0,-1.3333333,-85.388398,680.08465)"><g
        id="g12"><g
          id="g14"
          clip-path="url(#clipPath18)"><g
diff --git a/assets/img/lc-logo-black.png b/assets/img/lc-logo-black.png
new file mode 100644 (file)
index 0000000..5e3d9fe
Binary files /dev/null and b/assets/img/lc-logo-black.png differ
diff --git a/assets/img/lc-logo-black.svg b/assets/img/lc-logo-black.svg
new file mode 100644 (file)
index 0000000..3adf606
--- /dev/null
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="svg2"
+   xml:space="preserve"
+   width="1056"
+   height="816"
+   viewBox="0 0 1056 816"
+   sodipodi:docname="lc-icon-black.svg"
+   inkscape:version="0.92.1 r"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6"><clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath18"><path
+         d="M 0,612 H 792 V 0 H 0 Z"
+         id="path16"
+         inkscape:connector-curvature="0" /></clipPath></defs><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="923"
+     inkscape:window-height="480"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="0.28921569"
+     inkscape:cx="528"
+     inkscape:cy="408"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="g10" /><g
+     id="g10"
+     inkscape:groupmode="layer"
+     inkscape:label="LibraryCarpentryLogo_Draft_04"
+     transform="matrix(1.3333333,0,0,-1.3333333,0,816)"><g
+       id="g12"><g
+         id="g14"
+         clip-path="url(#clipPath18)"><g
+           id="g20"
+           transform="translate(314.9707,239.4268)"><path
+             d="M 0,0 C 8.395,0 13.455,3.795 18.055,7.935 V 21.506 C 6.095,21.391 -9.775,21.391 -9.775,9.431 -9.775,3.335 -6.441,0 0,0 m 18.055,29.786 v 5.405 c 0,5.175 -3.105,9.662 -12.651,9.662 -10.465,0 -16.791,-4.832 -17.94,-4.832 -1.61,0 -4.025,4.486 -4.025,5.751 0,2.991 10.12,7.36 21.621,7.36 14.26,0 22.656,-6.67 22.656,-18.055 V 9.315 c 0,-9.43 1.38,-13.916 1.38,-14.49 0,-2.185 -4.715,-2.646 -6.21,-2.646 -2.761,0 -3.335,4.831 -4.026,8.05 -4.37,-4.83 -10.695,-8.625 -19.321,-8.625 -11.155,0 -19.666,5.406 -19.666,17.251 0,19.436 20.586,20.701 38.182,20.931"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path22"
+             inkscape:connector-curvature="0" /></g><g
+           id="g24"
+           transform="translate(362.2344,274.3887)"><path
+             d="m 0,0 c 0,9.43 -1.381,13.915 -1.381,14.49 0,2.186 4.716,2.645 6.211,2.645 2.76,0 3.336,-4.6 4.025,-7.59 3.911,5.52 8.51,8.625 13.34,8.625 4.487,0 6.671,-1.955 6.671,-4.484 0,-2.186 -0.92,-6.211 -2.3,-6.211 C 25.071,7.475 24.15,8.74 20.24,8.74 14.261,8.74 9.66,1.725 9.66,1.725 v -42.092 c 0,-1.611 -1.38,-2.53 -4.599,-2.53 H 4.6 c -3.22,0 -4.6,0.919 -4.6,2.53 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path26"
+             inkscape:connector-curvature="0" /></g><g
+           id="g28"
+           transform="translate(427.4404,239.541)"><path
+             d="m 0,0 h 0.69 c 9.89,0.23 15.065,7.706 15.065,21.392 0,14.835 -5.06,23.231 -14.145,23.231 -5.06,0 -10.81,-2.761 -15.526,-7.935 V 5.176 C -9.776,1.726 -4.945,0 0,0 m -13.916,-29.211 c 0,-1.609 -1.38,-2.53 -4.601,-2.53 h -0.459 c -3.22,0 -4.6,0.921 -4.6,2.53 v 64.059 c 0,9.429 -1.38,13.915 -1.38,14.49 0,2.185 4.715,2.644 6.21,2.644 2.761,0 3.335,-4.599 4.025,-7.589 5.636,5.865 11.731,8.625 18.286,8.625 13.801,0 22.311,-12.88 22.311,-30.362 v -1.035 c 0,-19.32 -9.66,-30.131 -23.346,-30.131 -7.131,0 -11.961,2.415 -16.446,5.865 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path30"
+             inkscape:connector-curvature="0" /></g><g
+           id="g32"
+           transform="translate(506.4453,266.1074)"><path
+             d="M 0,0 C 0,12.076 -4.6,18.172 -13.801,18.172 -23.806,18.172 -29.096,12.076 -29.9,0 Z m -13.455,26.451 c 15.756,0 23.691,-10.465 23.691,-30.015 0,-1.381 -2.416,-4.715 -3.795,-4.715 H -29.9 c 0.92,-12.766 6.324,-18.517 17.711,-18.517 10.004,0 15.64,4.83 16.79,4.83 1.61,0 4.025,-4.485 4.025,-5.75 0,-2.761 -9.085,-7.36 -20.701,-7.36 -19.091,0 -28.177,9.775 -28.177,30.361 0,20.356 9.201,31.166 26.797,31.166"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path34"
+             inkscape:connector-curvature="0" /></g><g
+           id="g36"
+           transform="translate(531.7422,274.3887)"><path
+             d="m 0,0 c 0,9.43 -1.38,13.915 -1.38,14.49 0,2.186 4.716,2.645 6.21,2.645 2.761,0 3.336,-4.6 4.025,-7.59 4.831,5.405 11.501,8.625 17.942,8.625 11.73,0 18.746,-7.015 18.746,-18.631 v -39.906 c 0,-1.611 -1.381,-2.53 -4.601,-2.53 h -0.46 c -3.22,0 -4.6,0.919 -4.6,2.53 v 38.986 c 0,7.016 -4.255,11.156 -11.731,11.156 -5.174,0 -10.695,-3.105 -14.491,-8.05 v -42.092 c 0,-1.611 -1.379,-2.53 -4.599,-2.53 h -0.46 c -3.22,0 -4.601,0.919 -4.601,2.53 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path38"
+             inkscape:connector-curvature="0" /></g><g
+           id="g40"
+           transform="translate(598.2119,283.5889)"><path
+             d="M 0,0 H -5.751 C -7.36,0 -8.05,1.034 -8.05,3.45 v 1.38 c 0,2.415 0.69,3.45 2.299,3.45 L 0,8.28 1.38,20.356 c 0.115,1.61 1.266,2.53 3.68,2.53 h 1.15 c 2.416,0 3.45,-0.92 3.45,-2.53 V 8.28 h 9.661 c 1.61,0 2.3,-1.035 2.3,-3.45 V 3.45 C 21.621,1.034 20.931,0 19.321,0 H 9.66 v -35.767 c 0,-6.9 2.876,-8.51 6.21,-8.51 3.336,0 3.91,0.575 4.945,0.575 1.611,0 2.416,-4.486 2.416,-5.405 0,-3.106 -5.291,-3.451 -8.396,-3.451 C 9.085,-52.558 0,-50.027 0,-36.687 Z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path42"
+             inkscape:connector-curvature="0" /></g><g
+           id="g44"
+           transform="translate(635.5859,274.3887)"><path
+             d="m 0,0 c 0,9.43 -1.38,13.915 -1.38,14.49 0,2.186 4.716,2.645 6.21,2.645 2.761,0 3.336,-4.6 4.025,-7.59 3.911,5.52 8.511,8.625 13.341,8.625 4.486,0 6.671,-1.955 6.671,-4.484 0,-2.186 -0.92,-6.211 -2.301,-6.211 -1.494,0 -2.415,1.265 -6.325,1.265 C 14.262,8.74 9.66,1.725 9.66,1.725 v -42.092 c 0,-1.611 -1.379,-2.53 -4.599,-2.53 h -0.46 c -3.22,0 -4.601,0.919 -4.601,2.53 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path46"
+             inkscape:connector-curvature="0" /></g><g
+           id="g48"
+           transform="translate(669.7402,288.6484)"><path
+             d="m 0,0 c -0.114,0.346 -0.344,1.035 -0.344,1.496 0,1.15 1.494,1.955 4.945,1.955 h 0.92 c 2.299,0 4.025,-0.461 4.6,-1.841 L 25.762,-39.906 41.057,1.61 c 0.461,1.38 2.3,1.841 4.716,1.841 3.45,0 4.946,-0.69 4.946,-1.955 0,-0.461 -0.115,-0.92 -0.346,-1.611 L 20.816,-78.434 c -0.689,-1.724 -2.644,-2.415 -5.404,-2.415 h -1.726 c -2.53,0 -3.795,0.691 -3.795,1.841 0,0.69 0.23,0.92 10.236,25.301 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path50"
+             inkscape:connector-curvature="0" /></g><g
+           id="g52"
+           transform="translate(173.6738,440.5723)"><path
+             d="m 0,0 c 0,1.609 1.381,2.529 4.602,2.529 h 0.459 c 3.22,0 4.6,-0.92 4.6,-2.529 v -55.548 c 0,-1.61 -1.38,-2.53 -4.6,-2.53 H 4.602 c -3.221,0 -4.602,0.92 -4.602,2.53 z m -0.459,19.32 v 6.785 c 0,1.611 1.38,2.531 4.6,2.531 h 1.38 c 3.22,0 4.6,-0.92 4.6,-2.531 V 19.32 c 0,-1.609 -1.38,-2.529 -4.6,-2.529 h -1.38 c -3.22,0 -4.6,0.92 -4.6,2.529"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path54"
+             inkscape:connector-curvature="0" /></g><g
+           id="g56"
+           transform="translate(228.6465,390.4297)"><path
+             d="m 0,0 c 9.084,0 14.145,8.395 14.145,23.23 0,13.686 -5.175,21.163 -15.066,21.392 h -0.69 c -4.946,0 -9.776,-1.726 -13.915,-5.175 V 7.936 C -10.811,2.76 -5.061,0 0,0 m -25.188,76.248 c 0,1.61 1.381,2.53 4.601,2.53 h 0.46 c 3.221,0 4.601,-0.92 4.601,-2.53 v -28.98 c 4.485,3.449 9.315,5.865 16.446,5.865 13.685,0 23.346,-10.811 23.346,-30.132 v -1.035 c 0,-17.482 -8.511,-30.362 -22.311,-30.362 -6.557,0 -12.651,2.761 -18.287,8.626 -0.805,-4.025 -1.84,-6.786 -1.84,-6.786 -0.46,-1.034 -1.494,-1.38 -3.105,-1.38 h -0.459 c -2.416,0 -3.452,0.92 -3.452,2.531 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path58"
+             inkscape:connector-curvature="0" /></g><g
+           id="g60"
+           transform="translate(269.4678,425.3906)"><path
+             d="m 0,0 c 0,9.432 -1.38,13.916 -1.38,14.491 0,2.185 4.715,2.646 6.21,2.646 2.761,0 3.335,-4.601 4.025,-7.591 3.911,5.52 8.511,8.626 13.341,8.626 4.485,0 6.67,-1.955 6.67,-4.486 0,-2.185 -0.92,-6.209 -2.3,-6.209 -1.495,0 -2.415,1.263 -6.325,1.263 C 14.261,8.74 9.66,1.726 9.66,1.726 v -42.092 c 0,-1.611 -1.38,-2.53 -4.6,-2.53 H 4.601 C 1.38,-42.896 0,-41.977 0,-40.366 Z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path62"
+             inkscape:connector-curvature="0" /></g><g
+           id="g64"
+           transform="translate(326.9688,390.4297)"><path
+             d="m 0,0 c 8.395,0 13.455,3.795 18.055,7.936 v 13.57 C 6.095,21.391 -9.775,21.391 -9.775,9.43 -9.775,3.335 -6.441,0 0,0 m 18.055,29.786 v 5.405 c 0,5.176 -3.105,9.661 -12.651,9.661 -10.465,0 -16.791,-4.831 -17.94,-4.831 -1.61,0 -4.025,4.486 -4.025,5.75 0,2.991 10.12,7.362 21.621,7.362 14.26,0 22.656,-6.671 22.656,-18.057 V 9.315 c 0,-9.43 1.38,-13.916 1.38,-14.491 0,-2.184 -4.715,-2.644 -6.21,-2.644 -2.761,0 -3.335,4.83 -4.026,8.05 -4.37,-4.831 -10.695,-8.626 -19.321,-8.626 -11.155,0 -19.666,5.406 -19.666,17.251 0,19.436 20.586,20.702 38.182,20.931"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path66"
+             inkscape:connector-curvature="0" /></g><g
+           id="g68"
+           transform="translate(374.2324,425.3906)"><path
+             d="m 0,0 c 0,9.432 -1.381,13.916 -1.381,14.491 0,2.185 4.716,2.646 6.211,2.646 2.76,0 3.336,-4.601 4.025,-7.591 3.911,5.52 8.51,8.626 13.34,8.626 4.487,0 6.671,-1.955 6.671,-4.486 0,-2.185 -0.92,-6.209 -2.3,-6.209 C 25.071,7.477 24.15,8.74 20.24,8.74 14.261,8.74 9.66,1.726 9.66,1.726 v -42.092 c 0,-1.611 -1.38,-2.53 -4.599,-2.53 H 4.6 c -3.22,0 -4.6,0.919 -4.6,2.53 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path70"
+             inkscape:connector-curvature="0" /></g><g
+           id="g72"
+           transform="translate(408.3867,439.6523)"><path
+             d="m 0,0 c -0.115,0.345 -0.345,1.035 -0.345,1.494 0,1.151 1.495,1.955 4.945,1.955 h 0.921 c 2.299,0 4.024,-0.459 4.6,-1.84 L 25.762,-39.907 41.057,1.609 c 0.461,1.381 2.3,1.84 4.715,1.84 3.451,0 4.945,-0.689 4.945,-1.955 0,-0.459 -0.114,-0.92 -0.344,-1.609 L 20.816,-78.434 c -0.69,-1.725 -2.645,-2.416 -5.406,-2.416 h -1.724 c -2.53,0 -3.795,0.691 -3.795,1.84 0,0.691 0.23,0.92 10.235,25.302 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path74"
+             inkscape:connector-curvature="0" /></g><g
+           id="g76"
+           transform="translate(268.1396,298.084)"><path
+             d="m 0,0 h -46.771 v -23.824 l 20.206,0.731 c 0,0 18.242,-2.564 26.565,23.093"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path78"
+             inkscape:connector-curvature="0" /></g><g
+           id="g80"
+           transform="translate(186.2686,298.084)"><path
+             d="m 0,0 h -42.728 v -25.971 c 9.594,-3.48 13.341,-10.605 25.592,-10.605 9.515,0 13.448,2.511 17.136,5.279 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path82"
+             inkscape:connector-curvature="0" /></g><g
+           id="g84"
+           transform="translate(209.8252,213.8242)"><path
+             d="m 0,0 c 0,-4.353 -2.758,-7.882 -6.156,-7.882 -3.4,0 -6.157,3.529 -6.157,7.882 v 88.789 c 0,4.357 2.757,7.885 6.157,7.885 3.398,0 6.156,-3.528 6.156,-7.885 z m 97.275,115.246 h -2.406 v 5.904 c 0.123,0.248 0.2,0.528 0.2,0.827 v 24.638 c 0,1 -0.78,1.811 -1.744,1.811 H 20.678 c -0.499,0.054 -0.99,-0.082 -1.342,-0.432 l -39.469,-39.023 c -0.385,-0.381 -0.516,-0.926 -0.424,-1.473 V -14.907 c 0,-0.786 0.368,-1.451 0.879,-1.705 l 37.85,-37.372 c 0.118,-0.117 0.256,-0.2 0.402,-0.267 0.25,-0.142 0.533,-0.23 0.84,-0.23 h 54.664 v -1.984 c 0,-1.01 0.798,-1.828 1.783,-1.828 h 16.87 c 0.986,0 1.784,0.818 1.784,1.828 v 32.827 c 0,1.011 -0.798,1.828 -1.784,1.828 h -16.87 c -0.985,0 -1.783,-0.817 -1.783,-1.828 v -2.586 H 30.566 L 8.307,-4.243 V 97.994 l 22.425,22.172 h 35.677 v -4.92 h -2.608 c -1.039,0 -1.881,-0.779 -1.881,-1.744 v -5.291 c 0,-0.965 0.842,-1.744 1.881,-1.744 h 33.474 c 1.038,0 1.883,0.779 1.883,1.744 v 5.291 c 0,0.965 -0.845,1.744 -1.883,1.744"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path86"
+             inkscape:connector-curvature="0" /></g><g
+           id="g88"
+           transform="translate(130.4912,285.0215)"><path
+             d="m 0,0 c 0,-3.017 -2.265,-5.463 -5.058,-5.463 -2.793,0 -5.056,2.446 -5.056,5.463 0,3.016 2.263,5.461 5.056,5.461 C -2.265,5.461 0,3.016 0,0 m 10.128,209.072 v 8.47 H -20.243 V -25.936 h 30.371 v 64.17 H 2.394 v 5.678 h 7.734 V 61.827 H -2.553 v 5.679 H 10.128 V 85.421 H 2.394 v 5.681 h 7.734 v 17.914 H -2.553 v 5.679 h 12.681 v 17.914 H 2.394 v 5.68 h 7.734 v 17.914 H -2.553 v 5.68 h 12.681 v 17.914 H 2.394 v 5.681 h 7.734 v 17.916 H -2.553 v 5.678 z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path90"
+             inkscape:connector-curvature="0" /></g><g
+           id="g92"
+           transform="translate(107.7373,298.084)"><path
+             d="m 0,0 h -36.196 c 9.542,-26.602 27.375,-23.093 27.375,-23.093 L 0,-23.428 Z"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path94"
+             inkscape:connector-curvature="0" /></g><g
+           id="g96"
+           transform="translate(331.3496,127.376)"><path
+             d="m 0,0 h -16.679 c -0.957,0 -1.731,-0.771 -1.731,-1.726 V -2.75 h -11.653 v 5.289 c 0,1.065 -0.859,1.927 -1.918,1.927 h -1.387 v 20.79 h -8.378 V 4.466 h -1.386 c -1.06,0 -1.918,-0.862 -1.918,-1.927 V -2.75 h -37.023 l 0.01,0.706 c 0,0.69 -0.654,2.1 -1.276,2.1 h -0.994 v 0.019 l -6.413,-0.001 v -13.827 l 3.643,10e-4 c 0.114,-0.043 0.231,-0.08 0.358,-0.08 h 3.406 c 0.622,0 1.123,0.56 1.123,1.25 l 0.035,2.363 h 37.131 v -5.794 c 0,-1.064 0.858,-1.926 1.918,-1.926 h 11.151 c 1.059,0 1.918,0.862 1.918,1.926 v 5.794 h 11.653 v -1.529 c 0,-0.954 0.774,-1.726 1.731,-1.726 H 0 c 0.956,0 1.731,0.772 1.731,1.726 V -1.726 C 1.731,-0.771 0.956,0 0,0"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path98"
+             inkscape:connector-curvature="0" /></g><g
+           id="g100"
+           transform="translate(285.8154,217.1611)"><path
+             d="m 0,0 h 3.998 v -21.466 h 8.919 V 0 h 3.999 c 1.023,0 1.855,0.781 1.855,1.745 v 5.292 c 0,0.088 -0.014,0.174 -0.027,0.258 V 9.589 H -1.828 V 7.295 C -1.842,7.211 -1.855,7.125 -1.855,7.037 V 1.745 C -1.855,0.781 -1.025,0 0,0"
+             style="fill:#7b7979;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             id="path102"
+             inkscape:connector-curvature="0" /></g></g></g></g></svg>
\ No newline at end of file
diff --git a/bin/boilerplate/.travis.yml b/bin/boilerplate/.travis.yml
new file mode 100644 (file)
index 0000000..d30f78a
--- /dev/null
@@ -0,0 +1,23 @@
+# dist: trusty  # Ubuntu 14.04
+language: python
+python: 3.6
+branches:
+  only:
+  - gh-pages
+  - /.*/
+before_install:
+  - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
+  - echo "deb https://cran.rstudio.com/bin/linux/ubuntu trusty/" | sudo tee -a /etc/apt/sources.list
+  - sudo apt-get update -y
+  - sudo apt-get install -y r-base
+  - sudo Rscript -e "install.packages('knitr', repos = 'https://', dependencies = TRUE)"
+  - sudo Rscript -e "install.packages('stringr', repos = 'https://cran.rstudio.com', dependencies = TRUE)"
+  - sudo Rscript -e "install.packages('checkpoint', repos = 'https://cran.rstudio.com', dependencies = TRUE)"
+  - sudo Rscript -e "install.packages('ggplot2', repos = 'https://cran.rstudio.com', dependencies = TRUE)"
+  - rvm default
+  - gem install json kramdown jekyll
+install:
+  - pip install pyyaml
+script:
+  - make lesson-check-all
+  - make --always-make site
diff --git a/bin/boilerplate/AUTHORS b/bin/boilerplate/AUTHORS
new file mode 100644 (file)
index 0000000..04e1f5a
--- /dev/null
@@ -0,0 +1 @@
+FIXME: list authors' names and email addresses.
\ No newline at end of file
diff --git a/bin/boilerplate/CITATION b/bin/boilerplate/CITATION
new file mode 100644 (file)
index 0000000..56ece3c
--- /dev/null
@@ -0,0 +1 @@
+FIXME: describe how to cite this lesson.
\ No newline at end of file
diff --git a/bin/boilerplate/CODE_OF_CONDUCT.md b/bin/boilerplate/CODE_OF_CONDUCT.md
new file mode 100644 (file)
index 0000000..c3b9669
--- /dev/null
@@ -0,0 +1,11 @@
+---
+layout: page
+title: "Contributor Code of Conduct"
+---
+As contributors and maintainers of this project,
+we pledge to follow the [Carpentry Code of Conduct][coc].
+
+Instances of abusive, harassing, or otherwise unacceptable behavior
+may be reported by following our [reporting guidelines][coc-reporting].
+
+{% include links.md %}
diff --git a/bin/boilerplate/CONTRIBUTING.md b/bin/boilerplate/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..63d53e8
--- /dev/null
@@ -0,0 +1,148 @@
+# Contributing
+
+[Software Carpentry][swc-site] and [Data Carpentry][dc-site] are open source projects,
+and we welcome contributions of all kinds:
+new lessons,
+fixes to existing material,
+bug reports,
+and reviews of proposed changes are all welcome.
+
+## Contributor Agreement
+
+By contributing,
+you agree that we may redistribute your work under [our license](LICENSE.md).
+In exchange,
+we will address your issues and/or assess your change proposal as promptly as we can,
+and help you become a member of our community.
+Everyone involved in [Software Carpentry][swc-site] and [Data Carpentry][dc-site]
+agrees to abide by our [code of conduct](CODE_OF_CONDUCT.md).
+
+## How to Contribute
+
+The easiest way to get started is to file an issue
+to tell us about a spelling mistake,
+some awkward wording,
+or a factual error.
+This is a good way to introduce yourself
+and to meet some of our community members.
+
+1.  If you do not have a [GitHub][github] account,
+    you can [send us comments by email][email].
+    However,
+    we will be able to respond more quickly if you use one of the other methods described below.
+
+2.  If you have a [GitHub][github] account,
+    or are willing to [create one][github-join],
+    but do not know how to use Git,
+    you can report problems or suggest improvements by [creating an issue][issues].
+    This allows us to assign the item to someone
+    and to respond to it in a threaded discussion.
+
+3.  If you are comfortable with Git,
+    and would like to add or change material,
+    you can submit a pull request (PR).
+    Instructions for doing this are [included below](#using-github).
+
+## Where to Contribute
+
+1.  If you wish to change this lesson,
+    please work in <https://github.com/swcarpentry/FIXME>,
+    which can be viewed at <https://swcarpentry.github.io/FIXME>.
+
+2.  If you wish to change the example lesson,
+    please work in <https://github.com/carpentries/lesson-example>,
+    which documents the format of our lessons
+    and can be viewed at <https://carpentries.github.io/lesson-example>.
+
+3.  If you wish to change the template used for workshop websites,
+    please work in <https://github.com/carpentries/workshop-template>.
+    The home page of that repository explains how to set up workshop websites,
+    while the extra pages in <https://carpentries.github.io/workshop-template>
+    provide more background on our design choices.
+
+4.  If you wish to change CSS style files, tools,
+    or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`,
+    please work in <https://github.com/carpentries/styles>.
+
+## What to Contribute
+
+There are many ways to contribute,
+from writing new exercises and improving existing ones
+to updating or filling in the documentation
+and submitting [bug reports][issues]
+about things that don't work, aren't clear, or are missing.
+If you are looking for ideas, please see the 'Issues' tab for
+a list of issues associated with this repository,
+or you may also look at the issues for [Data Carpentry][dc-issues]
+and [Software Carpentry][swc-issues] projects.
+
+Comments on issues and reviews of pull requests are just as welcome:
+we are smarter together than we are on our own.
+Reviews from novices and newcomers are particularly valuable:
+it's easy for people who have been using these lessons for a while
+to forget how impenetrable some of this material can be,
+so fresh eyes are always welcome.
+
+## What *Not* to Contribute
+
+Our lessons already contain more material than we can cover in a typical workshop,
+so we are usually *not* looking for more concepts or tools to add to them.
+As a rule,
+if you want to introduce a new idea,
+you must (a) estimate how long it will take to teach
+and (b) explain what you would take out to make room for it.
+The first encourages contributors to be honest about requirements;
+the second, to think hard about priorities.
+
+We are also not looking for exercises or other material that only run on one platform.
+Our workshops typically contain a mixture of Windows, Mac OS X, and Linux users;
+in order to be usable,
+our lessons must run equally well on all three.
+
+## Using GitHub
+
+If you choose to contribute via GitHub, you may want to look at
+[How to Contribute to an Open Source Project on GitHub][how-contribute].
+To manage changes, we follow [GitHub flow][github-flow].
+Each lesson has two maintainers who review issues and pull requests or encourage others to do so.
+The maintainers are community volunteers and have final say over what gets merged into the lesson.
+To use the web interface for contributing to a lesson:
+
+1.  Fork the originating repository to your GitHub profile.
+2.  Within your version of the forked repository, move to the `gh-pages` branch and
+create a new branch for each significant change being made.
+3.  Navigate to the file(s) you wish to change within the new branches and make revisions as required.
+4.  Commit all changed files within the appropriate branches.
+5.  Create individual pull requests from each of your changed branches
+to the `gh-pages` branch within the originating repository.
+6.  If you receive feedback, make changes using your issue-specific branches of the forked
+repository and the pull requests will update automatically.
+7.  Repeat as needed until all feedback has been addressed.
+
+When starting work, please make sure your clone of the originating `gh-pages` branch is up-to-date
+before creating your own revision-specific branch(es) from there.
+Additionally, please only work from your newly-created branch(es) and *not*
+your clone of the originating `gh-pages` branch.
+Lastly, published copies of all the lessons are available in the `gh-pages` branch of the originating
+repository for reference while revising.
+
+## Other Resources
+
+General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-site]
+happens on the [discussion mailing list][discuss-list],
+which everyone is welcome to join.
+You can also [reach us by email][email].
+
+[email]: mailto:admin@software-carpentry.org
+[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry
+[dc-lessons]: http://datacarpentry.org/lessons/
+[dc-site]: http://datacarpentry.org/
+[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss
+[github]: https://github.com
+[github-flow]: https://guides.github.com/introduction/flow/
+[github-join]: https://github.com/join
+[how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
+[issues]: https://guides.github.com/features/issues/
+[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry
+[swc-lessons]: https://software-carpentry.org/lessons/
+[swc-site]: https://software-carpentry.org/
diff --git a/bin/boilerplate/README.md b/bin/boilerplate/README.md
new file mode 100644 (file)
index 0000000..43a6b72
--- /dev/null
@@ -0,0 +1,28 @@
+# FIXME Lesson title
+
+[![Create a Slack Account with us](https://img.shields.io/badge/Create_Slack_Account-The_Carpentries-071159.svg)](https://swc-slack-invite.herokuapp.com/)
+
+FIXME
+
+## Contributing
+
+We welcome all contributions to improve the lesson! Maintainers will do their best to help you if you have any
+questions, concerns, or experience any difficulties along the way.
+
+We'd like to ask you to familiarize yourself with our [Contribution Guide](CONTRIBUTING.md) and have a look at
+the [more detailed guidelines][lesson-example] on proper formatting, ways to render the lesson locally, and even
+how to write new episodes.
+
+## Maintainer(s)
+
+* FIXME
+
+## Authors
+
+A list of contributors to the lesson can be found in [AUTHORS](AUTHORS)
+
+## Citation
+
+To cite this lesson, please consult with [CITATION](CITATION)
+
+[lesson-example]: https://carpentries.github.io/lesson-example
diff --git a/bin/boilerplate/_config.yml b/bin/boilerplate/_config.yml
new file mode 100644 (file)
index 0000000..a62f808
--- /dev/null
@@ -0,0 +1,89 @@
+#------------------------------------------------------------
+# Values for this lesson.
+#------------------------------------------------------------
+
+# Which carpentry is this ("swc", "dc", "lc", or "cp")?
+# swc: Software Carpentry
+# dc: Data Carpentry
+# lc: Library Carpentry
+# cp: Carpentries (to use for instructor traning for instance)
+carpentry: "swc"
+
+# Overall title for pages.
+title: "Lesson Title"
+
+#------------------------------------------------------------
+# Generic settings (should not need to change).
+#------------------------------------------------------------
+
+# What kind of thing is this ("workshop" or "lesson")?
+kind: "lesson"
+
+# Magic to make URLs resolve both locally and on GitHub.
+# See https://help.github.com/articles/repository-metadata-on-github-pages/.
+# Please don't change it: <USERNAME>/<PROJECT> is correct.
+repository: <USERNAME>/<PROJECT>
+
+# Email address, no mailto:
+email: "team@carpentries.org"
+
+# Sites.
+amy_site: "https://amy.software-carpentry.org/workshops"
+carpentries_github: "https://github.com/carpentries"
+carpentries_pages: "https://carpentries.github.io"
+carpentries_site: "https://carpentries.org/"
+dc_site: "http://datacarpentry.org"
+example_repo: "https://github.com/carpentries/lesson-example"
+example_site: "https://carpentries.github.io/lesson-example"
+lc_site: "https://librarycarpentry.github.io/"
+swc_github: "https://github.com/swcarpentry"
+swc_pages: "https://swcarpentry.github.io"
+swc_site: "https://software-carpentry.org"
+template_repo: "https://github.com/carpentries/styles"
+training_site: "https://carpentries.github.io/instructor-training"
+workshop_repo: "https://github.com/carpentries/workshop-template"
+workshop_site: "https://carpentries.github.io/workshop-template"
+
+# Surveys.
+pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id="
+post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id="
+training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training"
+
+# Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am).
+start_time: 0
+
+# Specify that things in the episodes collection should be output.
+collections:
+  episodes:
+    output: true
+    permalink: /:path/index.html
+  extras:
+    output: true
+    permalink: /:path/index.html
+
+# Set the default layout for things in the episodes collection.
+defaults:
+  - values:
+      root: .
+      layout: page
+  - scope:
+      path: ""
+      type: episodes
+    values:
+      root: ..
+      layout: episode
+  - scope:
+      path: ""
+      type: extras
+    values:
+      root: ..
+      layout: page
+
+# Files and directories that are not to be copied.
+exclude:
+  - Makefile
+  - bin/
+  - .Rproj.user/
+
+# Turn on built-in syntax highlighting.
+highlighter: rouge
diff --git a/bin/boilerplate/_episodes/01-introduction.md b/bin/boilerplate/_episodes/01-introduction.md
new file mode 100644 (file)
index 0000000..fcfdda1
--- /dev/null
@@ -0,0 +1,14 @@
+---
+title: "Introduction"
+teaching: 0
+exercises: 0
+questions:
+- "Key question (FIXME)"
+objectives:
+- "First objective. (FIXME)"
+keypoints:
+- "First key point. (FIXME)"
+---
+FIXME
+
+{% include links.md %}
diff --git a/bin/boilerplate/_extras/about.md b/bin/boilerplate/_extras/about.md
new file mode 100644 (file)
index 0000000..5f07f65
--- /dev/null
@@ -0,0 +1,5 @@
+---
+title: About
+---
+{% include carpentries.html %}
+{% include links.md %}
diff --git a/bin/boilerplate/_extras/discuss.md b/bin/boilerplate/_extras/discuss.md
new file mode 100644 (file)
index 0000000..bfc33c5
--- /dev/null
@@ -0,0 +1,6 @@
+---
+title: Discussion
+---
+FIXME
+
+{% include links.md %}
diff --git a/bin/boilerplate/_extras/figures.md b/bin/boilerplate/_extras/figures.md
new file mode 100644 (file)
index 0000000..c1511e8
--- /dev/null
@@ -0,0 +1,40 @@
+---
+title: Figures
+---
+<script>
+  window.onload = function() {
+    var lesson_episodes = [
+    {% for episode in site.episodes %}
+    "{{ episode.url}}"{% unless forloop.last %},{% endunless %}
+    {% endfor %}
+    ];
+    var xmlHttp = [];  /* Required since we are going to query every episode. */
+    for (i=0; i < lesson_episodes.length; i++) {
+      xmlHttp[i] = new XMLHttpRequest();
+      xmlHttp[i].episode = lesson_episodes[i];  /* To enable use this later. */
+      xmlHttp[i].onreadystatechange = function() {
+        if (this.readyState == 4 && this.status == 200) {
+          var article_here = document.getElementById(this.episode);
+          var parser = new DOMParser();
+          var htmlDoc = parser.parseFromString(this.responseText,"text/html");
+          var htmlDocArticle = htmlDoc.getElementsByTagName("article")[0];
+          article_here.appendChild(htmlDocArticle.getElementsByTagName("h1")[0]);
+          for (let image of htmlDocArticle.getElementsByTagName("img")) {
+            article_here.appendChild(image);
+          }
+        }
+      }
+      episode_url = "{{ page.root }}" + lesson_episodes[i];
+      xmlHttp[i].open("GET", episode_url);
+      xmlHttp[i].send(null);
+    }
+  }
+</script>
+{% comment %}
+Create anchor for each one of the episodes.
+{% endcomment %}
+{% for episode in site.episodes %}
+<article id="{{ episode.url }}"></article>
+{% endfor %}
+
+{% include links.md %}
diff --git a/bin/boilerplate/_extras/guide.md b/bin/boilerplate/_extras/guide.md
new file mode 100644 (file)
index 0000000..50f266f
--- /dev/null
@@ -0,0 +1,6 @@
+---
+title: "Instructor Notes"
+---
+FIXME
+
+{% include links.md %}
diff --git a/bin/boilerplate/aio.md b/bin/boilerplate/aio.md
new file mode 100644 (file)
index 0000000..a418f3b
--- /dev/null
@@ -0,0 +1,34 @@
+---
+---
+<script>
+  window.onload = function() {
+    var lesson_episodes = [
+    {% for episode in site.episodes %}
+    "{{ episode.url}}"{% unless forloop.last %},{% endunless %}
+    {% endfor %}
+    ];
+    var xmlHttp = [];  /* Required since we are going to query every episode. */
+    for (i=0; i < lesson_episodes.length; i++) {
+      xmlHttp[i] = new XMLHttpRequest();
+      xmlHttp[i].episode = lesson_episodes[i];  /* To enable use this later. */
+      xmlHttp[i].onreadystatechange = function() {
+      if (this.readyState == 4 && this.status == 200) {
+        var article_here = document.getElementById(this.episode);
+        var parser = new DOMParser();
+        var htmlDoc = parser.parseFromString(this.responseText,"text/html");
+        var htmlDocArticle = htmlDoc.getElementsByTagName("article")[0];
+        article_here.innerHTML = htmlDocArticle.innerHTML;
+        }
+      }
+      episode_url = "{{ page.root }}" + lesson_episodes[i];
+      xmlHttp[i].open("GET", episode_url);
+      xmlHttp[i].send(null);
+    }
+  }
+</script>
+{% comment %}
+Create anchor for each one of the episodes.
+{% endcomment %}
+{% for episode in site.episodes %}
+<article id="{{ episode.url }}"></article>
+{% endfor %}
diff --git a/bin/boilerplate/index.md b/bin/boilerplate/index.md
new file mode 100644 (file)
index 0000000..7fb812c
--- /dev/null
@@ -0,0 +1,13 @@
+---
+layout: lesson
+root: .  # Is the only page that don't follow the partner /:path/index.html
+permalink: index.html  # Is the only page that don't follow the partner /:path/index.html
+---
+FIXME: home page introduction
+
+> ## Prerequisites
+>
+> FIXME
+{: .prereq}
+
+{% include links.md %}
diff --git a/bin/boilerplate/reference.md b/bin/boilerplate/reference.md
new file mode 100644 (file)
index 0000000..8c82616
--- /dev/null
@@ -0,0 +1,9 @@
+---
+layout: reference
+---
+
+## Glossary
+
+FIXME
+
+{% include links.md %}
diff --git a/bin/boilerplate/setup.md b/bin/boilerplate/setup.md
new file mode 100644 (file)
index 0000000..b8c5032
--- /dev/null
@@ -0,0 +1,7 @@
+---
+title: Setup
+---
+FIXME
+
+
+{% include links.md %}
index 66f6310c0d41e415c83d50e38a0b1aba92ee0d9f..8ed1bf89f594a8db28f1dc76ae5d7c3eab06c9f6 100755 (executable)
@@ -1,18 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Check lesson files and their contents.
 """
 
-from __future__ import print_function
-import sys
+
 import os
 import glob
-import json
 import re
-from optparse import OptionParser
+from argparse import ArgumentParser
 
-from util import Reporter, read_markdown, load_yaml, check_unwanted_files, require, IMAGE_FILE_SUFFIX
+from util import (Reporter, read_markdown, load_yaml, check_unwanted_files,
+                  require)
 
 __version__ = '0.3'
 
@@ -23,10 +22,11 @@ SOURCE_DIRS = ['', '_episodes', '_extras']
 # FIXME: We do not yet validate whether any files have the required
 #   YAML headers, but should in the future.
 # The '%' is replaced with the source directory path for checking.
-# Episodes are handled specially, and extra files in '_extras' are also handled specially.
-# This list must include all the Markdown files listed in the 'bin/initialize' script.
+# Episodes are handled specially, and extra files in '_extras' are also handled
+# specially. This list must include all the Markdown files listed in the
+# 'bin/initialize' script.
 REQUIRED_FILES = {
-    '%/CONDUCT.md': True,
+    '%/CODE_OF_CONDUCT.md': True,
     '%/CONTRIBUTING.md': False,
     '%/LICENSE.md': True,
     '%/README.md': False,
@@ -101,6 +101,7 @@ BREAK_METADATA_FIELDS = {
 # How long are lines allowed to be?
 MAX_LINE_LEN = 100
 
+
 def main():
     """Main driver."""
 
@@ -110,43 +111,50 @@ def main():
     args.references = read_references(args.reporter, args.reference_path)
 
     docs = read_all_markdown(args.source_dir, args.parser)
-    check_fileset(args.source_dir, args.reporter, docs.keys())
+    check_fileset(args.source_dir, args.reporter, list(docs.keys()))
     check_unwanted_files(args.source_dir, args.reporter)
-    for filename in docs.keys():
+    for filename in list(docs.keys()):
         checker = create_checker(args, filename, docs[filename])
         checker.check()
 
     args.reporter.report()
+    if args.reporter.messages and not args.permissive:
+        exit(1)
 
 
 def parse_args():
     """Parse command-line arguments."""
 
-    parser = OptionParser()
-    parser.add_option('-l', '--linelen',
-                      default=False,
-                      action="store_true",
-                      dest='line_lengths',
-                      help='Check line lengths')
-    parser.add_option('-p', '--parser',
-                      default=None,
-                      dest='parser',
-                      help='path to Markdown parser')
-    parser.add_option('-r', '--references',
-                      default=None,
-                      dest='reference_path',
-                      help='path to Markdown file of external references')
-    parser.add_option('-s', '--source',
-                      default=os.curdir,
-                      dest='source_dir',
-                      help='source directory')
-    parser.add_option('-w', '--whitespace',
-                      default=False,
-                      action="store_true",
-                      dest='trailing_whitespace',
-                      help='Check for trailing whitespace')
-
-    args, extras = parser.parse_args()
+    parser = ArgumentParser(description="""Check episode files in a lesson.""")
+    parser.add_argument('-l', '--linelen',
+                        default=False,
+                        action="store_true",
+                        dest='line_lengths',
+                        help='Check line lengths')
+    parser.add_argument('-p', '--parser',
+                        default=None,
+                        dest='parser',
+                        help='path to Markdown parser')
+    parser.add_argument('-r', '--references',
+                        default=None,
+                        dest='reference_path',
+                        help='path to Markdown file of external references')
+    parser.add_argument('-s', '--source',
+                        default=os.curdir,
+                        dest='source_dir',
+                        help='source directory')
+    parser.add_argument('-w', '--whitespace',
+                        default=False,
+                        action="store_true",
+                        dest='trailing_whitespace',
+                        help='Check for trailing whitespace')
+    parser.add_argument('--permissive',
+                        default=False,
+                        action="store_true",
+                        dest='permissive',
+                        help='Do not raise an error even if issues are detected')
+
+    args, extras = parser.parse_known_args()
     require(args.parser is not None,
             'Path to Markdown parser not provided')
     require(not extras,
@@ -160,14 +168,21 @@ def check_config(reporter, source_dir):
 
     config_file = os.path.join(source_dir, '_config.yml')
     config = load_yaml(config_file)
-    reporter.check_field(config_file, 'configuration', config, 'kind', 'lesson')
-    reporter.check_field(config_file, 'configuration', config, 'carpentry', ('swc', 'dc', 'lc'))
+    reporter.check_field(config_file, 'configuration',
+                         config, 'kind', 'lesson')
+    reporter.check_field(config_file, 'configuration',
+                         config, 'carpentry', ('swc', 'dc', 'lc', 'cp'))
     reporter.check_field(config_file, 'configuration', config, 'title')
     reporter.check_field(config_file, 'configuration', config, 'email')
 
-    reporter.check({'values': {'root': '..'}} in config.get('defaults', []),
+    for defaults in [
+            {'values': {'root': '.', 'layout': 'page'}},
+            {'values': {'root': '..', 'layout': 'episode'}, 'scope': {'type': 'episodes', 'path': ''}},
+            {'values': {'root': '..', 'layout': 'page'}, 'scope': {'type': 'extras', 'path': ''}}
+            ]:
+        reporter.check(defaults in config.get('defaults', []),
                    'configuration',
-                   '"root" not set to ".." in configuration')
+                   '"root" not set to "." in configuration')
 
 
 def read_references(reporter, ref_path):
@@ -235,17 +250,17 @@ def check_fileset(source_dir, reporter, filenames_present):
         if m and m.group(1):
             seen.append(m.group(1))
         else:
-            reporter.add(None, 'Episode {0} has badly-formatted filename', filename)
+            reporter.add(
+                None, 'Episode {0} has badly-formatted filename', filename)
 
     # Check for duplicate episode numbers.
     reporter.check(len(seen) == len(set(seen)),
-                        None,
-                        'Duplicate episode numbers {0} vs {1}',
-                        sorted(seen), sorted(set(seen)))
+                   None,
+                   'Duplicate episode numbers {0} vs {1}',
+                   sorted(seen), sorted(set(seen)))
 
     # Check that numbers are consecutive.
-    seen = [int(s) for s in seen]
-    seen.sort()
+    seen = sorted([int(s) for s in seen])
     clean = True
     for i in range(len(seen) - 1):
         clean = clean and ((seen[i+1] - seen[i]) == 1)
@@ -261,17 +276,16 @@ def create_checker(args, filename, info):
     for (pat, cls) in CHECKERS:
         if pat.search(filename):
             return cls(args, filename, **info)
+    return NotImplemented
 
-
-class CheckBase(object):
+class CheckBase:
     """Base class for checking Markdown files."""
 
     def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
         """Cache arguments for checking."""
 
-        super(CheckBase, self).__init__()
         self.args = args
-        self.reporter = self.args.reporter # for convenience
+        self.reporter = self.args.reporter  # for convenience
         self.filename = filename
         self.metadata = metadata
         self.metadata_len = metadata_len
@@ -281,7 +295,6 @@ class CheckBase(object):
 
         self.layout = None
 
-
     def check(self):
         """Run tests."""
 
@@ -292,7 +305,6 @@ class CheckBase(object):
         self.check_codeblock_classes()
         self.check_defined_link_references()
 
-
     def check_metadata(self):
         """Check the YAML metadata."""
 
@@ -301,53 +313,51 @@ class CheckBase(object):
                             'Missing metadata entirely')
 
         if self.metadata and (self.layout is not None):
-            self.reporter.check_field(self.filename, 'metadata', self.metadata, 'layout', self.layout)
-
+            self.reporter.check_field(
+                self.filename, 'metadata', self.metadata, 'layout', self.layout)
 
     def check_line_lengths(self):
         """Check the raw text of the lesson body."""
 
         if self.args.line_lengths:
-            over = [i for (i, l, n) in self.lines if (n > MAX_LINE_LEN) and (not l.startswith('!'))]
+            over = [i for (i, l, n) in self.lines if (
+                n > MAX_LINE_LEN) and (not l.startswith('!'))]
             self.reporter.check(not over,
                                 self.filename,
                                 'Line(s) are too long: {0}',
                                 ', '.join([str(i) for i in over]))
 
-
     def check_trailing_whitespace(self):
         """Check for whitespace at the ends of lines."""
 
         if self.args.trailing_whitespace:
-            trailing = [i for (i, l, n) in self.lines if P_TRAILING_WHITESPACE.match(l)]
+            trailing = [
+                i for (i, l, n) in self.lines if P_TRAILING_WHITESPACE.match(l)]
             self.reporter.check(not trailing,
                                 self.filename,
                                 'Line(s) end with whitespace: {0}',
                                 ', '.join([str(i) for i in trailing]))
 
-
     def check_blockquote_classes(self):
         """Check that all blockquotes have known classes."""
 
-        for node in self.find_all(self.doc, {'type' : 'blockquote'}):
+        for node in self.find_all(self.doc, {'type': 'blockquote'}):
             cls = self.get_val(node, 'attr', 'class')
             self.reporter.check(cls in KNOWN_BLOCKQUOTES,
                                 (self.filename, self.get_loc(node)),
                                 'Unknown or missing blockquote type {0}',
                                 cls)
 
-
     def check_codeblock_classes(self):
         """Check that all code blocks have known classes."""
 
-        for node in self.find_all(self.doc, {'type' : 'codeblock'}):
+        for node in self.find_all(self.doc, {'type': 'codeblock'}):
             cls = self.get_val(node, 'attr', 'class')
             self.reporter.check(cls in KNOWN_CODEBLOCKS,
                                 (self.filename, self.get_loc(node)),
                                 'Unknown or missing code block type {0}',
                                 cls)
 
-
     def check_defined_link_references(self):
         """Check that defined links resolve in the file.
 
@@ -355,7 +365,7 @@ class CheckBase(object):
         """
 
         result = set()
-        for node in self.find_all(self.doc, {'type' : 'text'}):
+        for node in self.find_all(self.doc, {'type': 'text'}):
             for match in P_INTERNAL_LINK_REF.findall(node['value']):
                 text = match[0]
                 link = match[1]
@@ -366,11 +376,10 @@ class CheckBase(object):
                             'Internally-defined links may be missing definitions: {0}',
                             ', '.join(sorted(result)))
 
-
     def find_all(self, node, pattern, accum=None):
         """Find all matches for a pattern."""
 
-        assert type(pattern) == dict, 'Patterns must be dictionaries'
+        assert isinstance(pattern, dict), 'Patterns must be dictionaries'
         if accum is None:
             accum = []
         if self.match(node, pattern):
@@ -379,7 +388,6 @@ class CheckBase(object):
             self.find_all(child, pattern, accum)
         return accum
 
-
     def match(self, node, pattern):
         """Does this node match the given pattern?"""
 
@@ -387,16 +395,16 @@ class CheckBase(object):
             if key not in node:
                 return False
             val = pattern[key]
-            if type(val) == str:
+            if isinstance(val, str):
                 if node[key] != val:
                     return False
-            elif type(val) == dict:
+            elif isinstance(val, dict):
                 if not self.match(node[key], val):
                     return False
         return True
 
-
-    def get_val(self, node, *chain):
+    @staticmethod
+    def get_val(node, *chain):
         """Get value one or more levels down."""
 
         curr = node
@@ -406,7 +414,6 @@ class CheckBase(object):
                 break
         return curr
 
-
     def get_loc(self, node):
         """Convenience method to get node's line number."""
 
@@ -419,10 +426,6 @@ class CheckBase(object):
 class CheckNonJekyll(CheckBase):
     """Check a file that isn't translated by Jekyll."""
 
-    def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
-        super(CheckNonJekyll, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
-
-
     def check_metadata(self):
         self.reporter.check(self.metadata is None,
                             self.filename,
@@ -433,11 +436,11 @@ class CheckIndex(CheckBase):
     """Check the main index page."""
 
     def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
-        super(CheckIndex, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
+        super().__init__(args, filename, metadata, metadata_len, text, lines, doc)
         self.layout = 'lesson'
 
     def check_metadata(self):
-        super(CheckIndex, self).check_metadata()
+        super().check_metadata()
         self.reporter.check(self.metadata.get('root', '') == '.',
                             self.filename,
                             'Root not set to "."')
@@ -446,19 +449,14 @@ class CheckIndex(CheckBase):
 class CheckEpisode(CheckBase):
     """Check an episode page."""
 
-    def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
-        super(CheckEpisode, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
-
-
     def check(self):
         """Run extra tests."""
 
-        super(CheckEpisode, self).check()
+        super().check()
         self.check_reference_inclusion()
 
-
     def check_metadata(self):
-        super(CheckEpisode, self).check_metadata()
+        super().check_metadata()
         if self.metadata:
             if 'layout' in self.metadata:
                 if self.metadata['layout'] == 'break':
@@ -470,19 +468,18 @@ class CheckEpisode(CheckBase):
             else:
                 self.check_metadata_fields(TEACHING_METADATA_FIELDS)
 
-
     def check_metadata_fields(self, expected):
+        """Check metadata fields."""
         for (name, type_) in expected:
             if name not in self.metadata:
                 self.reporter.add(self.filename,
                                   'Missing metadata field {0}',
                                   name)
-            elif type(self.metadata[name]) != type_:
+            elif not isinstance(self.metadata[name], type_):
                 self.reporter.add(self.filename,
                                   '"{0}" has wrong type in metadata ({1} instead of {2})',
                                   name, type(self.metadata[name]), type_)
 
-
     def check_reference_inclusion(self):
         """Check that links file has been included."""
 
@@ -507,7 +504,7 @@ class CheckReference(CheckBase):
     """Check the reference page."""
 
     def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
-        super(CheckReference, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
+        super().__init__(args, filename, metadata, metadata_len, text, lines, doc)
         self.layout = 'reference'
 
 
@@ -515,8 +512,7 @@ class CheckGeneric(CheckBase):
     """Check a generic page."""
 
     def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
-        super(CheckGeneric, self).__init__(args, filename, metadata, metadata_len, text, lines, doc)
-        self.layout = 'page'
+        super().__init__(args, filename, metadata, metadata_len, text, lines, doc)
 
 
 CHECKERS = [
@@ -525,6 +521,7 @@ CHECKERS = [
     (re.compile(r'index\.md'), CheckIndex),
     (re.compile(r'reference\.md'), CheckReference),
     (re.compile(r'_episodes/.*\.md'), CheckEpisode),
+    (re.compile(r'aio\.md'), CheckNonJekyll),
     (re.compile(r'.*\.md'), CheckGeneric)
 ]
 
index acb253b542fc9009602a3c7351352f6b37aeba04..a96ba383a4046c39527d771872e6158867e502ba 100755 (executable)
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """Initialize a newly-created repository."""
 
 
-from __future__ import print_function
 import sys
 import os
-
-ROOT_AUTHORS = '''\
-FIXME: list authors' names and email addresses.
-'''
-
-ROOT_CITATION = '''\
-FIXME: describe how to cite this lesson.
-'''
-
-ROOT_CONTRIBUTING_MD = '''\
-# Contributing
-
-[Software Carpentry][swc-site] and [Data Carpentry][dc-site] are open source projects,
-and we welcome contributions of all kinds:
-new lessons,
-fixes to existing material,
-bug reports,
-and reviews of proposed changes are all welcome.
-
-## Contributor Agreement
-
-By contributing,
-you agree that we may redistribute your work under [our license](LICENSE.md).
-In exchange,
-we will address your issues and/or assess your change proposal as promptly as we can,
-and help you become a member of our community.
-Everyone involved in [Software Carpentry][swc-site] and [Data Carpentry][dc-site]
-agrees to abide by our [code of conduct](CONDUCT.md).
-
-## How to Contribute
-
-The easiest way to get started is to file an issue
-to tell us about a spelling mistake,
-some awkward wording,
-or a factual error.
-This is a good way to introduce yourself
-and to meet some of our community members.
-
-1.  If you do not have a [GitHub][github] account,
-    you can [send us comments by email][email].
-    However,
-    we will be able to respond more quickly if you use one of the other methods described below.
-
-2.  If you have a [GitHub][github] account,
-    or are willing to [create one][github-join],
-    but do not know how to use Git,
-    you can report problems or suggest improvements by [creating an issue][issues].
-    This allows us to assign the item to someone
-    and to respond to it in a threaded discussion.
-
-3.  If you are comfortable with Git,
-    and would like to add or change material,
-    you can submit a pull request (PR).
-    Instructions for doing this are [included below](#using-github).
-
-## Where to Contribute
-
-1.  If you wish to change this lesson,
-    please work in <https://github.com/swcarpentry/FIXME>,
-    which can be viewed at <https://swcarpentry.github.io/FIXME>.
-
-2.  If you wish to change the example lesson,
-    please work in <https://github.com/swcarpentry/lesson-example>,
-    which documents the format of our lessons
-    and can be viewed at <https://swcarpentry.github.io/lesson-example>.
-
-3.  If you wish to change the template used for workshop websites,
-    please work in <https://github.com/swcarpentry/workshop-template>.
-    The home page of that repository explains how to set up workshop websites,
-    while the extra pages in <https://swcarpentry.github.io/workshop-template>
-    provide more background on our design choices.
-
-4.  If you wish to change CSS style files, tools,
-    or HTML boilerplate for lessons or workshops stored in `_includes` or `_layouts`,
-    please work in <https://github.com/swcarpentry/styles>.
-
-## What to Contribute
-
-There are many ways to contribute,
-from writing new exercises and improving existing ones
-to updating or filling in the documentation
-and and submitting [bug reports][issues]
-about things that don't work, aren't clear, or are missing.
-If you are looking for ideas, please see the 'Issues' tab for
-a list of issues associated with this repository,
-or you may also look at the issues for [Data Carpentry][dc-issues]
-and [Software Carpentry][swc-issues] projects.
-
-Comments on issues and reviews of pull requests are just as welcome:
-we are smarter together than we are on our own.
-Reviews from novices and newcomers are particularly valuable:
-it's easy for people who have been using these lessons for a while
-to forget how impenetrable some of this material can be,
-so fresh eyes are always welcome.
-
-## What *Not* to Contribute
-
-Our lessons already contain more material than we can cover in a typical workshop,
-so we are usually *not* looking for more concepts or tools to add to them.
-As a rule,
-if you want to introduce a new idea,
-you must (a) estimate how long it will take to teach
-and (b) explain what you would take out to make room for it.
-The first encourages contributors to be honest about requirements;
-the second, to think hard about priorities.
-
-We are also not looking for exercises or other material that only run on one platform.
-Our workshops typically contain a mixture of Windows, Mac OS X, and Linux users;
-in order to be usable,
-our lessons must run equally well on all three.
-
-## Using GitHub
-
-If you choose to contribute via GitHub, you may want to look at
-[How to Contribute to an Open Source Project on GitHub][how-contribute].
-To manage changes, we follow [GitHub flow][github-flow]. 
-Each lesson has two maintainers who review issues and pull requests or encourage others to do so.
-The maintainers are community volunteers and have final say over what gets merged into the lesson.
-To use the web interface for contributing to a lesson:
-
-1.  Fork the master repository to your GitHub profile.
-2.  Within your version of the forked repository, move to the `gh-pages` branch and
-create a new branch for each significant change being made.
-3.  Navigate to the file(s) you wish to change within the new branches and make revisions as required.
-4.  Commit all changed files within the appropriate branches.
-5.  Create individual pull requests from each of your changed branches
-to the `gh-pages` branch within the master repository.
-6.  If you receive feedback, make changes using your issue-specific branches of the forked
-repository and the pull requests will update automatically.
-7.  Repeat as needed until all feedback has been addressed.
-
-When starting work, please make sure your clone of the master `gh-pages` branch is up-to-date
-before creating your own revision-specific branch(es) from there.
-Additionally, please only work from your newly-created branch(es) and *not*
-your clone of the master `gh-pages` branch.
-Lastly, published copies of all the lessons are available in the `gh-pages` branch of the master
-repository for reference while revising.
-
-## Other Resources
-
-General discussion of [Software Carpentry][swc-site] and [Data Carpentry][dc-site]
-happens on the [discussion mailing list][discuss-list],
-which everyone is welcome to join.
-You can also [reach us by email][email].
-
-[email]: mailto:admin@software-carpentry.org
-[dc-issues]: https://github.com/issues?q=user%3Adatacarpentry
-[dc-lessons]: http://datacarpentry.org/lessons/
-[dc-site]: http://datacarpentry.org/
-[discuss-list]: http://lists.software-carpentry.org/listinfo/discuss
-[github]: https://github.com
-[github-flow]: https://guides.github.com/introduction/flow/
-[github-join]: https://github.com/join
-[how-contribute]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
-[issues]: https://guides.github.com/features/issues/
-[swc-issues]: https://github.com/issues?q=user%3Aswcarpentry
-[swc-lessons]: https://software-carpentry.org/lessons/
-[swc-site]: https://software-carpentry.org/
-'''
-
-ROOT_CONFIG_YML = '''\
-#------------------------------------------------------------
-# Values for this lesson.
-#------------------------------------------------------------
-
-# Which carpentry is this ("swc", "dc", or "lc")?
-carpentry: "swc"
-
-# Overall title for pages.
-title: "Lesson Title"
-
-# Contact.  This *must* include the protocol: if it's an email
-# address, it must look like "mailto:lessons@software-carpentry.org",
-# or if it's a URL, "https://gitter.im/username/ProjectName".
-email: "mailto:lessons@software-carpentry.org"
-
-#------------------------------------------------------------
-# Generic settings (should not need to change).
-#------------------------------------------------------------
-
-# What kind of thing is this ("workshop" or "lesson")?
-kind: "lesson"
-
-# Magic to make URLs resolve both locally and on GitHub.
-# See https://help.github.com/articles/repository-metadata-on-github-pages/.
-repository: <USERNAME>/<PROJECT>
-
-# Sites.
-amy_site: "https://amy.software-carpentry.org/workshops"
-dc_site: "http://datacarpentry.org"
-swc_github: "https://github.com/swcarpentry"
-swc_site: "https://software-carpentry.org"
-swc_pages: "https://swcarpentry.github.io"
-lc_site: "https://librarycarpentry.github.io/"
-template_repo: "https://github.com/swcarpentry/styles"
-example_repo: "https://github.com/swcarpentry/lesson-example"
-example_site: "https://swcarpentry.github.com/lesson-example"
-workshop_repo: "https://github.com/swcarpentry/workshop-template"
-workshop_site: "https://swcarpentry.github.io/workshop-template"
-training_site: "https://swcarpentry.github.io/instructor-training"
-
-# Surveys.
-pre_survey: "https://www.surveymonkey.com/r/swc_pre_workshop_v1?workshop_id="
-post_survey: "https://www.surveymonkey.com/r/swc_post_workshop_v1?workshop_id="
-training_post_survey: "https://www.surveymonkey.com/r/post-instructor-training"
-
-# Start time in minutes (0 to be clock-independent, 540 to show a start at 09:00 am).
-start_time: 0
-
-# Specify that things in the episodes collection should be output.
-collections:
-  episodes:
-    output: true
-    permalink: /:path/index.html
-  extras:
-    output: true
-    permalink: /:path/index.html
-
-# Set the default layout for things in the episodes collection.
-defaults:
-  - values:
-      root: ..
-  - scope:
-      path: ""
-      type: episodes
-    values:
-      layout: episode
-
-# Files and directories that are not to be copied.
-exclude:
-  - Makefile
-  - bin
-
-# Turn on built-in syntax highlighting.
-highlighter: rouge
-'''
-
-ROOT_INDEX_MD = '''\
----
-layout: lesson
-root: .
-permalink: index.html  # Is the only page that don't follow the partner /:path/index.html
----
-FIXME: home page introduction
-
-> ## Prerequisites
->
-> FIXME
-{: .prereq}
-'''
-
-ROOT_REFERENCE_MD = '''\
----
-layout: reference
-root: .
----
-
-## Glossary
-
-FIXME
-'''
-
-ROOT_SETUP_MD = '''\
----
-layout: page
-title: Setup
-root: .
----
-FIXME
-'''
-
-ROOT_AIO_MD = '''\
----
-layout: page 
-root: .
----
-<script>
-  window.onload = function() {
-    var lesson_episodes = [
-    {% for episode in site.episodes %}
-    "{{ episode.url}}"{% unless forloop.last %},{% endunless %}
-    {% endfor %}
-    ];
-    var xmlHttp = [];  /* Required since we are going to query every episode. */
-    for (i=0; i < lesson_episodes.length; i++) {
-      xmlHttp[i] = new XMLHttpRequest();
-      xmlHttp[i].episode = lesson_episodes[i];  /* To enable use this later. */
-      xmlHttp[i].onreadystatechange = function() {
-      if (this.readyState == 4 && this.status == 200) {
-        var article_here = document.getElementById(this.episode);
-        var parser = new DOMParser();
-        var htmlDoc = parser.parseFromString(this.responseText,"text/html");
-        var htmlDocArticle = htmlDoc.getElementsByTagName("article")[0];
-        article_here.innerHTML = htmlDocArticle.innerHTML;
-        }
-      }
-      episode_url = "{{ page.root }}" + lesson_episodes[i];
-      xmlHttp[i].open("GET", episode_url);
-      xmlHttp[i].send(null);
-    }
-  }
-</script>
-{% comment %}
-Create anchor for each one of the episodes.
-{% endcomment %}
-{% for episode in site.episodes %}
-<article id="{{ episode.url }}"></article>
-{% endfor %}
-'''
-
-EPISODES_INTRODUCTION_MD = '''\
----
-title: "Introduction"
-teaching: 0
-exercises: 0
-questions:
-- "Key question"
-objectives:
-- "First objective."
-keypoints:
-- "First key point."
----
-'''
-
-EXTRAS_ABOUT_MD = '''\
----
-layout: page
-title: About
----
-{% include carpentries.html %}
-'''
-
-EXTRAS_DISCUSS_MD = '''\
----
-layout: page
-title: Discussion
----
-FIXME
-'''
-
-EXTRAS_FIGURES_MD = '''\
----
-layout: page
-title: Figures
----
-<script>
-  window.onload = function() {
-    var lesson_episodes = [
-    {% for episode in site.episodes %}
-    "{{ episode.url}}"{% unless forloop.last %},{% endunless %}
-    {% endfor %}
-    ];
-    var xmlHttp = [];  /* Required since we are going to query every episode. */
-    for (i=0; i < lesson_episodes.length; i++) {
-      xmlHttp[i] = new XMLHttpRequest();
-      xmlHttp[i].episode = lesson_episodes[i];  /* To enable use this later. */
-      xmlHttp[i].onreadystatechange = function() {
-        if (this.readyState == 4 && this.status == 200) {
-          var article_here = document.getElementById(this.episode);
-          var parser = new DOMParser();
-          var htmlDoc = parser.parseFromString(this.responseText,"text/html");
-          var htmlDocArticle = htmlDoc.getElementsByTagName("article")[0];
-          article_here.appendChild(htmlDocArticle.getElementsByTagName("h1")[0]);
-          for (let image of htmlDocArticle.getElementsByTagName("img")) {
-            article_here.appendChild(image);
-          }
-        }
-      }
-      episode_url = "{{ page.root }}" + lesson_episodes[i];
-      xmlHttp[i].open("GET", episode_url);
-      xmlHttp[i].send(null);
-    }
-  }
-</script>
-{% comment %}
-Create anchor for each one of the episodes.
-{% endcomment %}
-{% for episode in site.episodes %}
-<article id="{{ episode.url }}"></article>
-{% endfor %}
-'''
-
-EXTRAS_GUIDE_MD = '''\
----
-layout: page
-title: "Instructor Notes"
----
-FIXME
-'''
+import shutil
 
 BOILERPLATE = (
-    ('AUTHORS', ROOT_AUTHORS),
-    ('CITATION', ROOT_CITATION),
-    ('CONTRIBUTING.md', ROOT_CONTRIBUTING_MD),
-    ('_config.yml', ROOT_CONFIG_YML),
-    ('index.md', ROOT_INDEX_MD),
-    ('reference.md', ROOT_REFERENCE_MD),
-    ('setup.md', ROOT_SETUP_MD),
-    ('aio.md', ROOT_AIO_MD),
-    ('_episodes/01-introduction.md', EPISODES_INTRODUCTION_MD),
-    ('_extras/about.md', EXTRAS_ABOUT_MD),
-    ('_extras/discuss.md', EXTRAS_DISCUSS_MD),
-    ('_extras/figures.md', EXTRAS_FIGURES_MD),
-    ('_extras/guide.md', EXTRAS_GUIDE_MD),
+    '.travis.yml',
+    'AUTHORS',
+    'CITATION',
+    'CODE_OF_CONDUCT.md',
+    'CONTRIBUTING.md',
+    'README.md',
+    '_config.yml',
+    '_episodes/01-introduction.md',
+    '_extras/about.md',
+    '_extras/discuss.md',
+    '_extras/figures.md',
+    '_extras/guide.md',
+    'aio.md',
+    'index.md',
+    'reference.md',
+    'setup.md',
 )
 
 
@@ -418,7 +32,7 @@ def main():
 
     # Check.
     errors = False
-    for (path, _) in BOILERPLATE:
+    for path in BOILERPLATE:
         if os.path.exists(path):
             print('Warning: {0} already exists.'.format(path), file=sys.stderr)
             errors = True
@@ -427,9 +41,11 @@ def main():
         sys.exit(1)
 
     # Create.
-    for (path, content) in BOILERPLATE:
-        with open(path, 'w') as writer:
-            writer.write(content)
+    for path in BOILERPLATE:
+        shutil.copyfile(
+            "bin/boilerplate/{}".format(path),
+            path
+        )
 
 
 if __name__ == '__main__':
index fd04ce936bbb99c1042f044a5edaa9509c7ab66b..af4b78235a7ce9e24ff69f8b3c5245410c063524 100755 (executable)
@@ -1,17 +1,17 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 """
 Check repository settings.
 """
 
-from __future__ import print_function
+
 import sys
 import os
 from subprocess import Popen, PIPE
 import re
-from optparse import OptionParser
+from argparse import ArgumentParser
 
-from util import Reporter, load_yaml, require
+from util import Reporter, require
 
 # Import this way to produce a more useful error message.
 try:
@@ -35,15 +35,26 @@ F_API_URL = 'https://api.github.com/repos/{0}/{1}/labels'
 
 # Expected labels and colors.
 EXPECTED = {
-    'bug' : 'bd2c00',
-    'discussion' : 'fc8dc1',
-    'enhancement' : '9cd6dc',
-    'help-wanted' : 'f4fd9c',
-    'instructor-training' : '6e5494',
-    'newcomer-friendly' : 'eec275',
-    'question' : '808040',
-    'template-and-tools' : '2b3990',
-    'work-in-progress' : '7ae78e'
+    'help wanted': 'dcecc7',
+    'status:in progress': '9bcc65',
+    'status:changes requested': '679f38',
+    'status:wait': 'fff2df',
+    'status:refer to cac': 'ffdfb2',
+    'status:need more info': 'ee6c00',
+    'status:blocked': 'e55100',
+    'status:out of scope': 'eeeeee',
+    'status:duplicate': 'bdbdbd',
+    'type:typo text': 'f8bad0',
+    'type:bug': 'eb3f79',
+    'type:formatting': 'ac1357',
+    'type:template and tools': '7985cb',
+    'type:instructor guide': '00887a',
+    'type:discussion': 'b2e5fc',
+    'type:enhancement': '7fdeea',
+    'type:clarification': '00acc0',
+    'type:teaching example': 'ced8dc',
+    'good first issue': 'ffeb3a',
+    'high priority': 'd22e2e'
 }
 
 
@@ -54,7 +65,7 @@ def main():
 
     args = parse_args()
     reporter = Reporter()
-    repo_url = get_repo_url(args.source_dir, args.repo_url)
+    repo_url = get_repo_url(args.repo_url)
     check_labels(reporter, repo_url)
     reporter.report()
 
@@ -64,24 +75,24 @@ def parse_args():
     Parse command-line arguments.
     """
 
-    parser = OptionParser()
-    parser.add_option('-r', '--repo',
-                      default=None,
-                      dest='repo_url',
-                      help='repository URL')
-    parser.add_option('-s', '--source',
-                      default=os.curdir,
-                      dest='source_dir',
-                      help='source directory')
-
-    args, extras = parser.parse_args()
+    parser = ArgumentParser(description="""Check repository settings.""")
+    parser.add_argument('-r', '--repo',
+                        default=None,
+                        dest='repo_url',
+                        help='repository URL')
+    parser.add_argument('-s', '--source',
+                        default=os.curdir,
+                        dest='source_dir',
+                        help='source directory')
+
+    args, extras = parser.parse_known_args()
     require(not extras,
             'Unexpected trailing command-line arguments "{0}"'.format(extras))
 
     return args
 
 
-def get_repo_url(source_dir, repo_url):
+def get_repo_url(repo_url):
     """
     Figure out which repository to query.
     """
@@ -92,7 +103,8 @@ def get_repo_url(source_dir, repo_url):
 
     # Guess.
     cmd = 'git remote -v'
-    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True, universal_newlines=True)
+    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
+              close_fds=True, universal_newlines=True)
     stdout_data, stderr_data = p.communicate()
     stdout_data = stdout_data.split('\n')
     matches = [P_GIT_REMOTE.match(line) for line in stdout_data]
@@ -101,10 +113,12 @@ def get_repo_url(source_dir, repo_url):
             'Unexpected output from git remote command: "{0}"'.format(matches))
 
     username = matches[0].group(1)
-    require(username, 'empty username in git remote output {0}'.format(matches[0]))
+    require(
+        username, 'empty username in git remote output {0}'.format(matches[0]))
 
     project_name = matches[0].group(2)
-    require(username, 'empty project name in git remote output {0}'.format(matches[0]))
+    require(
+        username, 'empty project name in git remote output {0}'.format(matches[0]))
 
     url = F_REPO_URL.format(username, project_name)
     return url
@@ -131,7 +145,7 @@ def check_labels(reporter, repo_url):
 
     overlap = set(EXPECTED.keys()).intersection(set(actual.keys()))
     for name in sorted(overlap):
-        reporter.check(EXPECTED[name] == actual[name],
+        reporter.check(EXPECTED[name].lower() == actual[name].lower(),
                        None,
                        'Color mis-match for label {0} in {1}: expected {2}, found {3}',
                        name, repo_url, EXPECTED[name], actual[name])
@@ -143,13 +157,15 @@ def get_labels(repo_url):
     """
 
     m = P_REPO_URL.match(repo_url)
-    require(m, 'repository URL {0} does not match expected pattern'.format(repo_url))
+    require(
+        m, 'repository URL {0} does not match expected pattern'.format(repo_url))
 
     username = m.group(1)
     require(username, 'empty username in repository URL {0}'.format(repo_url))
 
     project_name = m.group(2)
-    require(username, 'empty project name in repository URL {0}'.format(repo_url))
+    require(
+        username, 'empty project name in repository URL {0}'.format(repo_url))
 
     url = F_API_URL.format(username, project_name)
     r = requests.get(url)
index 743d0cf45774cc1cc13d7e268b1fb1a6bb46c6fa..960059e8d6b0090c7ac8748ded69626fb4a9aefa 100755 (executable)
@@ -1,11 +1,14 @@
+#!/usr/bin/env python3
+
 import unittest
 
 import lesson_check
 import util
 
+
 class TestFileList(unittest.TestCase):
     def setUp(self):
-        self.reporter = util.Reporter()  ## TODO: refactor reporter class.
+        self.reporter = util.Reporter()  # TODO: refactor reporter class.
 
     def test_file_list_has_expected_entries(self):
         # For first pass, simply assume that all required files are present
@@ -15,5 +18,6 @@ class TestFileList(unittest.TestCase):
         lesson_check.check_fileset('', self.reporter, all_filenames)
         self.assertEqual(len(self.reporter.messages), 0)
 
+
 if __name__ == "__main__":
     unittest.main()
index 0cc8de69d130481bdc354a2a0ff2ccf761cb52e7..522f5dfc6a00ff07cbcf64bb4c744745c47b02b5 100644 (file)
@@ -1,4 +1,3 @@
-from __future__ import print_function
 import sys
 import os
 import json
@@ -29,16 +28,14 @@ UNWANTED_FILES = [
 # (Can't use 'None' because that might be a legitimate value.)
 REPORTER_NOT_SET = []
 
-class Reporter(object):
+
+class Reporter:
     """Collect and report errors."""
 
     def __init__(self):
         """Constructor."""
-
-        super(Reporter, self).__init__()
         self.messages = []
 
-
     def check_field(self, filename, name, values, key, expected=REPORTER_NOT_SET):
         """Check that a dictionary has an expected value."""
 
@@ -48,10 +45,11 @@ class Reporter(object):
             pass
         elif type(expected) in (tuple, set, list):
             if values[key] not in expected:
-                self.add(filename, '{0} {1} value {2} is not in {3}', name, key, values[key], expected)
+                self.add(
+                    filename, '{0} {1} value {2} is not in {3}', name, key, values[key], expected)
         elif values[key] != expected:
-            self.add(filename, '{0} {1} is {2} not {3}', name, key, values[key], expected)
-
+            self.add(filename, '{0} {1} is {2} not {3}',
+                     name, key, values[key], expected)
 
     def check(self, condition, location, fmt, *args):
         """Append error if condition not met."""
@@ -59,12 +57,36 @@ class Reporter(object):
         if not condition:
             self.add(location, fmt, *args)
 
-
     def add(self, location, fmt, *args):
         """Append error unilaterally."""
 
         self.messages.append((location, fmt.format(*args)))
 
+    @staticmethod
+    def pretty(item):
+        location, message = item
+        if isinstance(location, type(None)):
+            return message
+        elif isinstance(location, str):
+            return location + ': ' + message
+        elif isinstance(location, tuple):
+            return '{0}:{1}: '.format(*location) + message
+
+        print('Unknown item "{0}"'.format(item), file=sys.stderr)
+        return NotImplemented
+
+    @staticmethod
+    def key(item):
+        location, message = item
+        if isinstance(location, type(None)):
+            return ('', -1, message)
+        elif isinstance(location, str):
+            return (location, -1, message)
+        elif isinstance(location, tuple):
+            return (location[0], location[1], message)
+
+        print('Unknown item "{0}"'.format(item), file=sys.stderr)
+        return NotImplemented
 
     def report(self, stream=sys.stdout):
         """Report all messages in order."""
@@ -72,30 +94,8 @@ class Reporter(object):
         if not self.messages:
             return
 
-        def pretty(item):
-            location, message = item
-            if isinstance(location, type(None)):
-                return message
-            elif isinstance(location, str):
-                return location + ': ' + message
-            elif isinstance(location, tuple):
-                return '{0}:{1}: '.format(*location) + message
-            else:
-                assert False, 'Unknown item "{0}"'.format(item)
-
-        def key(item):
-            location, message = item
-            if isinstance(location, type(None)):
-                return ('', -1, message)
-            elif isinstance(location, str):
-                return (location, -1, message)
-            elif isinstance(location, tuple):
-                return (location[0], location[1], message)
-            else:
-                assert False, 'Unknown item "{0}"'.format(item)
-
-        for m in sorted(self.messages, key=key):
-            print(pretty(m), file=stream)
+        for m in sorted(self.messages, key=self.key):
+            print(self.pretty(m), file=stream)
 
 
 def read_markdown(parser, path):
@@ -111,11 +111,13 @@ def read_markdown(parser, path):
 
     # Split into lines.
     metadata_len = 0 if metadata_raw is None else metadata_raw.count('\n')
-    lines = [(metadata_len+i+1, line, len(line)) for (i, line) in enumerate(body.split('\n'))]
+    lines = [(metadata_len+i+1, line, len(line))
+             for (i, line) in enumerate(body.split('\n'))]
 
     # Parse Markdown.
     cmd = 'ruby {0}'.format(parser)
-    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, close_fds=True, universal_newlines=True)
+    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
+              close_fds=True, universal_newlines=True)
     stdout_data, stderr_data = p.communicate(body)
     doc = json.loads(stdout_data)
 
@@ -136,7 +138,6 @@ def split_metadata(path, text):
 
     metadata_raw = None
     metadata_yaml = None
-    metadata_len = None
 
     pieces = text.split('---', 2)
     if len(pieces) == 3:
@@ -145,7 +146,8 @@ def split_metadata(path, text):
         try:
             metadata_yaml = yaml.load(metadata_raw)
         except yaml.YAMLError as e:
-            print('Unable to parse YAML header in {0}:\n{1}'.format(path, e), file=sys.stderr)
+            print('Unable to parse YAML header in {0}:\n{1}'.format(
+                path, e), file=sys.stderr)
             sys.exit(1)
 
     return metadata_raw, metadata_yaml, text
@@ -160,8 +162,9 @@ def load_yaml(filename):
     try:
         with open(filename, 'r') as reader:
             return yaml.load(reader)
-    except (yaml.YAMLError, FileNotFoundError) as e:
-        print('Unable to load YAML file {0}:\n{1}'.format(filename, e), file=sys.stderr)
+    except (yaml.YAMLError, IOError) as e:
+        print('Unable to load YAML file {0}:\n{1}'.format(
+            filename, e), file=sys.stderr)
         sys.exit(1)
 
 
index f82ce3d69417e3cd1990aea96603afcda2e2aff9..bd15210a93e844530b502d4867cac00f593d7897 100755 (executable)
@@ -1,10 +1,10 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 '''Check that a workshop's index.html metadata is valid.  See the
 docstrings on the checking functions for a summary of the checks.
 '''
 
-from __future__ import print_function
+
 import sys
 import os
 import re
@@ -174,8 +174,8 @@ def check_latitude_longitude(latlng):
     try:
         lat, lng = latlng.split(',')
         lat = float(lat)
-        long = float(lng)
-        return (-90.0 <= lat <= 90.0) and (-180.0 <= long <= 180.0)
+        lng = float(lng)
+        return (-90.0 <= lat <= 90.0) and (-180.0 <= lng <= 180.0)
     except ValueError:
         return False
 
@@ -203,9 +203,9 @@ def check_helpers(helpers):
 
 
 @look_for_fixme
-def check_email(email):
+def check_emails(emails):
     """
-    'email' must be a comma-separated list of valid email addresses.
+    'emails' must be a comma-separated list of valid email addresses.
     The list may be empty. A valid email address consists of characters,
     an '@', and more characters.  It should not contain the default contact
     """
@@ -217,7 +217,7 @@ def check_email(email):
                 return False
     else:
         return False
-  
+
     return True
 
 
@@ -294,9 +294,9 @@ HANDLERS = {
                    '["First helper", "Second helper",..]'),
 
     'email':    (True, check_emails,
-                   'contact email list isn\'t a valid list of format ' +
-                   '["me@example.org", "you@example.org",..] or contains incorrectly formatted email addresses or ' +
-                   '"{0}".'.format(DEFAULT_CONTACT_EMAIL)),
+                 'contact email list isn\'t a valid list of format ' +
+                 '["me@example.org", "you@example.org",..] or contains incorrectly formatted email addresses or ' +
+                 '"{0}".'.format(DEFAULT_CONTACT_EMAIL)),
 
     'eventbrite': (False, check_eventbrite, 'Eventbrite key appears invalid'),
 
@@ -308,10 +308,10 @@ HANDLERS = {
 }
 
 # REQUIRED is all required categories.
-REQUIRED = set([k for k in HANDLERS if HANDLERS[k][0]])
+REQUIRED = {k for k in HANDLERS if HANDLERS[k][0]}
 
 # OPTIONAL is all optional categories.
-OPTIONAL = set([k for k in HANDLERS if not HANDLERS[k][0]])
+OPTIONAL = {k for k in HANDLERS if not HANDLERS[k][0]}
 
 
 def check_blank_lines(reporter, raw):
@@ -319,7 +319,8 @@ def check_blank_lines(reporter, raw):
     Blank lines are not allowed in category headers.
     """
 
-    lines = [(i, x) for (i, x) in enumerate(raw.strip().split('\n')) if not x.strip()]
+    lines = [(i, x) for (i, x) in enumerate(
+        raw.strip().split('\n')) if not x.strip()]
     reporter.check(not lines,
                    None,
                    'Blank line(s) in header: {0}',
diff --git a/favicon-dc.ico b/favicon-dc.ico
deleted file mode 100644 (file)
index 4937f2e..0000000
Binary files a/favicon-dc.ico and /dev/null differ
diff --git a/favicon-lc.ico b/favicon-lc.ico
deleted file mode 100644 (file)
index f4f3c93..0000000
Binary files a/favicon-lc.ico and /dev/null differ
diff --git a/favicon-swc.ico b/favicon-swc.ico
deleted file mode 100644 (file)
index 34f80ad..0000000
Binary files a/favicon-swc.ico and /dev/null differ