aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarAgustin Henze <tin@sluc.org.ar>2015-08-26 07:57:04 -0300
committerLibravatarAgustin Henze <tin@sluc.org.ar>2015-08-26 07:57:04 -0300
commit8041475aab2b8efad7d2857027331bd626d26312 (patch)
tree3980e1763c067079a4cebb425d642ca9eac834bf
parentb0b24795b24ee6809397fbbadf42f31f310a219f (diff)
downloadnikola-8041475aab2b8efad7d2857027331bd626d26312.tar.bz2
nikola-8041475aab2b8efad7d2857027331bd626d26312.tar.xz
nikola-8041475aab2b8efad7d2857027331bd626d26312.tar.zst
Imported Upstream version 7.6.4
-rw-r--r--.coveragerc2
-rwxr-xr-x.pypt/ghrel90
-rw-r--r--.travis.yml13
-rw-r--r--AUTHORS.txt213
-rw-r--r--CHANGES.txt128
-rw-r--r--README.rst14
-rw-r--r--appveyor.yml11
-rw-r--r--bower_components/jquery-colorbox/.bower.json8
-rw-r--r--bower_components/jquery-colorbox/README.md8
-rw-r--r--bower_components/jquery-colorbox/bower.json1
-rw-r--r--bower_components/jquery-colorbox/i18n/jquery.colorbox-he.js4
-rw-r--r--bower_components/jquery-colorbox/i18n/jquery.colorbox-zh-TW.js6
-rw-r--r--bower_components/jquery-colorbox/jquery.colorbox.js8
-rw-r--r--bower_components/jquery-colorbox/package.json2
-rw-r--r--bower_components/moment/.bower.json8
-rw-r--r--bower_components/moment/CHANGELOG.md18
-rw-r--r--bower_components/moment/README.md1
-rw-r--r--bower_components/moment/bower.json1
-rw-r--r--bower_components/moment/locale/af.js6
-rw-r--r--bower_components/moment/locale/ar-ma.js6
-rw-r--r--bower_components/moment/locale/ar-sa.js4
-rw-r--r--bower_components/moment/locale/ar-tn.js6
-rw-r--r--bower_components/moment/locale/ar.js4
-rw-r--r--bower_components/moment/locale/az.js6
-rw-r--r--bower_components/moment/locale/be.js6
-rw-r--r--bower_components/moment/locale/bg.js6
-rw-r--r--bower_components/moment/locale/bn.js8
-rw-r--r--bower_components/moment/locale/bo.js6
-rw-r--r--bower_components/moment/locale/br.js4
-rw-r--r--bower_components/moment/locale/bs.js6
-rw-r--r--bower_components/moment/locale/ca.js4
-rw-r--r--bower_components/moment/locale/cs.js6
-rw-r--r--bower_components/moment/locale/cv.js6
-rw-r--r--bower_components/moment/locale/cy.js6
-rw-r--r--bower_components/moment/locale/da.js6
-rw-r--r--bower_components/moment/locale/de-at.js4
-rw-r--r--bower_components/moment/locale/de.js4
-rw-r--r--bower_components/moment/locale/el.js4
-rw-r--r--bower_components/moment/locale/en-au.js4
-rw-r--r--bower_components/moment/locale/en-ca.js4
-rw-r--r--bower_components/moment/locale/en-gb.js4
-rw-r--r--bower_components/moment/locale/eo.js6
-rw-r--r--bower_components/moment/locale/es.js6
-rw-r--r--bower_components/moment/locale/et.js6
-rw-r--r--bower_components/moment/locale/eu.js10
-rw-r--r--bower_components/moment/locale/fa.js6
-rw-r--r--bower_components/moment/locale/fi.js8
-rw-r--r--bower_components/moment/locale/fo.js6
-rw-r--r--bower_components/moment/locale/fr-ca.js10
-rw-r--r--bower_components/moment/locale/fr.js6
-rw-r--r--bower_components/moment/locale/fy.js6
-rw-r--r--bower_components/moment/locale/gl.js6
-rw-r--r--bower_components/moment/locale/he.js10
-rw-r--r--bower_components/moment/locale/hi.js4
-rw-r--r--bower_components/moment/locale/hr.js6
-rw-r--r--bower_components/moment/locale/hu.js6
-rw-r--r--bower_components/moment/locale/hy-am.js6
-rw-r--r--bower_components/moment/locale/id.js6
-rw-r--r--bower_components/moment/locale/is.js6
-rw-r--r--bower_components/moment/locale/it.js6
-rw-r--r--bower_components/moment/locale/ja.js6
-rw-r--r--bower_components/moment/locale/jv.js6
-rw-r--r--bower_components/moment/locale/ka.js4
-rw-r--r--bower_components/moment/locale/km.js6
-rw-r--r--bower_components/moment/locale/ko.js4
-rw-r--r--bower_components/moment/locale/lb.js4
-rw-r--r--bower_components/moment/locale/lt.js22
-rw-r--r--bower_components/moment/locale/lv.js6
-rw-r--r--bower_components/moment/locale/me.js6
-rw-r--r--bower_components/moment/locale/mk.js6
-rw-r--r--bower_components/moment/locale/ml.js4
-rw-r--r--bower_components/moment/locale/mr.js4
-rw-r--r--bower_components/moment/locale/ms-my.js6
-rw-r--r--bower_components/moment/locale/ms.js81
-rw-r--r--bower_components/moment/locale/my.js4
-rw-r--r--bower_components/moment/locale/nb.js6
-rw-r--r--bower_components/moment/locale/ne.js4
-rw-r--r--bower_components/moment/locale/nl.js6
-rw-r--r--bower_components/moment/locale/nn.js6
-rw-r--r--bower_components/moment/locale/pl.js6
-rw-r--r--bower_components/moment/locale/pt-br.js8
-rw-r--r--bower_components/moment/locale/pt.js6
-rw-r--r--bower_components/moment/locale/ro.js2
-rw-r--r--bower_components/moment/locale/ru.js6
-rw-r--r--bower_components/moment/locale/si.js4
-rw-r--r--bower_components/moment/locale/sk.js6
-rw-r--r--bower_components/moment/locale/sl.js6
-rw-r--r--bower_components/moment/locale/sq.js6
-rw-r--r--bower_components/moment/locale/sr-cyrl.js6
-rw-r--r--bower_components/moment/locale/sr.js6
-rw-r--r--bower_components/moment/locale/sv.js6
-rw-r--r--bower_components/moment/locale/ta.js6
-rw-r--r--bower_components/moment/locale/th.js6
-rw-r--r--bower_components/moment/locale/tl-ph.js6
-rw-r--r--bower_components/moment/locale/tr.js6
-rw-r--r--bower_components/moment/locale/tzl.js84
-rw-r--r--bower_components/moment/locale/tzm-latn.js6
-rw-r--r--bower_components/moment/locale/tzm.js6
-rw-r--r--bower_components/moment/locale/uk.js6
-rw-r--r--bower_components/moment/locale/uz.js6
-rw-r--r--bower_components/moment/locale/vi.js10
-rw-r--r--bower_components/moment/locale/zh-cn.js8
-rw-r--r--bower_components/moment/locale/zh-tw.js8
-rw-r--r--bower_components/moment/min/locales.js643
-rw-r--r--bower_components/moment/min/moment-with-locales.js984
-rw-r--r--bower_components/moment/min/tests.js1169
-rw-r--r--bower_components/moment/moment.js340
-rw-r--r--bower_components/moment/src/lib/create/from-anything.js23
-rw-r--r--bower_components/moment/src/lib/create/from-string.js6
-rw-r--r--bower_components/moment/src/lib/create/valid.js1
-rw-r--r--bower_components/moment/src/lib/duration/as.js6
-rw-r--r--bower_components/moment/src/lib/duration/bubble.js39
-rw-r--r--bower_components/moment/src/lib/duration/iso-string.js36
-rw-r--r--bower_components/moment/src/lib/format/format.js7
-rw-r--r--bower_components/moment/src/lib/locale/formats.js22
-rw-r--r--bower_components/moment/src/lib/locale/locales.js4
-rw-r--r--bower_components/moment/src/lib/moment/calendar.js4
-rw-r--r--bower_components/moment/src/lib/moment/constructor.js2
-rw-r--r--bower_components/moment/src/lib/moment/min-max.js2
-rw-r--r--bower_components/moment/src/lib/moment/prototype.js3
-rw-r--r--bower_components/moment/src/lib/moment/to-type.js13
-rw-r--r--bower_components/moment/src/lib/parse/regex.js9
-rw-r--r--bower_components/moment/src/lib/units/day-of-week.js28
-rw-r--r--bower_components/moment/src/lib/units/day-of-year.js18
-rw-r--r--bower_components/moment/src/lib/units/millisecond.js38
-rw-r--r--bower_components/moment/src/lib/units/offset.js31
-rw-r--r--bower_components/moment/src/lib/units/year.js6
-rw-r--r--bower_components/moment/src/lib/utils/abs-ceil.js7
-rw-r--r--bower_components/moment/src/lib/utils/deprecate.js5
-rw-r--r--bower_components/moment/src/lib/utils/to-int.js8
-rw-r--r--bower_components/moment/src/lib/utils/zero-fill.js10
-rw-r--r--bower_components/moment/src/locale/af.js6
-rw-r--r--bower_components/moment/src/locale/ar-ma.js6
-rw-r--r--bower_components/moment/src/locale/ar-sa.js4
-rw-r--r--bower_components/moment/src/locale/ar-tn.js6
-rw-r--r--bower_components/moment/src/locale/ar.js4
-rw-r--r--bower_components/moment/src/locale/az.js6
-rw-r--r--bower_components/moment/src/locale/be.js6
-rw-r--r--bower_components/moment/src/locale/bg.js6
-rw-r--r--bower_components/moment/src/locale/bn.js8
-rw-r--r--bower_components/moment/src/locale/bo.js6
-rw-r--r--bower_components/moment/src/locale/br.js4
-rw-r--r--bower_components/moment/src/locale/bs.js6
-rw-r--r--bower_components/moment/src/locale/ca.js4
-rw-r--r--bower_components/moment/src/locale/cs.js6
-rw-r--r--bower_components/moment/src/locale/cv.js6
-rw-r--r--bower_components/moment/src/locale/cy.js6
-rw-r--r--bower_components/moment/src/locale/da.js6
-rw-r--r--bower_components/moment/src/locale/de-at.js4
-rw-r--r--bower_components/moment/src/locale/de.js4
-rw-r--r--bower_components/moment/src/locale/el.js4
-rw-r--r--bower_components/moment/src/locale/en-au.js4
-rw-r--r--bower_components/moment/src/locale/en-ca.js4
-rw-r--r--bower_components/moment/src/locale/en-gb.js4
-rw-r--r--bower_components/moment/src/locale/eo.js6
-rw-r--r--bower_components/moment/src/locale/es.js6
-rw-r--r--bower_components/moment/src/locale/et.js6
-rw-r--r--bower_components/moment/src/locale/eu.js10
-rw-r--r--bower_components/moment/src/locale/fa.js6
-rw-r--r--bower_components/moment/src/locale/fi.js8
-rw-r--r--bower_components/moment/src/locale/fo.js6
-rw-r--r--bower_components/moment/src/locale/fr-ca.js10
-rw-r--r--bower_components/moment/src/locale/fr.js6
-rw-r--r--bower_components/moment/src/locale/fy.js6
-rw-r--r--bower_components/moment/src/locale/gl.js6
-rw-r--r--bower_components/moment/src/locale/he.js10
-rw-r--r--bower_components/moment/src/locale/hi.js4
-rw-r--r--bower_components/moment/src/locale/hr.js6
-rw-r--r--bower_components/moment/src/locale/hu.js6
-rw-r--r--bower_components/moment/src/locale/hy-am.js6
-rw-r--r--bower_components/moment/src/locale/id.js6
-rw-r--r--bower_components/moment/src/locale/is.js6
-rw-r--r--bower_components/moment/src/locale/it.js6
-rw-r--r--bower_components/moment/src/locale/ja.js6
-rw-r--r--bower_components/moment/src/locale/jv.js6
-rw-r--r--bower_components/moment/src/locale/ka.js4
-rw-r--r--bower_components/moment/src/locale/km.js6
-rw-r--r--bower_components/moment/src/locale/ko.js4
-rw-r--r--bower_components/moment/src/locale/lb.js4
-rw-r--r--bower_components/moment/src/locale/lt.js22
-rw-r--r--bower_components/moment/src/locale/lv.js6
-rw-r--r--bower_components/moment/src/locale/me.js6
-rw-r--r--bower_components/moment/src/locale/mk.js6
-rw-r--r--bower_components/moment/src/locale/ml.js4
-rw-r--r--bower_components/moment/src/locale/mr.js4
-rw-r--r--bower_components/moment/src/locale/ms-my.js6
-rw-r--r--bower_components/moment/src/locale/ms.js73
-rw-r--r--bower_components/moment/src/locale/my.js4
-rw-r--r--bower_components/moment/src/locale/nb.js6
-rw-r--r--bower_components/moment/src/locale/ne.js4
-rw-r--r--bower_components/moment/src/locale/nl.js6
-rw-r--r--bower_components/moment/src/locale/nn.js6
-rw-r--r--bower_components/moment/src/locale/pl.js6
-rw-r--r--bower_components/moment/src/locale/pt-br.js8
-rw-r--r--bower_components/moment/src/locale/pt.js6
-rw-r--r--bower_components/moment/src/locale/ro.js2
-rw-r--r--bower_components/moment/src/locale/ru.js6
-rw-r--r--bower_components/moment/src/locale/si.js4
-rw-r--r--bower_components/moment/src/locale/sk.js6
-rw-r--r--bower_components/moment/src/locale/sl.js6
-rw-r--r--bower_components/moment/src/locale/sq.js6
-rw-r--r--bower_components/moment/src/locale/sr-cyrl.js6
-rw-r--r--bower_components/moment/src/locale/sr.js6
-rw-r--r--bower_components/moment/src/locale/sv.js6
-rw-r--r--bower_components/moment/src/locale/ta.js6
-rw-r--r--bower_components/moment/src/locale/th.js6
-rw-r--r--bower_components/moment/src/locale/tl-ph.js6
-rw-r--r--bower_components/moment/src/locale/tr.js6
-rw-r--r--bower_components/moment/src/locale/tzl.js78
-rw-r--r--bower_components/moment/src/locale/tzm-latn.js6
-rw-r--r--bower_components/moment/src/locale/tzm.js6
-rw-r--r--bower_components/moment/src/locale/uk.js6
-rw-r--r--bower_components/moment/src/locale/uz.js6
-rw-r--r--bower_components/moment/src/locale/vi.js10
-rw-r--r--bower_components/moment/src/locale/zh-cn.js8
-rw-r--r--bower_components/moment/src/locale/zh-tw.js8
-rw-r--r--bower_components/moment/src/moment.js4
-rw-r--r--docs/extending.txt38
-rw-r--r--docs/man/nikola.1.gzbin1777 -> 1785 bytes
-rw-r--r--docs/man/nikola.rst4
-rw-r--r--docs/manual.txt896
-rw-r--r--docs/social_buttons.txt2
-rw-r--r--docs/sphinx/conf.py4
-rw-r--r--docs/support.rst14
-rw-r--r--docs/theming.txt4
-rw-r--r--dodo.py9
-rw-r--r--nikola/__init__.py4
-rw-r--r--nikola/__main__.py94
-rw-r--r--nikola/conf.py.in70
-rw-r--r--nikola/data/samplesite/README.txt7
-rw-r--r--nikola/data/samplesite/posts/1.rst10
-rw-r--r--nikola/data/symlinked.txt185
-rw-r--r--nikola/data/themes/base-jinja/templates/archiveindex.tmpl2
-rw-r--r--nikola/data/themes/base-jinja/templates/base.tmpl5
-rw-r--r--nikola/data/themes/base-jinja/templates/base_footer.tmpl2
-rw-r--r--nikola/data/themes/base-jinja/templates/base_header.tmpl4
-rw-r--r--nikola/data/themes/base-jinja/templates/base_helper.tmpl17
-rw-r--r--nikola/data/themes/base-jinja/templates/index.tmpl2
-rw-r--r--nikola/data/themes/base-jinja/templates/list_post.tmpl2
-rw-r--r--nikola/data/themes/base-jinja/templates/post_header.tmpl4
-rw-r--r--nikola/data/themes/base-jinja/templates/post_helper.tmpl4
-rw-r--r--nikola/data/themes/base-jinja/templates/tag.tmpl6
-rw-r--r--nikola/data/themes/base-jinja/templates/tagindex.tmpl2
-rw-r--r--nikola/data/themes/base/assets/css/rst.css122
-rw-r--r--nikola/data/themes/base/assets/css/theme.css1
-rw-r--r--nikola/data/themes/base/messages/messages_bs.py39
-rw-r--r--nikola/data/themes/base/messages/messages_fi.py8
-rw-r--r--nikola/data/themes/base/messages/messages_hr.py8
-rw-r--r--nikola/data/themes/base/messages/messages_it.py4
-rw-r--r--nikola/data/themes/base/messages/messages_nb.py26
-rw-r--r--nikola/data/themes/base/messages/messages_pa.py39
-rw-r--r--nikola/data/themes/base/messages/messages_pt.py68
-rw-r--r--nikola/data/themes/base/messages/messages_sk.py10
-rw-r--r--nikola/data/themes/base/messages/messages_sr.py10
-rw-r--r--nikola/data/themes/base/messages/messages_sr@latin.py39
-rw-r--r--nikola/data/themes/base/messages/messages_sv.py22
-rw-r--r--nikola/data/themes/base/messages/messages_ur.py6
-rw-r--r--nikola/data/themes/base/templates/archiveindex.tmpl2
-rw-r--r--nikola/data/themes/base/templates/base.tmpl5
-rw-r--r--nikola/data/themes/base/templates/base_footer.tmpl2
-rw-r--r--nikola/data/themes/base/templates/base_header.tmpl4
-rw-r--r--nikola/data/themes/base/templates/base_helper.tmpl17
-rw-r--r--nikola/data/themes/base/templates/index.tmpl2
-rw-r--r--nikola/data/themes/base/templates/list_post.tmpl2
-rw-r--r--nikola/data/themes/base/templates/post_header.tmpl4
-rw-r--r--nikola/data/themes/base/templates/post_helper.tmpl4
-rw-r--r--nikola/data/themes/base/templates/tag.tmpl6
-rw-r--r--nikola/data/themes/base/templates/tagindex.tmpl2
-rw-r--r--nikola/data/themes/bootstrap-jinja/AUTHORS.txt1
-rw-r--r--nikola/data/themes/bootstrap-jinja/README.md23
-rw-r--r--nikola/data/themes/bootstrap-jinja/assets/css/theme.css205
l---------nikola/data/themes/bootstrap-jinja/bundles1
-rw-r--r--nikola/data/themes/bootstrap-jinja/engine1
-rw-r--r--nikola/data/themes/bootstrap-jinja/parent1
-rw-r--r--nikola/data/themes/bootstrap-jinja/templates/base.tmpl93
-rw-r--r--nikola/data/themes/bootstrap-jinja/templates/base_helper.tmpl184
-rw-r--r--nikola/data/themes/bootstrap-jinja/templates/gallery.tmpl94
-rw-r--r--nikola/data/themes/bootstrap-jinja/templates/listing.tmpl28
-rw-r--r--nikola/data/themes/bootstrap-jinja/templates/slides.tmpl24
-rw-r--r--nikola/data/themes/bootstrap/README.md23
-rw-r--r--nikola/data/themes/bootstrap/assets/css/theme.css205
-rw-r--r--nikola/data/themes/bootstrap/bundles4
-rw-r--r--nikola/data/themes/bootstrap/engine1
-rw-r--r--nikola/data/themes/bootstrap/parent1
-rw-r--r--nikola/data/themes/bootstrap/templates/base.tmpl93
-rw-r--r--nikola/data/themes/bootstrap/templates/base_helper.tmpl184
-rw-r--r--nikola/data/themes/bootstrap/templates/gallery.tmpl94
-rw-r--r--nikola/data/themes/bootstrap/templates/listing.tmpl28
-rw-r--r--nikola/data/themes/bootstrap/templates/slides.tmpl24
-rw-r--r--nikola/data/themes/bootstrap3-jinja/README.md2
l---------nikola/data/themes/bootstrap3-jinja/assets/css/colorbox.css (renamed from nikola/data/themes/bootstrap-jinja/assets/css/colorbox.css)0
l---------nikola/data/themes/bootstrap3-jinja/assets/css/images/controls.png (renamed from nikola/data/themes/bootstrap-jinja/assets/css/images/controls.png)0
l---------nikola/data/themes/bootstrap3-jinja/assets/css/images/loading.gif (renamed from nikola/data/themes/bootstrap-jinja/assets/css/images/loading.gif)0
-rw-r--r--nikola/data/themes/bootstrap3-jinja/assets/css/theme.css6
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js)0
-rw-r--r--nikola/data/themes/bootstrap3-jinja/assets/js/flowr.plugin.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/flowr.plugin.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/jquery.colorbox.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/jquery.colorbox.js)0
l---------nikola/data/themes/bootstrap3-jinja/assets/js/jquery.js (renamed from nikola/data/themes/bootstrap-jinja/assets/js/jquery.js)0
-rw-r--r--nikola/data/themes/bootstrap3-jinja/parent2
-rw-r--r--nikola/data/themes/bootstrap3-jinja/templates/base.tmpl6
-rw-r--r--nikola/data/themes/bootstrap3-jinja/templates/base_helper.tmpl19
-rw-r--r--nikola/data/themes/bootstrap3-jinja/templates/post.tmpl (renamed from nikola/data/themes/bootstrap-jinja/templates/post.tmpl)0
-rw-r--r--nikola/data/themes/bootstrap3-jinja/templates/tags.tmpl (renamed from nikola/data/themes/bootstrap-jinja/templates/tags.tmpl)0
-rw-r--r--nikola/data/themes/bootstrap3/README.md2
l---------nikola/data/themes/bootstrap3/assets/css/colorbox.css (renamed from nikola/data/themes/bootstrap/assets/css/colorbox.css)0
l---------nikola/data/themes/bootstrap3/assets/css/images/controls.png (renamed from nikola/data/themes/bootstrap/assets/css/images/controls.png)0
l---------nikola/data/themes/bootstrap3/assets/css/images/loading.gif (renamed from nikola/data/themes/bootstrap/assets/css/images/loading.gif)0
-rw-r--r--nikola/data/themes/bootstrap3/assets/css/theme.css6
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ar.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ar.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bg.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bg.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bn.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bn.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ca.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ca.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-cs.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-cs.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-da.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-da.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-de.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-de.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-es.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-es.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-et.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-et.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fa.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fa.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fi.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fi.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gl.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gl.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-he.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-he.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hu.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hu.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-id.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-id.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-it.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-it.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ja.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ja.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-kr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-kr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lt.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lt.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lv.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lv.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-my.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-my.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-nl.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-nl.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-no.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-no.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pl.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pl.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ro.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ro.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ru.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ru.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-si.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-si.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sk.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sk.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sv.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sv.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-tr.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-tr.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-uk.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-uk.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js)0
l---------nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js (renamed from nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js)0
-rw-r--r--nikola/data/themes/bootstrap3/assets/js/flowr.plugin.js (renamed from nikola/data/themes/bootstrap/assets/js/flowr.plugin.js)0
l---------nikola/data/themes/bootstrap3/assets/js/jquery.colorbox.js (renamed from nikola/data/themes/bootstrap/assets/js/jquery.colorbox.js)0
l---------nikola/data/themes/bootstrap3/assets/js/jquery.js (renamed from nikola/data/themes/bootstrap/assets/js/jquery.js)0
-rw-r--r--nikola/data/themes/bootstrap3/parent2
-rw-r--r--nikola/data/themes/bootstrap3/templates/base.tmpl6
-rw-r--r--nikola/data/themes/bootstrap3/templates/base_helper.tmpl19
-rw-r--r--nikola/data/themes/bootstrap3/templates/post.tmpl (renamed from nikola/data/themes/bootstrap/templates/post.tmpl)0
-rw-r--r--nikola/data/themes/bootstrap3/templates/tags.tmpl (renamed from nikola/data/themes/bootstrap/templates/tags.tmpl)0
-rw-r--r--nikola/filters.py37
-rw-r--r--nikola/image_processing.py3
-rw-r--r--nikola/nikola.py322
-rw-r--r--nikola/packages/__init__.py2
-rw-r--r--nikola/packages/tzlocal/__init__.py2
-rw-r--r--nikola/packages/tzlocal/darwin.py3
-rw-r--r--nikola/packages/tzlocal/unix.py8
-rw-r--r--nikola/packages/tzlocal/win32.py5
-rw-r--r--nikola/packages/tzlocal/windows_tz.py1
-rw-r--r--nikola/plugin_categories.py126
-rw-r--r--nikola/plugins/__init__.py3
-rw-r--r--nikola/plugins/basic_import.py14
-rw-r--r--nikola/plugins/command/__init__.py2
-rw-r--r--nikola/plugins/command/auto.plugin16
-rw-r--r--nikola/plugins/command/auto/__init__.py196
-rw-r--r--nikola/plugins/command/bootswatch_theme.plugin15
-rw-r--r--nikola/plugins/command/bootswatch_theme.py3
-rw-r--r--nikola/plugins/command/check.plugin15
-rw-r--r--nikola/plugins/command/check.py70
-rw-r--r--nikola/plugins/command/console.plugin16
-rw-r--r--nikola/plugins/command/console.py4
-rw-r--r--nikola/plugins/command/deploy.plugin16
-rw-r--r--nikola/plugins/command/deploy.py12
-rw-r--r--nikola/plugins/command/github_deploy.plugin16
-rw-r--r--nikola/plugins/command/github_deploy.py19
-rw-r--r--nikola/plugins/command/import_wordpress.plugin15
-rw-r--r--nikola/plugins/command/import_wordpress.py666
-rw-r--r--nikola/plugins/command/init.plugin16
-rw-r--r--nikola/plugins/command/init.py43
-rw-r--r--nikola/plugins/command/install_theme.plugin15
-rw-r--r--nikola/plugins/command/install_theme.py28
-rw-r--r--nikola/plugins/command/new_page.plugin16
-rw-r--r--nikola/plugins/command/new_page.py3
-rw-r--r--nikola/plugins/command/new_post.plugin15
-rw-r--r--nikola/plugins/command/new_post.py236
-rw-r--r--nikola/plugins/command/orphans.plugin15
-rw-r--r--nikola/plugins/command/orphans.py6
-rw-r--r--nikola/plugins/command/plugin.plugin15
-rw-r--r--nikola/plugins/command/plugin.py88
-rw-r--r--nikola/plugins/command/rst2html.plugin16
-rw-r--r--nikola/plugins/command/rst2html/__init__.py3
-rw-r--r--nikola/plugins/command/serve.plugin15
-rw-r--r--nikola/plugins/command/serve.py83
-rw-r--r--nikola/plugins/command/status.plugin16
-rw-r--r--nikola/plugins/command/status.py11
-rw-r--r--nikola/plugins/command/version.plugin16
-rw-r--r--nikola/plugins/command/version.py5
-rw-r--r--nikola/plugins/compile/__init__.py2
-rw-r--r--nikola/plugins/compile/html.plugin15
-rw-r--r--nikola/plugins/compile/html.py4
-rw-r--r--nikola/plugins/compile/ipynb.plugin15
-rw-r--r--nikola/plugins/compile/ipynb.py26
-rw-r--r--nikola/plugins/compile/markdown.plugin15
-rw-r--r--nikola/plugins/compile/markdown/__init__.py13
-rw-r--r--nikola/plugins/compile/markdown/mdx_gist.plugin17
-rw-r--r--nikola/plugins/compile/markdown/mdx_gist.py68
-rw-r--r--nikola/plugins/compile/markdown/mdx_nikola.plugin17
-rw-r--r--nikola/plugins/compile/markdown/mdx_nikola.py14
-rw-r--r--nikola/plugins/compile/markdown/mdx_podcast.plugin17
-rw-r--r--nikola/plugins/compile/markdown/mdx_podcast.py27
-rw-r--r--nikola/plugins/compile/pandoc.plugin15
-rw-r--r--nikola/plugins/compile/pandoc.py5
-rw-r--r--nikola/plugins/compile/php.plugin15
-rw-r--r--nikola/plugins/compile/php.py4
-rw-r--r--nikola/plugins/compile/rest.plugin15
-rw-r--r--nikola/plugins/compile/rest/__init__.py40
-rw-r--r--nikola/plugins/compile/rest/chart.plugin16
-rw-r--r--nikola/plugins/compile/rest/chart.py25
-rw-r--r--nikola/plugins/compile/rest/doc.plugin16
-rw-r--r--nikola/plugins/compile/rest/doc.py7
-rw-r--r--nikola/plugins/compile/rest/gist.plugin16
-rw-r--r--nikola/plugins/compile/rest/gist.py19
-rw-r--r--nikola/plugins/compile/rest/listing.plugin16
-rw-r--r--nikola/plugins/compile/rest/listing.py17
-rw-r--r--nikola/plugins/compile/rest/media.plugin16
-rw-r--r--nikola/plugins/compile/rest/media.py9
-rw-r--r--nikola/plugins/compile/rest/post_list.plugin17
-rw-r--r--nikola/plugins/compile/rest/post_list.py26
-rw-r--r--nikola/plugins/compile/rest/slides.plugin16
-rw-r--r--nikola/plugins/compile/rest/slides.py12
-rw-r--r--nikola/plugins/compile/rest/soundcloud.plugin16
-rw-r--r--nikola/plugins/compile/rest/soundcloud.py17
-rw-r--r--nikola/plugins/compile/rest/thumbnail.plugin17
-rw-r--r--nikola/plugins/compile/rest/thumbnail.py10
-rw-r--r--nikola/plugins/compile/rest/vimeo.plugin10
-rw-r--r--nikola/plugins/compile/rest/vimeo.py20
-rw-r--r--nikola/plugins/compile/rest/youtube.plugin12
-rw-r--r--nikola/plugins/compile/rest/youtube.py13
-rw-r--r--nikola/plugins/loghandler/smtp.plugin9
-rw-r--r--nikola/plugins/loghandler/smtp.py54
-rw-r--r--nikola/plugins/loghandler/stderr.plugin9
-rw-r--r--nikola/plugins/loghandler/stderr.py56
-rw-r--r--nikola/plugins/misc/__init__.py (renamed from nikola/plugins/loghandler/__init__.py)2
-rw-r--r--nikola/plugins/misc/scan_posts.py6
-rw-r--r--nikola/plugins/task/__init__.py2
-rw-r--r--nikola/plugins/task/archive.plugin15
-rw-r--r--nikola/plugins/task/archive.py26
-rw-r--r--nikola/plugins/task/bundles.plugin15
-rw-r--r--nikola/plugins/task/bundles.py7
-rw-r--r--nikola/plugins/task/copy_assets.plugin15
-rw-r--r--nikola/plugins/task/copy_assets.py4
-rw-r--r--nikola/plugins/task/copy_files.plugin15
-rw-r--r--nikola/plugins/task/copy_files.py4
-rw-r--r--nikola/plugins/task/galleries.plugin15
-rw-r--r--nikola/plugins/task/galleries.py52
-rw-r--r--nikola/plugins/task/gzip.plugin15
-rw-r--r--nikola/plugins/task/gzip.py3
-rw-r--r--nikola/plugins/task/indexes.plugin15
-rw-r--r--nikola/plugins/task/indexes.py22
-rw-r--r--nikola/plugins/task/listings.plugin15
-rw-r--r--nikola/plugins/task/listings.py26
-rw-r--r--nikola/plugins/task/pages.plugin15
-rw-r--r--nikola/plugins/task/pages.py10
-rw-r--r--nikola/plugins/task/posts.plugin15
-rw-r--r--nikola/plugins/task/posts.py12
-rw-r--r--nikola/plugins/task/redirect.plugin15
-rw-r--r--nikola/plugins/task/redirect.py6
-rw-r--r--nikola/plugins/task/robots.plugin15
-rw-r--r--nikola/plugins/task/robots.py7
-rw-r--r--nikola/plugins/task/rss.plugin15
-rw-r--r--nikola/plugins/task/rss.py5
-rw-r--r--nikola/plugins/task/scale_images.plugin16
-rw-r--r--nikola/plugins/task/scale_images.py13
-rw-r--r--nikola/plugins/task/sitemap.plugin15
-rw-r--r--nikola/plugins/task/sitemap/__init__.py44
-rw-r--r--nikola/plugins/task/sources.plugin15
-rw-r--r--nikola/plugins/task/sources.py13
-rw-r--r--nikola/plugins/task/tags.plugin15
-rw-r--r--nikola/plugins/task/tags.py44
-rw-r--r--nikola/plugins/template/__init__.py2
-rw-r--r--nikola/plugins/template/jinja.plugin16
-rw-r--r--nikola/plugins/template/jinja.py19
-rw-r--r--nikola/plugins/template/mako.plugin16
-rw-r--r--nikola/plugins/template/mako.py28
-rw-r--r--nikola/post.py176
-rw-r--r--nikola/rc4.py11
-rw-r--r--nikola/utils.py216
-rw-r--r--nikola/winutils.py5
-rw-r--r--requirements-extras.txt2
-rw-r--r--requirements-tests.txt6
-rw-r--r--requirements.txt4
-rw-r--r--scripts/INTERNAL USE ONLY0
-rwxr-xr-xscripts/getwheelhouse.sh2
-rwxr-xr-xscripts/jinjify.py9
-rwxr-xr-xscripts/update-bower.sh10
-rwxr-xr-xsetup.py2
-rw-r--r--tests/base.py24
-rw-r--r--tests/data/1-nolinks.rst28
-rw-r--r--tests/test_command_import_wordpress.py67
-rw-r--r--tests/test_integration.py6
-rw-r--r--tests/test_rss_feeds.py6
-rw-r--r--tests/test_slugify.py65
-rw-r--r--tests/test_utils.py70
-rw-r--r--translations/nikola.messages/bs.po132
-rw-r--r--translations/nikola.messages/fi.po15
-rw-r--r--translations/nikola.messages/hr.po15
-rw-r--r--translations/nikola.messages/it.po6
-rw-r--r--translations/nikola.messages/nb.po33
-rw-r--r--translations/nikola.messages/pa.po132
-rw-r--r--translations/nikola.messages/pt.po75
-rw-r--r--translations/nikola.messages/sk.po17
-rw-r--r--translations/nikola.messages/sr.po17
-rw-r--r--translations/nikola.messages/sr@latin.po132
-rw-r--r--translations/nikola.messages/sv.po28
-rw-r--r--translations/nikola.messages/ur.po10
556 files changed, 8202 insertions, 5388 deletions
diff --git a/.coveragerc b/.coveragerc
index 0cca61d..bdb3944 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,6 +1,6 @@
[run]
source = nikola
-omit = /tmp/*, _*
+omit = /tmp/*, _*, nikola/packages*, nikola/data*, nikola/winutils*
[report]
exclude_lines =
pragma: no cover
diff --git a/.pypt/ghrel b/.pypt/ghrel
index 26463c5..c34dc22 100755
--- a/.pypt/ghrel
+++ b/.pypt/ghrel
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Kw’s Release Tools/Python Project Template
-# GitHub Releases Creator
+# GitHub Release Creator
# Copyright © 2013-2015, Chris Warrick.
# All rights reserved.
#
@@ -33,58 +33,78 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# Arguments:
-# FILE BASEDIR REPO TAG
-
"""
Create GitHub releases out of changelogs.
-Usage: .pypt/commitlog FILE BASEDIR REPO TAG, where
+Usage: .pypt/commitlog FILE BASEDIR REPOSITORY TAG, where
FILE is the path to the file to use, which can be
a plain .md file or a CMFN file,
BASEDIR is the project directory,
- REPO is the full GitHub repository name (user/repo),
+ REPOSITORY is the full GitHub repository name (user/repo),
TAG is the tag to write to.
All paths should be absolute.
"""
+import argparse
+import json
import re
import requests
-import json
+import sys
from os.path import join as pjoin
-from sys import argv
-_script, FILE, BASEDIR, REPO, TAG = argv
-with open(pjoin(BASEDIR, '.pypt', 'gh-token')) as fh:
- TOKEN = fh.read().strip()
+def main():
+ """ghrel main function."""
+ parser = argparse.ArgumentParser(
+ description="GitHub Release Creator "
+ "(part of Chris Warrick's Python Project Template)")
+ parser.add_argument('filename', metavar='FILE', nargs=1,
+ help='File to parse (Markdown or commitlog)')
+ parser.add_argument('basedir', metavar='BASEDIR', nargs=1,
+ help='Project directory (must contain .pypt/gh-token)')
+ parser.add_argument('repo', metavar='REPOSITORY', nargs=1,
+ help='GitHub repository (owner/repo)')
+ parser.add_argument('tag', metavar='TAG', nargs=1,
+ help='Tag to create release for (vX.Y.Z)')
+ args = parser.parse_args()
+ # nargs gets you lists, not strings
+ filename = args.filename[0]
+ basedir = args.basedir[0]
+ repo = args.repo[0]
+ tag = args.tag[0]
-HEADERS = {
- 'User-Agent': 'Kwpolska/python-project-template',
- 'Authorization': 'token ' + TOKEN,
-}
+ with open(pjoin(basedir, '.pypt', 'gh-token')) as fh:
+ token = fh.read().strip()
-with open(FILE) as fh:
- fdata = fh.read()
- e = re.findall(
- '#~ CHANGELOG MESSAGE START ~#\n(.*?)\n#~ CHANGELOG MESSAGE END ~#',
- fdata, flags=re.S)
+ headers = {
+ 'User-Agent': 'Kwpolska/python-project-template',
+ 'Authorization': 'token ' + token,
+ }
- if e:
- # parse as a CMFN file, replace backticks (reST->Markdown)
- message = e[0].replace('``', '`')
- else:
- # parse as a plain Markdown file
- message = fdata
+ with open(filename) as fh:
+ fdata = fh.read()
+ e = re.findall(
+ '#~ CHANGELOG MESSAGE START ~#\n(.*?)\n'
+ '#~ CHANGELOG MESSAGE END ~#',
+ fdata, flags=re.S)
+
+ if e:
+ # parse as a CMFN file, replace backticks (reST -> Markdown)
+ message = e[0].replace('``', '`')
+ else:
+ # parse as a plain Markdown file
+ message = fdata
+ r = requests.post(
+ 'https://api.github.com/repos/{0}/releases'.format(repo),
+ data=json.dumps({'tag_name': tag, 'body': message}),
+ headers=headers)
-r = requests.post(
- 'https://api.github.com/repos/{0}/releases'.format(REPO),
- data=json.dumps({'tag_name': TAG, 'body': message}),
- headers=HEADERS)
+ if r.status_code == 201:
+ print("GitHub Release created: {0}".format(r.json()['html_url']))
+ else:
+ print("GitHub Release failed: {0}".format(r.text))
+ return 1
-if r.status_code == 201:
- print("GitHub Release created: {0}".format(r.json()['url']))
-else:
- print("GitHub Release failed: {0}".format(r.text))
- exit(1)
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/.travis.yml b/.travis.yml
index 123e481..f3b4857 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,13 @@
before_install:
- - "if [[ $NMODE == 'nikola' ]]; then sudo apt-get update -qq || true; fi"
- - "if [[ $NMODE == 'nikola' ]]; then sudo apt-get --reinstall install -qq language-pack-en-base language-pack-pl-base; fi"
- "pip install --upgrade pip wheel"
language: python
cache: apt
+sudo: false
+addons:
+ apt:
+ packages:
+ - language-pack-en-base
+ - language-pack-pl-base
python:
- "2.7"
- "3.3"
@@ -19,17 +23,18 @@ install:
- "if [[ $NMODE == 'nikola' ]]; then pip install -r requirements-tests.txt; if [[ \"$?\" == '1' ]]; then cat /home/travis/.pip/pip.log; false; fi; fi"
- "if [[ $NMODE == 'nikola' ]]; then pip install .; fi"
- "if [[ $NMODE == 'nikola' ]]; then scripts/getbaseline.sh $(scripts/getpyver.py short); fi"
- - "if [[ $NMODE == 'flake8' ]]; then pip install flake8; fi"
+ - "if [[ $NMODE == 'flake8' ]]; then pip install flake8 pep257; fi"
# We run tests and nikola (to see if the command is executable) OR flake8.
# We run `nikola` and `nikola help` because things may break due to human
# errors in argument parsing (cf. 96e78dd)
-# WARNING: if you edit this, make sure to replicate your changes in dodo.py.
+# WARNING: if you edit this, make sure to replicate your changes in dodo.py and appveyor.yml.
script:
- "if [[ $NMODE == 'nikola' ]]; then py.test --doctest-modules nikola/; fi"
- "if [[ $NMODE == 'nikola' ]]; then py.test --cov nikola --cov-report term-missing tests/; fi"
- "if [[ $NMODE == 'nikola' ]]; then nikola; fi"
- "if [[ $NMODE == 'nikola' ]]; then nikola help; fi"
- "if [[ $NMODE == 'flake8' ]]; then flake8 nikola/; fi"
+ - "if [[ $NMODE == 'flake8' ]]; then pep257 --count --match-dir='(?!^\\\\.)(?!data).*' nikola/; fi"
after_success:
- "if [[ $NMODE == 'nikola' ]]; then coveralls; fi"
notifications:
diff --git a/AUTHORS.txt b/AUTHORS.txt
index 0f2f8c8..94c3f68 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -1,106 +1,107 @@
-Agustin Henze <https://github.com/agustinhenze>
-Alberto Berti <https://github.com/azazel75>
-Alex Popescu <https://github.com/al3xandru>
-Alex Walters <https://github.com/tritium21>
-Andreas Linz <https://github.com/KLINGTdotNET>
-Areski Belaid <https://github.com/areski>
-Aru Sahni <https://github.com/arusahni>
-Aurelien Naldi <https://github.com/aurelien-naldi>
-Ben Mather <https://github.com/bwhmather>
-Boris Kaul <https://github.com/localvoid>
-Brandon W. Maister <https://github.com/quodlibetor>
-Bussonnier Matthias <https://gtihub.com/carreau>
-Carsten Grohmann <https://github.com/CarstenGrohmann>
-Casey M. Bessette <https://github.com/caseybessette>
-Chris Lee <https://github.com/clee>
-Chris Warrick <https://github.com/Kwpolska>
-Claudio Canepa <https://github.com/ccanepa>
-Damien Tournoud <https://github.com/damz>
-Damián Avila <https://github.com/damianavila>
-Daniel Aleksandersen <https://github.com/Aeyoun>
-Daniel Devine <https://github.com/DDevine>
-Daniel F. Moisset <https://github.com/dmoisset>
-David Beath <https://github.com/DBeath>
-Dhruv Baldawa <https://github.com/dhruvbaldawa>
-Dirk Engling <https://github.com/erdgeist>
-Dmitry Verkhoturov <https://github.com/paskal>
-Duncan Lock <https://github.com/dflock>
-Edinei Cavalcanti <https://github.com/neiesc>
-Eduardo Schettino <https://github.com/schettino72>
-Edwin Steele <https://github.com/edwinsteele>
-Emilien Klein <https://github.com/e2jk>
-Evgeni Golov <https://github.com/evgeni>
-Felix Fontein <https://github.com/felixfontein>
-Felix Schwarz <https://github.com/FelixSchwarz>
-Grzegorz Śliwiński <https://github.com/fizyk>
-Guillermo O. Freschi <https://github.com/Tordek>
-Hardening <https://github.com/hardening>
-Ivan Teoh <https://github.com/ivanteoh>
-John Kristensen <https://github.com/jerrykan>
-Joshua Barratt <https://github.com/jbarratt>
-Juan Pedro Fisanotti <https://github.com/fisadev>
-Kade For <https://github.com/kadefor>
-Kay Hayen <https://github.com/kayhayen>
-Leandro Poblet <https://github.com/DoctorMalboro>
-Luis Miguel Morillas <https://github.com/lmorillas>
-Manuel Kaufmann <https://github.com/humitos>
-Marcelo MD <https://github.com/marcelomd>
-Marcos Dione <https://github.com/StyXman>
-Mariano Guerra <https://github.com/marianoguerra>
-Mario Pozzo <https://github.com/camboris>
-Mark Eichin <https://github.com/eichin>
-Martin Bless <https://github.com/marble>
-Martin Wimpress <https://github.com/wimpr1m>
-Martín Gaitán <https://github.com/mgaitan>
-Matias Novoa <https://github.com/mattgaviota>
-Michael Joseph <https://github.com/michaeljoseph>
-Michael McNeil Forbes <https://github.com/mforbes>
-Michal Petrucha <https://github.com/koniiiik>
-Miguel Ángel García <https://github.com/magmax>
-Neil MartinsenBurrell <https://github.com/neilmb>
-Niko Wenselowski <https://github.com/okin>
-Nikola Kotur <https://github.com/kotnik>
-Ondřej Grover <https://github.com/smartass101>
-Onno Broekmans <https://github.com/onnodb>
-Pablo Seminario <https://github.com/pabluk>
-Patrick Wildt <https://github.com/Bluerise>
-Paul Ivanov <https://github.com/ivanov>
-Pelle Nilsson <https://github.com/pellenilsson>
-Pierpaolo Da Fieno <https://github.com/numshub>
-Puneeth Chaganti <https://github.com/punchagan>
-Raimon Esteve <https://github.com/raimonesteve>
-Ramiro Morales <https://github.com/ramiro>
-Roberto Alsina <https://github.com/ralsina>
-Rodrigo Bistolfi <https://github.com/rbistolfi>
-Roger Binns <https://github.com/rogerbinns>
-Roman Faizullin <https://github.com/faizrr>
-Roman Imankulov <https://github.com/imankulov>
-Santiago Pestarini <https://github.com/quijot>
-Sean Pue <https://github.com/seanpue>
-Simon van der Veldt <https://github.com/simonvanderveldt>
-Stefan Näwe <https://github.com/snaewe>
-Thibauld Nion <https://github.com/tibonihoo>
-Thomas Burette <https://github.com/tburette>
-Tim Chase <https://github.com/Gumnos>
-Tolu Sonaike <https://github.com/tolusonaike>
-Troy Toman <https://github.com/troytoman>
-Udo Spallek <https://github.com/udono>
-Yaşar Arabacı <https://github.com/yasar11732>
-Yasuhiko Shiga <https://github.com/quoth>
-Zhaojun Meng <https://github.com/zhaojunmeng>
-dastagg <https://github.com/dastagg>
-dastagg <https://github.com/dastagg>
-ermeaney <https://github.com/ermeaney>
-follower <https://github.com/follower>
-lbiaggi <https://github.com/lbiaggi>
-mrabbitt <https://github.com/mrabbitt>
-nlaurens <https://github.com/nlaurens>
-notfoss <https://github.com/notfoss>
-phora <https://github.com/phora>
-pmav99 <https://github.com/pmav99>
-pwm1234 <https://github.com/pwm1234>
-rafacarrascosa <https://github.com/rafacarrascosa>
-yarko <https://github.com/yarko>
-小明 <https://github.com/dongweiming>
-Brad Miller <https://github.com/bnmnetp>
-
+* `Agustin Henze <https://github.com/agustinhenze>`_
+* `Alberto Berti <https://github.com/azazel75>`_
+* `Alex Popescu <https://github.com/al3xandru>`_
+* `Alex Walters <https://github.com/tritium21>`_
+* `Andreas Linz <https://github.com/KLINGTdotNET>`_
+* `Areski Belaid <https://github.com/areski>`_
+* `Aru Sahni <https://github.com/arusahni>`_
+* `Aurelien Naldi <https://github.com/aurelien-naldi>`_
+* `Ben Mather <https://github.com/bwhmather>`_
+* `Boris Kaul <https://github.com/localvoid>`_
+* `Brandon W. Maister <https://github.com/quodlibetor>`_
+* `Bussonnier Matthias <https://gtihub.com/carreau>`_
+* `Carlos Martín Sánchez <https://github.com/carlosvin>`_
+* `Carsten Grohmann <https://github.com/CarstenGrohmann>`_
+* `Casey M. Bessette <https://github.com/caseybessette>`_
+* `Chris Lee <https://github.com/clee>`_
+* `Chris Warrick <https://github.com/Kwpolska>`_
+* `Claudio Canepa <https://github.com/ccanepa>`_
+* `Damien Tournoud <https://github.com/damz>`_
+* `Damián Avila <https://github.com/damianavila>`_
+* `Daniel Aleksandersen <https://github.com/Aeyoun>`_
+* `Daniel Devine <https://github.com/DDevine>`_
+* `Daniel F. Moisset <https://github.com/dmoisset>`_
+* `David Beath <https://github.com/DBeath>`_
+* `Dhruv Baldawa <https://github.com/dhruvbaldawa>`_
+* `Dirk Engling <https://github.com/erdgeist>`_
+* `Dmitry Verkhoturov <https://github.com/paskal>`_
+* `Duncan Lock <https://github.com/dflock>`_
+* `Edinei Cavalcanti <https://github.com/neiesc>`_
+* `Eduardo Schettino <https://github.com/schettino72>`_
+* `Edwin Steele <https://github.com/edwinsteele>`_
+* `Emilien Klein <https://github.com/e2jk>`_
+* `Evgeni Golov <https://github.com/evgeni>`_
+* `Felix Fontein <https://github.com/felixfontein>`_
+* `Felix Schwarz <https://github.com/FelixSchwarz>`_
+* `Grzegorz Śliwiński <https://github.com/fizyk>`_
+* `Guillermo O. Freschi <https://github.com/Tordek>`_
+* `Hardening <https://github.com/hardening>`_
+* `Ivan Teoh <https://github.com/ivanteoh>`_
+* `John Kristensen <https://github.com/jerrykan>`_
+* `Joshua Barratt <https://github.com/jbarratt>`_
+* `Juan Pedro Fisanotti <https://github.com/fisadev>`_
+* `Kade For <https://github.com/kadefor>`_
+* `Kay Hayen <https://github.com/kayhayen>`_
+* `Leandro Poblet <https://github.com/DoctorMalboro>`_
+* `Luis Miguel Morillas <https://github.com/lmorillas>`_
+* `Manuel Kaufmann <https://github.com/humitos>`_
+* `Marcelo MD <https://github.com/marcelomd>`_
+* `Marcos Dione <https://github.com/StyXman>`_
+* `Mariano Guerra <https://github.com/marianoguerra>`_
+* `Mario Pozzo <https://github.com/camboris>`_
+* `Mark Eichin <https://github.com/eichin>`_
+* `Martin Bless <https://github.com/marble>`_
+* `Martin Wimpress <https://github.com/wimpr1m>`_
+* `Martín Gaitán <https://github.com/mgaitan>`_
+* `Matias Novoa <https://github.com/mattgaviota>`_
+* `Michael Joseph <https://github.com/michaeljoseph>`_
+* `Michael McNeil Forbes <https://github.com/mforbes>`_
+* `Michal Petrucha <https://github.com/koniiiik>`_
+* `Miguel Ángel García <https://github.com/magmax>`_
+* `Neil MartinsenBurrell <https://github.com/neilmb>`_
+* `Niko Wenselowski <https://github.com/okin>`_
+* `Nikola Kotur <https://github.com/kotnik>`_
+* `Ondřej Grover <https://github.com/smartass101>`_
+* `Onno Broekmans <https://github.com/onnodb>`_
+* `Pablo Seminario <https://github.com/pabluk>`_
+* `Patrick Wildt <https://github.com/Bluerise>`_
+* `Paul Ivanov <https://github.com/ivanov>`_
+* `Pelle Nilsson <https://github.com/pellenilsson>`_
+* `Pierpaolo Da Fieno <https://github.com/numshub>`_
+* `Puneeth Chaganti <https://github.com/punchagan>`_
+* `Raimon Esteve <https://github.com/raimonesteve>`_
+* `Ramiro Morales <https://github.com/ramiro>`_
+* `Roberto Alsina <https://github.com/ralsina>`_
+* `Rodrigo Bistolfi <https://github.com/rbistolfi>`_
+* `Roger Binns <https://github.com/rogerbinns>`_
+* `Roman Faizullin <https://github.com/faizrr>`_
+* `Roman Imankulov <https://github.com/imankulov>`_
+* `Santiago Pestarini <https://github.com/quijot>`_
+* `Sean Pue <https://github.com/seanpue>`_
+* `Simon van der Veldt <https://github.com/simonvanderveldt>`_
+* `Stefan Näwe <https://github.com/snaewe>`_
+* `Thibauld Nion <https://github.com/tibonihoo>`_
+* `Thomas Burette <https://github.com/tburette>`_
+* `Tim Chase <https://github.com/Gumnos>`_
+* `Tolu Sonaike <https://github.com/tolusonaike>`_
+* `Troy Toman <https://github.com/troytoman>`_
+* `Udo Spallek <https://github.com/udono>`_
+* `Yamila Moreno <https://github.com/yamila-moreno>`_
+* `Yaşar Arabacı <https://github.com/yasar11732>`_
+* `Yasuhiko Shiga <https://github.com/quoth>`_
+* `Zhaojun Meng <https://github.com/zhaojunmeng>`_
+* `dastagg <https://github.com/dastagg>`_
+* `dastagg <https://github.com/dastagg>`_
+* `ermeaney <https://github.com/ermeaney>`_
+* `follower <https://github.com/follower>`_
+* `lbiaggi <https://github.com/lbiaggi>`_
+* `mrabbitt <https://github.com/mrabbitt>`_
+* `nlaurens <https://github.com/nlaurens>`_
+* `notfoss <https://github.com/notfoss>`_
+* `phora <https://github.com/phora>`_
+* `pmav99 <https://github.com/pmav99>`_
+* `pwm1234 <https://github.com/pwm1234>`_
+* `rafacarrascosa <https://github.com/rafacarrascosa>`_
+* `yarko <https://github.com/yarko>`_
+* `小明 <https://github.com/dongweiming>`_
+* `Brad Miller <https://github.com/bnmnetp>`_
diff --git a/CHANGES.txt b/CHANGES.txt
index ea3cd93..426b577 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,131 @@
+New in v7.6.4
+=============
+
+Features
+--------
+
+* Checking remote links also checks redirects (nikola check -lr)
+* Update suggested license to its latest version (Issue #1950)
+* Add Punjabi language, by Jasdeep Singh (Issue #1940)
+* New option to use custom, and several ``TEASER_END`` values
+
+Bugfixes
+--------
+
+* Rewrite srcset links (Issue #1939)
+* Add dependencies for include tag in Mako (Issue #1956)
+* Don’t duplicate BLOG_TITLE in the front page title (Issue #1952)
+* Escape instad of strip HTML in titles (Issue #1952)
+* Make LINK_CHECK_WHITELIST apply to remote link checks
+* Make STORY_INDEX work together with PRETTY_URLS (Issue #1949)
+* Refactor new_post to match lazy plugin loading (Issue #1943)
+* Make Nikola startup faster by not loading useless plugins (Issue #1825)
+* Ignore sliced multibyte characters when reading metadata for sitemaps
+* Fix NameError caused by failed import in auto plugin.
+
+New in v7.6.3
+=============
+
+Features
+--------
+
+* New translations: Serbian and Bosnian, by saleone
+* Added mechanism for rest extensions to depend on configuration options
+ (Issue #1919)
+* Render Jupyter notebooks (ipynb) in listings (Issue #1900)
+
+Bugfixes
+--------
+
+* Ignore sliced multibyte characters when reading metadata for sitemaps
+* Handle folders without trailing slashes in nikola auto (Issue #1933)
+* Set a base element to aid relative URL resolution, stripped on-the-fly
+ when using the auto or serve command to view site locally. (Issue #1922)
+* Rebuild archives when post slugs and titles change (Issue #1931)
+* Handle special characters in URLs in nikola auto (Issue #1925)
+* Avoid Broken Pipe error in nikola auto (Issue #1906)
+* "nikola auto" serving implicit index.html with wrong mime type (Issue #1921)
+* Handle non-integer shutter speeds and other variables in WordPress
+ importer (Issue #1917)
+
+
+New in v7.6.2
+=============
+
+Features
+--------
+
+* Make the Google Search example prettier, integrating well with
+ Bootstrap 3 (Issue #1912)
+* Add categories filter to post list directive (via Issue #1889)
+* Remove empty directories with nikola check --clean-files (Issue #1873)
+
+Bugfixes
+--------
+
+* Don't auto-rebuild on changes to ".foo" or "foo~" or changes in folders.
+* Don't assume things are HTML in auto mode (Issue #1915)
+* Don’t rebuild Atom syndication files unnecessarily often
+* Include .php files in sitemaps
+* Retry all client errors (4xx) to HEAD as GET reques when checking remote links
+* Graceful fallback in ``nikola serve --detach`` on Windows (Issue #1913)
+* Don't auto-rebuild on changes to ".foo" or "foo~" or changes in folders
+* auto should also rebuild in response to move events
+* Don’t get metadata from file if compiler-specific metadata exist (Issue #1904)
+* Fix PRETTY_URLS prompt for Windows (Issue #1901)
+* Fix reST and Markdown title extraction from documents (Issue #1895, #1898)
+* Minor improvements to the extending document
+* Re-add the hack to kill nikola auto on ^C (Issue #1893)
+
+New in v7.6.1
+=============
+
+Features
+--------
+
+* Several improvements to WordPress importer (PR #1867):
+
+ * Allowing to export categories and category hierarchy with
+ --export-categories-as-categories
+ * Allowing to exclude private posts, and allowing to include empty posts
+ * Allowing to use HTTP authentication for downloads with --download-auth
+ (PR #1848)
+ * Allowing to export comments with --export-comments
+ * Allowing to use WordPress page compiler to directly convert posts
+ to HTML on import with --transform-to-html
+ * Allowing to use WordPress page compiler on imported site instead of
+ converting posts to markdown with --use-wordpress-compiler
+ * Allowing to automatically install the WordPress page compiler when
+ needed with --install-wordpress-compiler
+ * Exporting information on attachments per post as JSON (#1867 and #1888)
+ * Exporting post status and excerpt
+
+* New ‘pagekind’ variable available to identify different kind of pages from theme templates
+* Add ``--no-server`` option to ``nikola auto`` (Issue #1883)
+* Always return unicode in slugify (Issue #1885)
+* Remove logging handlers (Issue #1797)
+* Add ``-d``, ``--detach`` option to ``nikola serve`` (Issue #1871)
+* Use provided teaser format (``*_READ_MORE_LINK``) with custom teaser text
+ (Issue #1879)
+* Delete old ``bootstrap`` theme (use ``bootstrap3`` instead)
+* Screen reader-friendly navbar collapses and dropdowns (Issue #1863)
+* Modern reST stylesheets, based in part on Bootstrap 3 (Issue #1150)
+
+Bugfixes
+--------
+
+* Use ``http`` as fallback in plugin/theme installers if a SSL error occurs
+ (Issue getnikola/nikola-themes#49)
+* Add missing ``xmlns:xhtml`` namespace to sitemaps (Issue #1890)
+* Fixed superfluous rebuild problems with Python 3. Note that this will cause
+ rebuilds for most sites. (Issue #1887)
+* Fix links in sample post (Issue #1874)
+* Don't use deprecated Yapsy methods (Isue #1868)
+* Surpress wincing when auto is aborted during rebuilding
+* Show tags only from the current language on tag listing pages (Issue #1856)
+* Remove gap between line numbers and code (Issue #1859)
+* Fix spurious warnings about posts published in the future (Issue #1850)
+
New in v7.6.0
=============
diff --git a/README.rst b/README.rst
index 8009623..3a82157 100644
--- a/README.rst
+++ b/README.rst
@@ -3,19 +3,19 @@ Nikola, a Static Site and Blog Generator
In goes content, out comes a website, ready to deploy.
-.. image:: http://img.shields.io/pypi/v/Nikola.png
+.. image:: http://img.shields.io/pypi/v/Nikola.svg
:target: https://pypi.python.org/pypi/Nikola
-.. image:: https://requires.io/github/getnikola/nikola/requirements.png?branch=master
- :target: https://requires.io/github/getnikola/nikola/requirements/?branch=master
+.. image:: https://img.shields.io/requires/github/getnikola/nikola.svg
+ :target: https://requires.io/github/getnikola/nikola/requirements/?branch=master
-.. image:: http://img.shields.io/travis/getnikola/nikola.png
+.. image:: http://img.shields.io/travis/getnikola/nikola.svg
:target: https://travis-ci.org/getnikola/nikola
.. image:: http://img.shields.io/coveralls/getnikola/nikola.png
:target: https://coveralls.io/r/getnikola/nikola?branch=master
-.. image:: http://img.shields.io/badge/license-MIT-green.png
+.. image:: http://img.shields.io/badge/license-MIT-green.svg
:target: https://github.com/getnikola/nikola/blob/master/LICENSE.txt
Why Static Websites?
@@ -65,10 +65,10 @@ Assuming you have pip installed::
For optional features::
- pip install Nikola[extras]
+ pip install "Nikola[extras]"
For tests (see tests/README.rst for more details)::
- pip install Nikola[extras,tests]
+ pip install "Nikola[extras,tests]"
For more information, see https://getnikola.com/
diff --git a/appveyor.yml b/appveyor.yml
index d4cd55c..52e4cda 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,16 +8,13 @@ init:
- "ECHO %PYTHON%"
- ps: "ls C:/Python*"
install:
- - ps: (new-object net.webclient).DownloadFile('https://raw.github.com/pypa/pip/master/contrib/get-pip.py', 'C:/get-pip.py')
- - "%PYTHON%/python.exe C:/get-pip.py"
- - "%PYTHON%/Scripts/pip.exe install --upgrade setuptools"
- "%PYTHON%/Scripts/pip.exe install -r requirements-extras.txt pytest mock freezegun"
- - "%PYTHON%/python.exe setup.py install"
+ - "%PYTHON%/Scripts/pip.exe install ."
test_script:
- "set path=%PYTHON%/Scripts;%path%"
- "%PYTHON%/python.exe --version"
- "%PYTHON%/Scripts/pip.exe --version"
- - "%PYTHON%/python.exe setup.py test"
- - "%nikola"
- - "%nikola help"
+ - "py.test tests/"
+ - "nikola"
+ - "nikola help"
diff --git a/bower_components/jquery-colorbox/.bower.json b/bower_components/jquery-colorbox/.bower.json
index 725e5a9..c2b3816 100644
--- a/bower_components/jquery-colorbox/.bower.json
+++ b/bower_components/jquery-colorbox/.bower.json
@@ -1,7 +1,6 @@
{
"name": "jquery-colorbox",
"description": "jQuery lightbox and modal window plugin",
- "version": "1.6.1",
"dependencies": {
"jquery": ">=1.3.2"
},
@@ -38,11 +37,12 @@
"example4/index.html",
"example5/index.html"
],
- "_release": "1.6.1",
+ "version": "1.6.3",
+ "_release": "1.6.3",
"_resolution": {
"type": "version",
- "tag": "1.6.1",
- "commit": "b817f48e5b8e5fa694020ef5fe2ccfd76d2bf4f0"
+ "tag": "1.6.3",
+ "commit": "f08f0ac16996b14e4ce681e0a08befc129b93924"
},
"_source": "git://github.com/jackmoore/colorbox.git",
"_target": "~1.6.0",
diff --git a/bower_components/jquery-colorbox/README.md b/bower_components/jquery-colorbox/README.md
index 0698ce2..9473a68 100644
--- a/bower_components/jquery-colorbox/README.md
+++ b/bower_components/jquery-colorbox/README.md
@@ -3,6 +3,14 @@ A customizable lightbox plugin for jQuery. See the [project page](http://jacklm
## Changelog:
+##### Version 1.6.3 - 2015/07/27
+
+* Fixed regression that caused error in IE8 when the calculated initial size was negative. Fixes #741
+
+##### Version 1.6.2 - 2015/07/13
+
+* Fixed iframe attribute name (allowFullScreen to allowFullscreen). Fixes #737
+
##### Version 1.6.1 - 2015/05/14
* Replaced the inline onclick handler for cboxPhoto with a namespaced event for easier unbinding. Fixes #719.
diff --git a/bower_components/jquery-colorbox/bower.json b/bower_components/jquery-colorbox/bower.json
index ab71158..f5fb8db 100644
--- a/bower_components/jquery-colorbox/bower.json
+++ b/bower_components/jquery-colorbox/bower.json
@@ -1,7 +1,6 @@
{
"name": "jquery-colorbox",
"description": "jQuery lightbox and modal window plugin",
- "version": "1.6.1",
"dependencies": {
"jquery": ">=1.3.2"
},
diff --git a/bower_components/jquery-colorbox/i18n/jquery.colorbox-he.js b/bower_components/jquery-colorbox/i18n/jquery.colorbox-he.js
index 78908e3..05e8460 100644
--- a/bower_components/jquery-colorbox/i18n/jquery.colorbox-he.js
+++ b/bower_components/jquery-colorbox/i18n/jquery.colorbox-he.js
@@ -1,8 +1,8 @@
/*
jQuery Colorbox language configuration
language: Hebrew (he)
- translated by: DavidCo
- site: DavidCo.me
+ translated by: David Cohen
+ site: dav.co.il
*/
jQuery.extend(jQuery.colorbox.settings, {
current: "תמונה {current} מתוך {total}",
diff --git a/bower_components/jquery-colorbox/i18n/jquery.colorbox-zh-TW.js b/bower_components/jquery-colorbox/i18n/jquery.colorbox-zh-TW.js
index b0c4f12..d72b742 100644
--- a/bower_components/jquery-colorbox/i18n/jquery.colorbox-zh-TW.js
+++ b/bower_components/jquery-colorbox/i18n/jquery.colorbox-zh-TW.js
@@ -8,8 +8,8 @@ jQuery.extend(jQuery.colorbox.settings, {
previous: "上一頁",
next: "下一頁",
close: "關閉",
- xhrError: "此內容加載失敗.",
- imgError: "此圖片加載失敗.",
+ xhrError: "此內容載入失敗.",
+ imgError: "此圖片加入失敗.",
slideshowStart: "開始幻燈片",
slideshowStop: "結束幻燈片"
-}); \ No newline at end of file
+});
diff --git a/bower_components/jquery-colorbox/jquery.colorbox.js b/bower_components/jquery-colorbox/jquery.colorbox.js
index 976d38e..7ce92f1 100644
--- a/bower_components/jquery-colorbox/jquery.colorbox.js
+++ b/bower_components/jquery-colorbox/jquery.colorbox.js
@@ -1,5 +1,5 @@
/*!
- Colorbox 1.6.1
+ Colorbox 1.6.3
license: MIT
http://www.jacklmoore.com/colorbox
*/
@@ -115,7 +115,7 @@
iframe.allowTransparency = "true";
}
iframe.name = (new Date()).getTime(); // give the iframe a unique name to prevent caching
- iframe.allowFullScreen = true;
+ iframe.allowFullscreen = true;
return iframe;
}
@@ -413,8 +413,8 @@
var maxWidth = settings.get('maxWidth');
var maxHeight = settings.get('maxHeight');
- settings.w = (maxWidth !== false ? Math.min(initialWidth, setSize(maxWidth, 'x')) : initialWidth) - loadedWidth - interfaceWidth;
- settings.h = (maxHeight !== false ? Math.min(initialHeight, setSize(maxHeight, 'y')) : initialHeight) - loadedHeight - interfaceHeight;
+ settings.w = Math.max((maxWidth !== false ? Math.min(initialWidth, setSize(maxWidth, 'x')) : initialWidth) - loadedWidth - interfaceWidth, 0);
+ settings.h = Math.max((maxHeight !== false ? Math.min(initialHeight, setSize(maxHeight, 'y')) : initialHeight) - loadedHeight - interfaceHeight, 0);
$loaded.css({width:'', height:settings.h});
publicMethod.position();
diff --git a/bower_components/jquery-colorbox/package.json b/bower_components/jquery-colorbox/package.json
index d94cb32..de888cb 100644
--- a/bower_components/jquery-colorbox/package.json
+++ b/bower_components/jquery-colorbox/package.json
@@ -1,7 +1,7 @@
{
"name": "jquery-colorbox",
"description": "jQuery lightbox and modal window plugin.",
- "version": "1.6.1",
+ "version": "1.6.3",
"keywords": [
"modal",
"lightbox",
diff --git a/bower_components/moment/.bower.json b/bower_components/moment/.bower.json
index 99c7933..51df0a7 100644
--- a/bower_components/moment/.bower.json
+++ b/bower_components/moment/.bower.json
@@ -1,6 +1,5 @@
{
"name": "moment",
- "version": "2.10.3",
"main": "moment.js",
"ignore": [
"**/.*",
@@ -21,11 +20,12 @@
"package.json"
],
"homepage": "https://github.com/moment/moment",
- "_release": "2.10.3",
+ "version": "2.10.6",
+ "_release": "2.10.6",
"_resolution": {
"type": "version",
- "tag": "2.10.3",
- "commit": "6fa444238494318e3c488c81d8520ad2eba8bae7"
+ "tag": "2.10.6",
+ "commit": "446ce77eb08c5c862d7b0b11ef1d2e884d12e3d7"
},
"_source": "git://github.com/moment/moment.git",
"_target": "~2.10.3",
diff --git a/bower_components/moment/CHANGELOG.md b/bower_components/moment/CHANGELOG.md
index 395261f..7da0b1f 100644
--- a/bower_components/moment/CHANGELOG.md
+++ b/bower_components/moment/CHANGELOG.md
@@ -1,6 +1,24 @@
Changelog
=========
+### 2.10.6
+
+[#2515](https://github.com/moment/moment/pull/2515) Fix regression introduced
+in `2.10.5` related to `moment.ISO_8601` parsing.
+
+### 2.10.5 [See full changelog](https://gist.github.com/ichernev/6ec13ac7efc396da44b2)
+
+Important changes:
+* [#2357](https://github.com/moment/moment/pull/2357) Improve unit bubbling for ISO dates
+ this fixes day to year conversions to work around end-of-year (~365 days). As
+ a side effect 365 days is 11 months and 30 days, and 366 days is one year.
+* [#2438](https://github.com/moment/moment/pull/2438) Fix inconsistent moment.min and moment.max results
+ Return invalid result if any of the inputs is invalid
+* [#2494](https://github.com/moment/moment/pull/2494) Fix two digit year parsing with YYYY format
+ This brings the benefits of YY to YYYY
+* [#2368](https://github.com/moment/moment/pull/2368) perf: use faster form of copying dates, across the board improvement
+
+
### 2.10.3 [See full changelog](https://gist.github.com/ichernev/f264b9bed5b00f8b1b7f)
* add `moment.fn.to` and `moment.fn.toNow` (similar to `from` and `fromNow`)
diff --git a/bower_components/moment/README.md b/bower_components/moment/README.md
index d5fc00a..d59f056 100644
--- a/bower_components/moment/README.md
+++ b/bower_components/moment/README.md
@@ -1,6 +1,7 @@
[![Join the chat at https://gitter.im/moment/moment](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/moment/moment?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]
+[![Coverage Status](https://coveralls.io/repos/moment/moment/badge.svg?branch=master)](https://coveralls.io/r/moment/moment?branch=master)
A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
diff --git a/bower_components/moment/bower.json b/bower_components/moment/bower.json
index 48d24c7..d9f47e8 100644
--- a/bower_components/moment/bower.json
+++ b/bower_components/moment/bower.json
@@ -1,6 +1,5 @@
{
"name": "moment",
- "version": "2.10.3",
"main": "moment.js",
"ignore": [
"**/.*",
diff --git a/bower_components/moment/locale/af.js b/bower_components/moment/locale/af.js
index 341170b..f6329e8 100644
--- a/bower_components/moment/locale/af.js
+++ b/bower_components/moment/locale/af.js
@@ -28,11 +28,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Vandag om] LT',
diff --git a/bower_components/moment/locale/ar-ma.js b/bower_components/moment/locale/ar-ma.js
index aa50dd8..f9f21b5 100644
--- a/bower_components/moment/locale/ar-ma.js
+++ b/bower_components/moment/locale/ar-ma.js
@@ -18,11 +18,11 @@
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
diff --git a/bower_components/moment/locale/ar-sa.js b/bower_components/moment/locale/ar-sa.js
index ef5da5b..cdb0f64 100644
--- a/bower_components/moment/locale/ar-sa.js
+++ b/bower_components/moment/locale/ar-sa.js
@@ -44,8 +44,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
diff --git a/bower_components/moment/locale/ar-tn.js b/bower_components/moment/locale/ar-tn.js
index ccf82cd..6f5a84f 100644
--- a/bower_components/moment/locale/ar-tn.js
+++ b/bower_components/moment/locale/ar-tn.js
@@ -16,11 +16,11 @@
weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[اليوم على الساعة] LT',
diff --git a/bower_components/moment/locale/ar.js b/bower_components/moment/locale/ar.js
index d08c983..c42f5e6 100644
--- a/bower_components/moment/locale/ar.js
+++ b/bower_components/moment/locale/ar.js
@@ -77,8 +77,8 @@
LTS : 'HH:mm:ss',
L : 'D/\u200FM/\u200FYYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
diff --git a/bower_components/moment/locale/az.js b/bower_components/moment/locale/az.js
index 6c17574..bd9830f 100644
--- a/bower_components/moment/locale/az.js
+++ b/bower_components/moment/locale/az.js
@@ -38,11 +38,11 @@
weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
diff --git a/bower_components/moment/locale/be.js b/bower_components/moment/locale/be.js
index 7ca287e..0fa37d7 100644
--- a/bower_components/moment/locale/be.js
+++ b/bower_components/moment/locale/be.js
@@ -62,11 +62,11 @@
weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сёння ў] LT',
diff --git a/bower_components/moment/locale/bg.js b/bower_components/moment/locale/bg.js
index af66834..c6601c6 100644
--- a/bower_components/moment/locale/bg.js
+++ b/bower_components/moment/locale/bg.js
@@ -17,11 +17,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
diff --git a/bower_components/moment/locale/bn.js b/bower_components/moment/locale/bn.js
index 515a6f1..745e277 100644
--- a/bower_components/moment/locale/bn.js
+++ b/bower_components/moment/locale/bn.js
@@ -45,8 +45,8 @@
LTS : 'A h:mm:ss সময়',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm সময়',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
},
calendar : {
sameDay : '[আজ] LT',
@@ -81,7 +81,7 @@
return symbolMap[match];
});
},
- meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,
+ meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,
isPM: function (input) {
return /^(দুপুর|বিকেল|রাত)$/.test(input);
},
@@ -92,7 +92,7 @@
if (hour < 4) {
return 'রাত';
} else if (hour < 10) {
- return 'শকাল';
+ return 'সকাল';
} else if (hour < 17) {
return 'দুপুর';
} else if (hour < 20) {
diff --git a/bower_components/moment/locale/bo.js b/bower_components/moment/locale/bo.js
index 5bcfd9a..4331f3b 100644
--- a/bower_components/moment/locale/bo.js
+++ b/bower_components/moment/locale/bo.js
@@ -42,11 +42,11 @@
weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
longDateFormat : {
LT : 'A h:mm',
- LTS : 'LT:ss',
+ LTS : 'A h:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm'
},
calendar : {
sameDay : '[དི་རིང] LT',
diff --git a/bower_components/moment/locale/br.js b/bower_components/moment/locale/br.js
index a08280c..d565505 100644
--- a/bower_components/moment/locale/br.js
+++ b/bower_components/moment/locale/br.js
@@ -64,8 +64,8 @@
LTS : 'h[e]mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D [a viz] MMMM YYYY',
- LLL : 'D [a viz] MMMM YYYY LT',
- LLLL : 'dddd, D [a viz] MMMM YYYY LT'
+ LLL : 'D [a viz] MMMM YYYY h[e]mm A',
+ LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
},
calendar : {
sameDay : '[Hiziv da] LT',
diff --git a/bower_components/moment/locale/bs.js b/bower_components/moment/locale/bs.js
index 57139cc..8b452ab 100644
--- a/bower_components/moment/locale/bs.js
+++ b/bower_components/moment/locale/bs.js
@@ -71,11 +71,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
diff --git a/bower_components/moment/locale/ca.js b/bower_components/moment/locale/ca.js
index 11cce50..6459d83 100644
--- a/bower_components/moment/locale/ca.js
+++ b/bower_components/moment/locale/ca.js
@@ -20,8 +20,8 @@
LTS : 'LT:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/locale/cs.js b/bower_components/moment/locale/cs.js
index 0d8789d..00aa126 100644
--- a/bower_components/moment/locale/cs.js
+++ b/bower_components/moment/locale/cs.js
@@ -83,11 +83,11 @@
weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes v] LT',
diff --git a/bower_components/moment/locale/cv.js b/bower_components/moment/locale/cv.js
index d01acab..7055d12 100644
--- a/bower_components/moment/locale/cv.js
+++ b/bower_components/moment/locale/cv.js
@@ -17,11 +17,11 @@
weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
- LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT',
- LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT'
+ LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+ LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
},
calendar : {
sameDay: '[Паян] LT [сехетре]',
diff --git a/bower_components/moment/locale/cy.js b/bower_components/moment/locale/cy.js
index e639124..a3c38a0 100644
--- a/bower_components/moment/locale/cy.js
+++ b/bower_components/moment/locale/cy.js
@@ -18,11 +18,11 @@
// time formats are the same as en-gb
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Heddiw am] LT',
diff --git a/bower_components/moment/locale/da.js b/bower_components/moment/locale/da.js
index 9a99381..2aff2bb 100644
--- a/bower_components/moment/locale/da.js
+++ b/bower_components/moment/locale/da.js
@@ -17,11 +17,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd [d.] D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[I dag kl.] LT',
diff --git a/bower_components/moment/locale/de-at.js b/bower_components/moment/locale/de-at.js
index 5309601..a2071bb 100644
--- a/bower_components/moment/locale/de-at.js
+++ b/bower_components/moment/locale/de-at.js
@@ -36,8 +36,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
diff --git a/bower_components/moment/locale/de.js b/bower_components/moment/locale/de.js
index 30a9b1e..81ffae4 100644
--- a/bower_components/moment/locale/de.js
+++ b/bower_components/moment/locale/de.js
@@ -35,8 +35,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
diff --git a/bower_components/moment/locale/el.js b/bower_components/moment/locale/el.js
index d185642..ee580e7 100644
--- a/bower_components/moment/locale/el.js
+++ b/bower_components/moment/locale/el.js
@@ -39,8 +39,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendarEl : {
sameDay : '[Σήμερα {}] LT',
diff --git a/bower_components/moment/locale/en-au.js b/bower_components/moment/locale/en-au.js
index 9a358e5..ae1ee4f 100644
--- a/bower_components/moment/locale/en-au.js
+++ b/bower_components/moment/locale/en-au.js
@@ -19,8 +19,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/locale/en-ca.js b/bower_components/moment/locale/en-ca.js
index e0aaf01..4526d89 100644
--- a/bower_components/moment/locale/en-ca.js
+++ b/bower_components/moment/locale/en-ca.js
@@ -20,8 +20,8 @@
LTS : 'h:mm:ss A',
L : 'YYYY-MM-DD',
LL : 'D MMMM, YYYY',
- LLL : 'D MMMM, YYYY LT',
- LLLL : 'dddd, D MMMM, YYYY LT'
+ LLL : 'D MMMM, YYYY h:mm A',
+ LLLL : 'dddd, D MMMM, YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/locale/en-gb.js b/bower_components/moment/locale/en-gb.js
index e9eeace..fb76283 100644
--- a/bower_components/moment/locale/en-gb.js
+++ b/bower_components/moment/locale/en-gb.js
@@ -20,8 +20,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/locale/eo.js b/bower_components/moment/locale/eo.js
index d4c7908..4cb0e3a 100644
--- a/bower_components/moment/locale/eo.js
+++ b/bower_components/moment/locale/eo.js
@@ -19,11 +19,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D[-an de] MMMM, YYYY',
- LLL : 'D[-an de] MMMM, YYYY LT',
- LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'
+ LLL : 'D[-an de] MMMM, YYYY HH:mm',
+ LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
},
meridiemParse: /[ap]\.t\.m/i,
isPM: function (input) {
diff --git a/bower_components/moment/locale/es.js b/bower_components/moment/locale/es.js
index 4349217..d910d50 100644
--- a/bower_components/moment/locale/es.js
+++ b/bower_components/moment/locale/es.js
@@ -26,11 +26,11 @@
weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY H:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/locale/et.js b/bower_components/moment/locale/et.js
index 8cadeb2..00207d4 100644
--- a/bower_components/moment/locale/et.js
+++ b/bower_components/moment/locale/et.js
@@ -37,11 +37,11 @@
weekdaysMin : 'P_E_T_K_N_R_L'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Täna,] LT',
diff --git a/bower_components/moment/locale/eu.js b/bower_components/moment/locale/eu.js
index c90391a..6029f47 100644
--- a/bower_components/moment/locale/eu.js
+++ b/bower_components/moment/locale/eu.js
@@ -17,15 +17,15 @@
weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY[ko] MMMM[ren] D[a]',
- LLL : 'YYYY[ko] MMMM[ren] D[a] LT',
- LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',
+ LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
+ LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
l : 'YYYY-M-D',
ll : 'YYYY[ko] MMM D[a]',
- lll : 'YYYY[ko] MMM D[a] LT',
- llll : 'ddd, YYYY[ko] MMM D[a] LT'
+ lll : 'YYYY[ko] MMM D[a] HH:mm',
+ llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
},
calendar : {
sameDay : '[gaur] LT[etan]',
diff --git a/bower_components/moment/locale/fa.js b/bower_components/moment/locale/fa.js
index 9a5e512..d9eb59d 100644
--- a/bower_components/moment/locale/fa.js
+++ b/bower_components/moment/locale/fa.js
@@ -41,11 +41,11 @@
weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
meridiemParse: /قبل از ظهر|بعد از ظهر/,
isPM: function (input) {
diff --git a/bower_components/moment/locale/fi.js b/bower_components/moment/locale/fi.js
index b402320..d889ee7 100644
--- a/bower_components/moment/locale/fi.js
+++ b/bower_components/moment/locale/fi.js
@@ -63,12 +63,12 @@
LTS : 'HH.mm.ss',
L : 'DD.MM.YYYY',
LL : 'Do MMMM[ta] YYYY',
- LLL : 'Do MMMM[ta] YYYY, [klo] LT',
- LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',
+ LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
+ LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
l : 'D.M.YYYY',
ll : 'Do MMM YYYY',
- lll : 'Do MMM YYYY, [klo] LT',
- llll : 'ddd, Do MMM YYYY, [klo] LT'
+ lll : 'Do MMM YYYY, [klo] HH.mm',
+ llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
},
calendar : {
sameDay : '[tänään] [klo] LT',
diff --git a/bower_components/moment/locale/fo.js b/bower_components/moment/locale/fo.js
index 734d078..e5aa93b 100644
--- a/bower_components/moment/locale/fo.js
+++ b/bower_components/moment/locale/fo.js
@@ -17,11 +17,11 @@
weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D. MMMM, YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D. MMMM, YYYY HH:mm'
},
calendar : {
sameDay : '[Í dag kl.] LT',
diff --git a/bower_components/moment/locale/fr-ca.js b/bower_components/moment/locale/fr-ca.js
index decc50c..db7fc1f 100644
--- a/bower_components/moment/locale/fr-ca.js
+++ b/bower_components/moment/locale/fr-ca.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -46,9 +46,9 @@
y : 'un an',
yy : '%d ans'
},
- ordinalParse: /\d{1,2}(er|)/,
+ ordinalParse: /\d{1,2}(er|e)/,
ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
+ return number + (number === 1 ? 'er' : 'e');
}
});
diff --git a/bower_components/moment/locale/fr.js b/bower_components/moment/locale/fr.js
index c2f83ef..4f60e58 100644
--- a/bower_components/moment/locale/fr.js
+++ b/bower_components/moment/locale/fr.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
diff --git a/bower_components/moment/locale/fy.js b/bower_components/moment/locale/fy.js
index 57380dd..3a5971a 100644
--- a/bower_components/moment/locale/fy.js
+++ b/bower_components/moment/locale/fy.js
@@ -26,11 +26,11 @@
weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[hjoed om] LT',
diff --git a/bower_components/moment/locale/gl.js b/bower_components/moment/locale/gl.js
index 88f271e..91b35a2 100644
--- a/bower_components/moment/locale/gl.js
+++ b/bower_components/moment/locale/gl.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/locale/he.js b/bower_components/moment/locale/he.js
index 19a3b87..35c3b46 100644
--- a/bower_components/moment/locale/he.js
+++ b/bower_components/moment/locale/he.js
@@ -19,15 +19,15 @@
weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [ב]MMMM YYYY',
- LLL : 'D [ב]MMMM YYYY LT',
- LLLL : 'dddd, D [ב]MMMM YYYY LT',
+ LLL : 'D [ב]MMMM YYYY HH:mm',
+ LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
l : 'D/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay : '[היום ב־]LT',
diff --git a/bower_components/moment/locale/hi.js b/bower_components/moment/locale/hi.js
index 7177806..f450c51 100644
--- a/bower_components/moment/locale/hi.js
+++ b/bower_components/moment/locale/hi.js
@@ -45,8 +45,8 @@
LTS : 'A h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
},
calendar : {
sameDay : '[आज] LT',
diff --git a/bower_components/moment/locale/hr.js b/bower_components/moment/locale/hr.js
index 2c948e3..7b5b4d3 100644
--- a/bower_components/moment/locale/hr.js
+++ b/bower_components/moment/locale/hr.js
@@ -70,11 +70,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
diff --git a/bower_components/moment/locale/hu.js b/bower_components/moment/locale/hu.js
index 4a95c84..5fc432d 100644
--- a/bower_components/moment/locale/hu.js
+++ b/bower_components/moment/locale/hu.js
@@ -51,11 +51,11 @@
weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'YYYY.MM.DD.',
LL : 'YYYY. MMMM D.',
- LLL : 'YYYY. MMMM D., LT',
- LLLL : 'YYYY. MMMM D., dddd LT'
+ LLL : 'YYYY. MMMM D. H:mm',
+ LLLL : 'YYYY. MMMM D., dddd H:mm'
},
meridiemParse: /de|du/i,
isPM: function (input) {
diff --git a/bower_components/moment/locale/hy-am.js b/bower_components/moment/locale/hy-am.js
index 08c5c75..a14737a 100644
--- a/bower_components/moment/locale/hy-am.js
+++ b/bower_components/moment/locale/hy-am.js
@@ -36,11 +36,11 @@
weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY թ.',
- LLL : 'D MMMM YYYY թ., LT',
- LLLL : 'dddd, D MMMM YYYY թ., LT'
+ LLL : 'D MMMM YYYY թ., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
},
calendar : {
sameDay: '[այսօր] LT',
diff --git a/bower_components/moment/locale/id.js b/bower_components/moment/locale/id.js
index d9278bd..2e7783b 100644
--- a/bower_components/moment/locale/id.js
+++ b/bower_components/moment/locale/id.js
@@ -18,11 +18,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|siang|sore|malam/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/locale/is.js b/bower_components/moment/locale/is.js
index 3276712..98afb05 100644
--- a/bower_components/moment/locale/is.js
+++ b/bower_components/moment/locale/is.js
@@ -84,11 +84,11 @@
weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd, D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H:mm',
+ LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
},
calendar : {
sameDay : '[í dag kl.] LT',
diff --git a/bower_components/moment/locale/it.js b/bower_components/moment/locale/it.js
index 84fe389..ea277e0 100644
--- a/bower_components/moment/locale/it.js
+++ b/bower_components/moment/locale/it.js
@@ -18,11 +18,11 @@
weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Oggi alle] LT',
diff --git a/bower_components/moment/locale/ja.js b/bower_components/moment/locale/ja.js
index de01577..a2ec885 100644
--- a/bower_components/moment/locale/ja.js
+++ b/bower_components/moment/locale/ja.js
@@ -17,11 +17,11 @@
weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
longDateFormat : {
LT : 'Ah時m分',
- LTS : 'LTs秒',
+ LTS : 'Ah時m分s秒',
L : 'YYYY/MM/DD',
LL : 'YYYY年M月D日',
- LLL : 'YYYY年M月D日LT',
- LLLL : 'YYYY年M月D日LT dddd'
+ LLL : 'YYYY年M月D日Ah時m分',
+ LLLL : 'YYYY年M月D日Ah時m分 dddd'
},
meridiemParse: /午前|午後/i,
isPM : function (input) {
diff --git a/bower_components/moment/locale/jv.js b/bower_components/moment/locale/jv.js
index e73ae19..e980ed4 100644
--- a/bower_components/moment/locale/jv.js
+++ b/bower_components/moment/locale/jv.js
@@ -18,11 +18,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /enjing|siyang|sonten|ndalu/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/locale/ka.js b/bower_components/moment/locale/ka.js
index 19bcb3a..4a28ae3 100644
--- a/bower_components/moment/locale/ka.js
+++ b/bower_components/moment/locale/ka.js
@@ -41,8 +41,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[დღეს] LT[-ზე]',
diff --git a/bower_components/moment/locale/km.js b/bower_components/moment/locale/km.js
index d6f6c65..ec92f25 100644
--- a/bower_components/moment/locale/km.js
+++ b/bower_components/moment/locale/km.js
@@ -17,11 +17,11 @@
weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
diff --git a/bower_components/moment/locale/ko.js b/bower_components/moment/locale/ko.js
index ded3714..11badbb 100644
--- a/bower_components/moment/locale/ko.js
+++ b/bower_components/moment/locale/ko.js
@@ -24,8 +24,8 @@
LTS : 'A h시 m분 s초',
L : 'YYYY.MM.DD',
LL : 'YYYY년 MMMM D일',
- LLL : 'YYYY년 MMMM D일 LT',
- LLLL : 'YYYY년 MMMM D일 dddd LT'
+ LLL : 'YYYY년 MMMM D일 A h시 m분',
+ LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
},
calendar : {
sameDay : '오늘 LT',
diff --git a/bower_components/moment/locale/lb.js b/bower_components/moment/locale/lb.js
index 43f988a..fefe83f 100644
--- a/bower_components/moment/locale/lb.js
+++ b/bower_components/moment/locale/lb.js
@@ -85,8 +85,8 @@
LTS: 'H:mm:ss [Auer]',
L: 'DD.MM.YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm [Auer]',
+ LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
},
calendar: {
sameDay: '[Haut um] LT',
diff --git a/bower_components/moment/locale/lt.js b/bower_components/moment/locale/lt.js
index 8f0ef54..303b850 100644
--- a/bower_components/moment/locale/lt.js
+++ b/bower_components/moment/locale/lt.js
@@ -29,6 +29,16 @@
return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
}
}
+ function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
+ 'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')
+ },
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
+ return months[nounCase][m.month()];
+ }
function translateSingular(number, withoutSuffix, key, isFuture) {
return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
}
@@ -59,22 +69,22 @@
}
var lt = moment.defineLocale('lt', {
- months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
+ months : monthsCaseReplace,
monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
weekdays : relativeWeekDay,
weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY [m.] MMMM D [d.]',
- LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',
- LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',
+ LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
l : 'YYYY-MM-DD',
ll : 'YYYY [m.] MMMM D [d.]',
- lll : 'YYYY [m.] MMMM D [d.], LT [val.]',
- llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'
+ lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
},
calendar : {
sameDay : '[Šiandien] LT',
diff --git a/bower_components/moment/locale/lv.js b/bower_components/moment/locale/lv.js
index ad1cc0a..62f8091 100644
--- a/bower_components/moment/locale/lv.js
+++ b/bower_components/moment/locale/lv.js
@@ -53,11 +53,11 @@
weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY.',
LL : 'YYYY. [gada] D. MMMM',
- LLL : 'YYYY. [gada] D. MMMM, LT',
- LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'
+ LLL : 'YYYY. [gada] D. MMMM, HH:mm',
+ LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
},
calendar : {
sameDay : '[Šodien pulksten] LT',
diff --git a/bower_components/moment/locale/me.js b/bower_components/moment/locale/me.js
index 37bc78c..ea7ec91 100644
--- a/bower_components/moment/locale/me.js
+++ b/bower_components/moment/locale/me.js
@@ -40,11 +40,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
diff --git a/bower_components/moment/locale/mk.js b/bower_components/moment/locale/mk.js
index f04826f..b1f1e10 100644
--- a/bower_components/moment/locale/mk.js
+++ b/bower_components/moment/locale/mk.js
@@ -17,11 +17,11 @@
weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Денес во] LT',
diff --git a/bower_components/moment/locale/ml.js b/bower_components/moment/locale/ml.js
index fe59373..c7c93ca 100644
--- a/bower_components/moment/locale/ml.js
+++ b/bower_components/moment/locale/ml.js
@@ -20,8 +20,8 @@
LTS : 'A h:mm:ss -നു',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm -നു',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
},
calendar : {
sameDay : '[ഇന്ന്] LT',
diff --git a/bower_components/moment/locale/mr.js b/bower_components/moment/locale/mr.js
index 9072d69..960d2f5 100644
--- a/bower_components/moment/locale/mr.js
+++ b/bower_components/moment/locale/mr.js
@@ -45,8 +45,8 @@
LTS : 'A h:mm:ss वाजता',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm वाजता',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
},
calendar : {
sameDay : '[आज] LT',
diff --git a/bower_components/moment/locale/ms-my.js b/bower_components/moment/locale/ms-my.js
index d1ea5a2..9c6fb56 100644
--- a/bower_components/moment/locale/ms-my.js
+++ b/bower_components/moment/locale/ms-my.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|tengahari|petang|malam/,
meridiemHour: function (hour, meridiem) {
diff --git a/bower_components/moment/locale/ms.js b/bower_components/moment/locale/ms.js
new file mode 100644
index 0000000..cd710dc
--- /dev/null
+++ b/bower_components/moment/locale/ms.js
@@ -0,0 +1,81 @@
+//! moment.js locale configuration
+//! locale : Bahasa Malaysia (ms-MY)
+//! author : Weldan Jamili : https://github.com/weldan
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :
+ typeof define === 'function' && define.amd ? define(['moment'], factory) :
+ factory(global.moment)
+}(this, function (moment) { 'use strict';
+
+
+ var ms = moment.defineLocale('ms', {
+ months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
+ monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
+ weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
+ weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
+ weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'HH.mm.ss',
+ L : 'DD/MM/YYYY',
+ LL : 'D MMMM YYYY',
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
+ },
+ meridiemParse: /pagi|tengahari|petang|malam/,
+ meridiemHour: function (hour, meridiem) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ if (meridiem === 'pagi') {
+ return hour;
+ } else if (meridiem === 'tengahari') {
+ return hour >= 11 ? hour : hour + 12;
+ } else if (meridiem === 'petang' || meridiem === 'malam') {
+ return hour + 12;
+ }
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'tengahari';
+ } else if (hours < 19) {
+ return 'petang';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Esok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kelmarin pukul] LT',
+ lastWeek : 'dddd [lepas pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'dalam %s',
+ past : '%s yang lepas',
+ s : 'beberapa saat',
+ m : 'seminit',
+ mm : '%d minit',
+ h : 'sejam',
+ hh : '%d jam',
+ d : 'sehari',
+ dd : '%d hari',
+ M : 'sebulan',
+ MM : '%d bulan',
+ y : 'setahun',
+ yy : '%d tahun'
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+
+ return ms;
+
+})); \ No newline at end of file
diff --git a/bower_components/moment/locale/my.js b/bower_components/moment/locale/my.js
index e50972b..72f65b5 100644
--- a/bower_components/moment/locale/my.js
+++ b/bower_components/moment/locale/my.js
@@ -45,8 +45,8 @@
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ယနေ.] LT [မှာ]',
diff --git a/bower_components/moment/locale/nb.js b/bower_components/moment/locale/nb.js
index 6ab39c4..966619c 100644
--- a/bower_components/moment/locale/nb.js
+++ b/bower_components/moment/locale/nb.js
@@ -18,11 +18,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'H.mm',
- LTS : 'LT.ss',
+ LTS : 'H.mm.ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H.mm',
+ LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'
},
calendar : {
sameDay: '[i dag kl.] LT',
diff --git a/bower_components/moment/locale/ne.js b/bower_components/moment/locale/ne.js
index dfbe878..257acf9 100644
--- a/bower_components/moment/locale/ne.js
+++ b/bower_components/moment/locale/ne.js
@@ -45,8 +45,8 @@
LTS : 'Aको h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, Aको h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
},
preparse: function (string) {
return string.replace(/[१२३४५६७८९०]/g, function (match) {
diff --git a/bower_components/moment/locale/nl.js b/bower_components/moment/locale/nl.js
index 7b5f3a2..60a3c43 100644
--- a/bower_components/moment/locale/nl.js
+++ b/bower_components/moment/locale/nl.js
@@ -26,11 +26,11 @@
weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[vandaag om] LT',
diff --git a/bower_components/moment/locale/nn.js b/bower_components/moment/locale/nn.js
index 74424cd..83d301a 100644
--- a/bower_components/moment/locale/nn.js
+++ b/bower_components/moment/locale/nn.js
@@ -17,11 +17,11 @@
weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[I dag klokka] LT',
diff --git a/bower_components/moment/locale/pl.js b/bower_components/moment/locale/pl.js
index 075c102..9c65c1f 100644
--- a/bower_components/moment/locale/pl.js
+++ b/bower_components/moment/locale/pl.js
@@ -51,11 +51,11 @@
weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Dziś o] LT',
diff --git a/bower_components/moment/locale/pt-br.js b/bower_components/moment/locale/pt-br.js
index 47948a3..d2c9351 100644
--- a/bower_components/moment/locale/pt-br.js
+++ b/bower_components/moment/locale/pt-br.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY [às] LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'
+ LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -38,7 +38,7 @@
relativeTime : {
future : 'em %s',
past : '%s atrás',
- s : 'segundos',
+ s : 'poucos segundos',
m : 'um minuto',
mm : '%d minutos',
h : 'uma hora',
diff --git a/bower_components/moment/locale/pt.js b/bower_components/moment/locale/pt.js
index 1a332e2..6487bc9 100644
--- a/bower_components/moment/locale/pt.js
+++ b/bower_components/moment/locale/pt.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
diff --git a/bower_components/moment/locale/ro.js b/bower_components/moment/locale/ro.js
index 576798b..92a89d1 100644
--- a/bower_components/moment/locale/ro.js
+++ b/bower_components/moment/locale/ro.js
@@ -33,7 +33,7 @@
weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
diff --git a/bower_components/moment/locale/ru.js b/bower_components/moment/locale/ru.js
index 77efbe4..14e67c6 100644
--- a/bower_components/moment/locale/ru.js
+++ b/bower_components/moment/locale/ru.js
@@ -69,11 +69,11 @@
monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сегодня в] LT',
diff --git a/bower_components/moment/locale/si.js b/bower_components/moment/locale/si.js
index e831f25..40e4591 100644
--- a/bower_components/moment/locale/si.js
+++ b/bower_components/moment/locale/si.js
@@ -20,8 +20,8 @@
LTS : 'a h:mm:ss',
L : 'YYYY/MM/DD',
LL : 'YYYY MMMM D',
- LLL : 'YYYY MMMM D, LT',
- LLLL : 'YYYY MMMM D [වැනි] dddd, LTS'
+ LLL : 'YYYY MMMM D, a h:mm',
+ LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
},
calendar : {
sameDay : '[අද] LT[ට]',
diff --git a/bower_components/moment/locale/sk.js b/bower_components/moment/locale/sk.js
index f48a560..d3084af 100644
--- a/bower_components/moment/locale/sk.js
+++ b/bower_components/moment/locale/sk.js
@@ -84,11 +84,11 @@
weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes o] LT',
diff --git a/bower_components/moment/locale/sl.js b/bower_components/moment/locale/sl.js
index 00c079b..a55062f 100644
--- a/bower_components/moment/locale/sl.js
+++ b/bower_components/moment/locale/sl.js
@@ -88,11 +88,11 @@
weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danes ob] LT',
diff --git a/bower_components/moment/locale/sq.js b/bower_components/moment/locale/sq.js
index ce587cc..d5fcdb5 100644
--- a/bower_components/moment/locale/sq.js
+++ b/bower_components/moment/locale/sq.js
@@ -26,11 +26,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Sot në] LT',
diff --git a/bower_components/moment/locale/sr-cyrl.js b/bower_components/moment/locale/sr-cyrl.js
index 8414596..a9c5c30 100644
--- a/bower_components/moment/locale/sr-cyrl.js
+++ b/bower_components/moment/locale/sr-cyrl.js
@@ -40,11 +40,11 @@
weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[данас у] LT',
diff --git a/bower_components/moment/locale/sr.js b/bower_components/moment/locale/sr.js
index 923b018..2d0125a 100644
--- a/bower_components/moment/locale/sr.js
+++ b/bower_components/moment/locale/sr.js
@@ -40,11 +40,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
diff --git a/bower_components/moment/locale/sv.js b/bower_components/moment/locale/sv.js
index df2421a..3f6238e 100644
--- a/bower_components/moment/locale/sv.js
+++ b/bower_components/moment/locale/sv.js
@@ -17,11 +17,11 @@
weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Idag] LT',
diff --git a/bower_components/moment/locale/ta.js b/bower_components/moment/locale/ta.js
index f0291c8..2c67c7d 100644
--- a/bower_components/moment/locale/ta.js
+++ b/bower_components/moment/locale/ta.js
@@ -17,11 +17,11 @@
weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, HH:mm',
+ LLLL : 'dddd, D MMMM YYYY, HH:mm'
},
calendar : {
sameDay : '[இன்று] LT',
diff --git a/bower_components/moment/locale/th.js b/bower_components/moment/locale/th.js
index 6fe2f44..7805ebb 100644
--- a/bower_components/moment/locale/th.js
+++ b/bower_components/moment/locale/th.js
@@ -17,11 +17,11 @@
weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
longDateFormat : {
LT : 'H นาฬิกา m นาที',
- LTS : 'LT s วินาที',
+ LTS : 'H นาฬิกา m นาที s วินาที',
L : 'YYYY/MM/DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY เวลา LT',
- LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'
+ LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
+ LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
},
meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
isPM: function (input) {
diff --git a/bower_components/moment/locale/tl-ph.js b/bower_components/moment/locale/tl-ph.js
index 938fd9d..06529ab 100644
--- a/bower_components/moment/locale/tl-ph.js
+++ b/bower_components/moment/locale/tl-ph.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'MM/D/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM DD, YYYY LT'
+ LLL : 'MMMM D, YYYY HH:mm',
+ LLLL : 'dddd, MMMM DD, YYYY HH:mm'
},
calendar : {
sameDay: '[Ngayon sa] LT',
diff --git a/bower_components/moment/locale/tr.js b/bower_components/moment/locale/tr.js
index f92e81d..115905e 100644
--- a/bower_components/moment/locale/tr.js
+++ b/bower_components/moment/locale/tr.js
@@ -39,11 +39,11 @@
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
diff --git a/bower_components/moment/locale/tzl.js b/bower_components/moment/locale/tzl.js
new file mode 100644
index 0000000..b932848
--- /dev/null
+++ b/bower_components/moment/locale/tzl.js
@@ -0,0 +1,84 @@
+//! moment.js locale configuration
+//! locale : talossan (tzl)
+//! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :
+ typeof define === 'function' && define.amd ? define(['moment'], factory) :
+ factory(global.moment)
+}(this, function (moment) { 'use strict';
+
+
+
+ var tzl = moment.defineLocale('tzl', {
+ months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
+ monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
+ weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
+ weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
+ weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'LT.ss',
+ L : 'DD.MM.YYYY',
+ LL : 'D. MMMM [dallas] YYYY',
+ LLL : 'D. MMMM [dallas] YYYY LT',
+ LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'd\'o' : 'D\'O';
+ } else {
+ return isLower ? 'd\'a' : 'D\'A';
+ }
+ },
+ calendar : {
+ sameDay : '[oxhi à] LT',
+ nextDay : '[demà à] LT',
+ nextWeek : 'dddd [à] LT',
+ lastDay : '[ieiri à] LT',
+ lastWeek : '[sür el] dddd [lasteu à] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'osprei %s',
+ past : 'ja%s',
+ s : processRelativeTime,
+ m : processRelativeTime,
+ mm : processRelativeTime,
+ h : processRelativeTime,
+ hh : processRelativeTime,
+ d : processRelativeTime,
+ dd : processRelativeTime,
+ M : processRelativeTime,
+ MM : processRelativeTime,
+ y : processRelativeTime,
+ yy : processRelativeTime
+ },
+ ordinalParse: /\d{1,2}\./,
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 's': ['viensas secunds', '\'iensas secunds'],
+ 'm': ['\'n míut', '\'iens míut'],
+ 'mm': [number + ' míuts', ' ' + number + ' míuts'],
+ 'h': ['\'n þora', '\'iensa þora'],
+ 'hh': [number + ' þoras', ' ' + number + ' þoras'],
+ 'd': ['\'n ziua', '\'iensa ziua'],
+ 'dd': [number + ' ziuas', ' ' + number + ' ziuas'],
+ 'M': ['\'n mes', '\'iens mes'],
+ 'MM': [number + ' mesen', ' ' + number + ' mesen'],
+ 'y': ['\'n ar', '\'iens ar'],
+ 'yy': [number + ' ars', ' ' + number + ' ars']
+ };
+ return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());
+ }
+
+ return tzl;
+
+})); \ No newline at end of file
diff --git a/bower_components/moment/locale/tzm-latn.js b/bower_components/moment/locale/tzm-latn.js
index 0442d13..7323f43 100644
--- a/bower_components/moment/locale/tzm-latn.js
+++ b/bower_components/moment/locale/tzm-latn.js
@@ -17,11 +17,11 @@
weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[asdkh g] LT',
diff --git a/bower_components/moment/locale/tzm.js b/bower_components/moment/locale/tzm.js
index a64d910..810d274 100644
--- a/bower_components/moment/locale/tzm.js
+++ b/bower_components/moment/locale/tzm.js
@@ -17,11 +17,11 @@
weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
diff --git a/bower_components/moment/locale/uk.js b/bower_components/moment/locale/uk.js
index 3a85ef8..8c2edad 100644
--- a/bower_components/moment/locale/uk.js
+++ b/bower_components/moment/locale/uk.js
@@ -69,11 +69,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY р.',
- LLL : 'D MMMM YYYY р., LT',
- LLLL : 'dddd, D MMMM YYYY р., LT'
+ LLL : 'D MMMM YYYY р., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY р., HH:mm'
},
calendar : {
sameDay: processHoursFunction('[Сьогодні '),
diff --git a/bower_components/moment/locale/uz.js b/bower_components/moment/locale/uz.js
index 4a84d00..d75360c 100644
--- a/bower_components/moment/locale/uz.js
+++ b/bower_components/moment/locale/uz.js
@@ -17,11 +17,11 @@
weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'D MMMM YYYY, dddd LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'D MMMM YYYY, dddd HH:mm'
},
calendar : {
sameDay : '[Бугун соат] LT [да]',
diff --git a/bower_components/moment/locale/vi.js b/bower_components/moment/locale/vi.js
index 4b6d289..2756a37 100644
--- a/bower_components/moment/locale/vi.js
+++ b/bower_components/moment/locale/vi.js
@@ -17,15 +17,15 @@
weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM [năm] YYYY',
- LLL : 'D MMMM [năm] YYYY LT',
- LLLL : 'dddd, D MMMM [năm] YYYY LT',
+ LLL : 'D MMMM [năm] YYYY HH:mm',
+ LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
l : 'DD/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay: '[Hôm nay lúc] LT',
diff --git a/bower_components/moment/locale/zh-cn.js b/bower_components/moment/locale/zh-cn.js
index 056c5ad..283c4ba 100644
--- a/bower_components/moment/locale/zh-cn.js
+++ b/bower_components/moment/locale/zh-cn.js
@@ -21,12 +21,12 @@
LTS : 'Ah点m分s秒',
L : 'YYYY-MM-DD',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah点mm分',
+ LLLL : 'YYYY年MMMD日ddddAh点mm分',
l : 'YYYY-MM-DD',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah点mm分',
+ llll : 'YYYY年MMMD日ddddAh点mm分'
},
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
meridiemHour: function (hour, meridiem) {
diff --git a/bower_components/moment/locale/zh-tw.js b/bower_components/moment/locale/zh-tw.js
index ce20225..e2f3075 100644
--- a/bower_components/moment/locale/zh-tw.js
+++ b/bower_components/moment/locale/zh-tw.js
@@ -20,12 +20,12 @@
LTS : 'Ah點m分s秒',
L : 'YYYY年MMMD日',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah點mm分',
+ LLLL : 'YYYY年MMMD日ddddAh點mm分',
l : 'YYYY年MMMD日',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah點mm分',
+ llll : 'YYYY年MMMD日ddddAh點mm分'
},
meridiemParse: /早上|上午|中午|下午|晚上/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/min/locales.js b/bower_components/moment/min/locales.js
index 4dfa44c..adc3e47 100644
--- a/bower_components/moment/min/locales.js
+++ b/bower_components/moment/min/locales.js
@@ -27,11 +27,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Vandag om] LT',
@@ -79,11 +79,11 @@
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
@@ -153,8 +153,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
@@ -217,11 +217,11 @@
weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[اليوم على الساعة] LT',
@@ -324,8 +324,8 @@
LTS : 'HH:mm:ss',
L : 'D/\u200FM/\u200FYYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
@@ -410,11 +410,11 @@
weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
@@ -527,11 +527,11 @@
weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сёння ў] LT',
@@ -618,11 +618,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
@@ -725,8 +725,8 @@
LTS : 'A h:mm:ss সময়',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm সময়',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
},
calendar : {
sameDay : '[আজ] LT',
@@ -761,7 +761,7 @@
return bn__symbolMap[match];
});
},
- meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,
+ meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,
isPM: function (input) {
return /^(দুপুর|বিকেল|রাত)$/.test(input);
},
@@ -772,7 +772,7 @@
if (hour < 4) {
return 'রাত';
} else if (hour < 10) {
- return 'শকাল';
+ return 'সকাল';
} else if (hour < 17) {
return 'দুপুর';
} else if (hour < 20) {
@@ -824,11 +824,11 @@
weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
longDateFormat : {
LT : 'A h:mm',
- LTS : 'LT:ss',
+ LTS : 'A h:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm'
},
calendar : {
sameDay : '[དི་རིང] LT',
@@ -945,8 +945,8 @@
LTS : 'h[e]mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D [a viz] MMMM YYYY',
- LLL : 'D [a viz] MMMM YYYY LT',
- LLLL : 'dddd, D [a viz] MMMM YYYY LT'
+ LLL : 'D [a viz] MMMM YYYY h[e]mm A',
+ LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
},
calendar : {
sameDay : '[Hiziv da] LT',
@@ -1048,11 +1048,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
@@ -1127,8 +1127,8 @@
LTS : 'LT:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -1258,11 +1258,11 @@
weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes v] LT',
@@ -1338,11 +1338,11 @@
weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
- LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT',
- LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT'
+ LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+ LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
},
calendar : {
sameDay: '[Паян] LT [сехетре]',
@@ -1391,11 +1391,11 @@
// time formats are the same as en-gb
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Heddiw am] LT',
@@ -1458,11 +1458,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd [d.] D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[I dag kl.] LT',
@@ -1526,8 +1526,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
@@ -1590,8 +1590,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
@@ -1658,8 +1658,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendarEl : {
sameDay : '[Σήμερα {}] LT',
@@ -1721,8 +1721,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
@@ -1777,8 +1777,8 @@
LTS : 'h:mm:ss A',
L : 'YYYY-MM-DD',
LL : 'D MMMM, YYYY',
- LLL : 'D MMMM, YYYY LT',
- LLLL : 'dddd, D MMMM, YYYY LT'
+ LLL : 'D MMMM, YYYY h:mm A',
+ LLLL : 'dddd, D MMMM, YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
@@ -1829,8 +1829,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
@@ -1884,11 +1884,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D[-an de] MMMM, YYYY',
- LLL : 'D[-an de] MMMM, YYYY LT',
- LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'
+ LLL : 'D[-an de] MMMM, YYYY HH:mm',
+ LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
},
meridiemParse: /[ap]\.t\.m/i,
isPM: function (input) {
@@ -1953,11 +1953,11 @@
weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY H:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -2032,11 +2032,11 @@
weekdaysMin : 'P_E_T_K_N_R_L'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Täna,] LT',
@@ -2081,15 +2081,15 @@
weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY[ko] MMMM[ren] D[a]',
- LLL : 'YYYY[ko] MMMM[ren] D[a] LT',
- LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',
+ LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
+ LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
l : 'YYYY-M-D',
ll : 'YYYY[ko] MMM D[a]',
- lll : 'YYYY[ko] MMM D[a] LT',
- llll : 'ddd, YYYY[ko] MMM D[a] LT'
+ lll : 'YYYY[ko] MMM D[a] HH:mm',
+ llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
},
calendar : {
sameDay : '[gaur] LT[etan]',
@@ -2158,11 +2158,11 @@
weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
meridiemParse: /قبل از ظهر|بعد از ظهر/,
isPM: function (input) {
@@ -2274,12 +2274,12 @@
LTS : 'HH.mm.ss',
L : 'DD.MM.YYYY',
LL : 'Do MMMM[ta] YYYY',
- LLL : 'Do MMMM[ta] YYYY, [klo] LT',
- LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',
+ LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
+ LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
l : 'D.M.YYYY',
ll : 'Do MMM YYYY',
- lll : 'Do MMM YYYY, [klo] LT',
- llll : 'ddd, Do MMM YYYY, [klo] LT'
+ lll : 'Do MMM YYYY, [klo] HH.mm',
+ llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
},
calendar : {
sameDay : '[tänään] [klo] LT',
@@ -2324,11 +2324,11 @@
weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D. MMMM, YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D. MMMM, YYYY HH:mm'
},
calendar : {
sameDay : '[Í dag kl.] LT',
@@ -2373,11 +2373,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -2402,9 +2402,9 @@
y : 'un an',
yy : '%d ans'
},
- ordinalParse: /\d{1,2}(er|)/,
+ ordinalParse: /\d{1,2}(er|e)/,
ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
+ return number + (number === 1 ? 'er' : 'e');
}
});
@@ -2420,11 +2420,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -2480,11 +2480,11 @@
weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[hjoed om] LT',
@@ -2531,11 +2531,11 @@
weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -2597,15 +2597,15 @@
weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [ב]MMMM YYYY',
- LLL : 'D [ב]MMMM YYYY LT',
- LLLL : 'dddd, D [ב]MMMM YYYY LT',
+ LLL : 'D [ב]MMMM YYYY HH:mm',
+ LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
l : 'D/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay : '[היום ב־]LT',
@@ -2694,8 +2694,8 @@
LTS : 'A h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
},
calendar : {
sameDay : '[आज] LT',
@@ -2831,11 +2831,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
@@ -2941,11 +2941,11 @@
weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'YYYY.MM.DD.',
LL : 'YYYY. MMMM D.',
- LLL : 'YYYY. MMMM D., LT',
- LLLL : 'YYYY. MMMM D., dddd LT'
+ LLL : 'YYYY. MMMM D. H:mm',
+ LLLL : 'YYYY. MMMM D., dddd H:mm'
},
meridiemParse: /de|du/i,
isPM: function (input) {
@@ -3024,11 +3024,11 @@
weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY թ.',
- LLL : 'D MMMM YYYY թ., LT',
- LLLL : 'dddd, D MMMM YYYY թ., LT'
+ LLL : 'D MMMM YYYY թ., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
},
calendar : {
sameDay: '[այսօր] LT',
@@ -3106,11 +3106,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|siang|sore|malam/,
meridiemHour : function (hour, meridiem) {
@@ -3244,11 +3244,11 @@
weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd, D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H:mm',
+ LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
},
calendar : {
sameDay : '[í dag kl.] LT',
@@ -3294,11 +3294,11 @@
weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Oggi alle] LT',
@@ -3352,11 +3352,11 @@
weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
longDateFormat : {
LT : 'Ah時m分',
- LTS : 'LTs秒',
+ LTS : 'Ah時m分s秒',
L : 'YYYY/MM/DD',
LL : 'YYYY年M月D日',
- LLL : 'YYYY年M月D日LT',
- LLLL : 'YYYY年M月D日LT dddd'
+ LLL : 'YYYY年M月D日Ah時m分',
+ LLLL : 'YYYY年M月D日Ah時m分 dddd'
},
meridiemParse: /午前|午後/i,
isPM : function (input) {
@@ -3407,11 +3407,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /enjing|siyang|sonten|ndalu/,
meridiemHour : function (hour, meridiem) {
@@ -3502,8 +3502,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[დღეს] LT[-ზე]',
@@ -3570,11 +3570,11 @@
weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
@@ -3624,8 +3624,8 @@
LTS : 'A h시 m분 s초',
L : 'YYYY.MM.DD',
LL : 'YYYY년 MMMM D일',
- LLL : 'YYYY년 MMMM D일 LT',
- LLLL : 'YYYY년 MMMM D일 dddd LT'
+ LLL : 'YYYY년 MMMM D일 A h시 m분',
+ LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
},
calendar : {
sameDay : '오늘 LT',
@@ -3742,8 +3742,8 @@
LTS: 'H:mm:ss [Auer]',
L: 'DD.MM.YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm [Auer]',
+ LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
},
calendar: {
sameDay: '[Haut um] LT',
@@ -3809,6 +3809,16 @@
return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
}
}
+ function lt__monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
+ 'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')
+ },
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
+ return months[nounCase][m.month()];
+ }
function translateSingular(number, withoutSuffix, key, isFuture) {
return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
}
@@ -3839,22 +3849,22 @@
}
var lt = moment.defineLocale('lt', {
- months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
+ months : lt__monthsCaseReplace,
monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
weekdays : relativeWeekDay,
weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY [m.] MMMM D [d.]',
- LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',
- LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',
+ LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
l : 'YYYY-MM-DD',
ll : 'YYYY [m.] MMMM D [d.]',
- lll : 'YYYY [m.] MMMM D [d.], LT [val.]',
- llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'
+ lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
},
calendar : {
sameDay : '[Šiandien] LT',
@@ -3937,11 +3947,11 @@
weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY.',
LL : 'YYYY. [gada] D. MMMM',
- LLL : 'YYYY. [gada] D. MMMM, LT',
- LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'
+ LLL : 'YYYY. [gada] D. MMMM, HH:mm',
+ LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
},
calendar : {
sameDay : '[Šodien pulksten] LT',
@@ -4009,11 +4019,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
@@ -4084,11 +4094,11 @@
weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Денес во] LT',
@@ -4166,8 +4176,8 @@
LTS : 'A h:mm:ss -നു',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm -നു',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
},
calendar : {
sameDay : '[ഇന്ന്] LT',
@@ -4251,8 +4261,8 @@
LTS : 'A h:mm:ss वाजता',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm वाजता',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
},
calendar : {
sameDay : '[आज] LT',
@@ -4333,11 +4343,82 @@
weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
+ },
+ meridiemParse: /pagi|tengahari|petang|malam/,
+ meridiemHour: function (hour, meridiem) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ if (meridiem === 'pagi') {
+ return hour;
+ } else if (meridiem === 'tengahari') {
+ return hour >= 11 ? hour : hour + 12;
+ } else if (meridiem === 'petang' || meridiem === 'malam') {
+ return hour + 12;
+ }
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'tengahari';
+ } else if (hours < 19) {
+ return 'petang';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Esok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kelmarin pukul] LT',
+ lastWeek : 'dddd [lepas pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'dalam %s',
+ past : '%s yang lepas',
+ s : 'beberapa saat',
+ m : 'seminit',
+ mm : '%d minit',
+ h : 'sejam',
+ hh : '%d jam',
+ d : 'sehari',
+ dd : '%d hari',
+ M : 'sebulan',
+ MM : '%d bulan',
+ y : 'setahun',
+ yy : '%d tahun'
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+
+ //! moment.js locale configuration
+ //! locale : Bahasa Malaysia (ms-MY)
+ //! author : Weldan Jamili : https://github.com/weldan
+
+ var ms = moment.defineLocale('ms', {
+ months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
+ monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
+ weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
+ weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
+ weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'HH.mm.ss',
+ L : 'DD/MM/YYYY',
+ LL : 'D MMMM YYYY',
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|tengahari|petang|malam/,
meridiemHour: function (hour, meridiem) {
@@ -4432,8 +4513,8 @@
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ယနေ.] LT [မှာ]',
@@ -4487,11 +4568,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'H.mm',
- LTS : 'LT.ss',
+ LTS : 'H.mm.ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H.mm',
+ LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'
},
calendar : {
sameDay: '[i dag kl.] LT',
@@ -4564,8 +4645,8 @@
LTS : 'Aको h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, Aको h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
},
preparse: function (string) {
return string.replace(/[१२३४५६७८९०]/g, function (match) {
@@ -4657,11 +4738,11 @@
weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[vandaag om] LT',
@@ -4708,11 +4789,11 @@
weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[I dag klokka] LT',
@@ -4791,11 +4872,11 @@
weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Dziś o] LT',
@@ -4851,11 +4932,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY [às] LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'
+ LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -4872,7 +4953,7 @@
relativeTime : {
future : 'em %s',
past : '%s atrás',
- s : 'segundos',
+ s : 'poucos segundos',
m : 'um minuto',
mm : '%d minutos',
h : 'uma hora',
@@ -4900,11 +4981,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -4969,7 +5050,7 @@
weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
@@ -5068,11 +5149,11 @@
monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сегодня в] LT',
@@ -5172,8 +5253,8 @@
LTS : 'a h:mm:ss',
L : 'YYYY/MM/DD',
LL : 'YYYY MMMM D',
- LLL : 'YYYY MMMM D, LT',
- LLLL : 'YYYY MMMM D [වැනි] dddd, LTS'
+ LLL : 'YYYY MMMM D, a h:mm',
+ LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
},
calendar : {
sameDay : '[අද] LT[ට]',
@@ -5290,11 +5371,11 @@
weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes o] LT',
@@ -5441,11 +5522,11 @@
weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danes ob] LT',
@@ -5528,11 +5609,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Sot në] LT',
@@ -5600,11 +5681,11 @@
weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[данас у] LT',
@@ -5697,11 +5778,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
@@ -5771,11 +5852,11 @@
weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Idag] LT',
@@ -5827,11 +5908,11 @@
weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, HH:mm',
+ LLLL : 'dddd, D MMMM YYYY, HH:mm'
},
calendar : {
sameDay : '[இன்று] LT',
@@ -5911,11 +5992,11 @@
weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
longDateFormat : {
LT : 'H นาฬิกา m นาที',
- LTS : 'LT s วินาที',
+ LTS : 'H นาฬิกา m นาที s วินาที',
L : 'YYYY/MM/DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY เวลา LT',
- LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'
+ LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
+ LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
},
meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
isPM: function (input) {
@@ -5965,11 +6046,11 @@
weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'MM/D/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM DD, YYYY LT'
+ LLL : 'MMMM D, YYYY HH:mm',
+ LLLL : 'dddd, MMMM DD, YYYY HH:mm'
},
calendar : {
sameDay: '[Ngayon sa] LT',
@@ -6038,11 +6119,11 @@
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
@@ -6084,6 +6165,80 @@
});
//! moment.js locale configuration
+ //! locale : talossan (tzl)
+ //! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
+
+
+ var tzl = moment.defineLocale('tzl', {
+ months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
+ monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
+ weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
+ weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
+ weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'LT.ss',
+ L : 'DD.MM.YYYY',
+ LL : 'D. MMMM [dallas] YYYY',
+ LLL : 'D. MMMM [dallas] YYYY LT',
+ LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'd\'o' : 'D\'O';
+ } else {
+ return isLower ? 'd\'a' : 'D\'A';
+ }
+ },
+ calendar : {
+ sameDay : '[oxhi à] LT',
+ nextDay : '[demà à] LT',
+ nextWeek : 'dddd [à] LT',
+ lastDay : '[ieiri à] LT',
+ lastWeek : '[sür el] dddd [lasteu à] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'osprei %s',
+ past : 'ja%s',
+ s : tzl__processRelativeTime,
+ m : tzl__processRelativeTime,
+ mm : tzl__processRelativeTime,
+ h : tzl__processRelativeTime,
+ hh : tzl__processRelativeTime,
+ d : tzl__processRelativeTime,
+ dd : tzl__processRelativeTime,
+ M : tzl__processRelativeTime,
+ MM : tzl__processRelativeTime,
+ y : tzl__processRelativeTime,
+ yy : tzl__processRelativeTime
+ },
+ ordinalParse: /\d{1,2}\./,
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+
+ function tzl__processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 's': ['viensas secunds', '\'iensas secunds'],
+ 'm': ['\'n míut', '\'iens míut'],
+ 'mm': [number + ' míuts', ' ' + number + ' míuts'],
+ 'h': ['\'n þora', '\'iensa þora'],
+ 'hh': [number + ' þoras', ' ' + number + ' þoras'],
+ 'd': ['\'n ziua', '\'iensa ziua'],
+ 'dd': [number + ' ziuas', ' ' + number + ' ziuas'],
+ 'M': ['\'n mes', '\'iens mes'],
+ 'MM': [number + ' mesen', ' ' + number + ' mesen'],
+ 'y': ['\'n ar', '\'iens ar'],
+ 'yy': [number + ' ars', ' ' + number + ' ars']
+ };
+ return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());
+ }
+
+ //! moment.js locale configuration
//! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
//! author : Abdel Said : https://github.com/abdelsaid
@@ -6095,11 +6250,11 @@
weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[asdkh g] LT',
@@ -6142,11 +6297,11 @@
weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
@@ -6241,11 +6396,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY р.',
- LLL : 'D MMMM YYYY р., LT',
- LLLL : 'dddd, D MMMM YYYY р., LT'
+ LLL : 'D MMMM YYYY р., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY р., HH:mm'
},
calendar : {
sameDay: processHoursFunction('[Сьогодні '),
@@ -6331,11 +6486,11 @@
weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'D MMMM YYYY, dddd LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'D MMMM YYYY, dddd HH:mm'
},
calendar : {
sameDay : '[Бугун соат] LT [да]',
@@ -6378,15 +6533,15 @@
weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM [năm] YYYY',
- LLL : 'D MMMM [năm] YYYY LT',
- LLLL : 'dddd, D MMMM [năm] YYYY LT',
+ LLL : 'D MMMM [năm] YYYY HH:mm',
+ LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
l : 'DD/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay: '[Hôm nay lúc] LT',
@@ -6437,12 +6592,12 @@
LTS : 'Ah点m分s秒',
L : 'YYYY-MM-DD',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah点mm分',
+ LLLL : 'YYYY年MMMD日ddddAh点mm分',
l : 'YYYY-MM-DD',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah点mm分',
+ llll : 'YYYY年MMMD日ddddAh点mm分'
},
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
meridiemHour: function (hour, meridiem) {
@@ -6552,12 +6707,12 @@
LTS : 'Ah點m分s秒',
L : 'YYYY年MMMD日',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah點mm分',
+ LLLL : 'YYYY年MMMD日ddddAh點mm分',
l : 'YYYY年MMMD日',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah點mm分',
+ llll : 'YYYY年MMMD日ddddAh點mm分'
},
meridiemParse: /早上|上午|中午|下午|晚上/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/min/moment-with-locales.js b/bower_components/moment/min/moment-with-locales.js
index 61145c0..e2bc4a1 100644
--- a/bower_components/moment/min/moment-with-locales.js
+++ b/bower_components/moment/min/moment-with-locales.js
@@ -88,6 +88,7 @@
flags.overflow < 0 &&
!flags.empty &&
!flags.invalidMonth &&
+ !flags.invalidWeekday &&
!flags.nullInput &&
!flags.invalidFormat &&
!flags.userInvalidated;
@@ -168,7 +169,7 @@
// Moment prototype object
function Moment(config) {
copyConfig(this, config);
- this._d = new Date(+config._d);
+ this._d = new Date(config._d != null ? config._d.getTime() : NaN);
// Prevent infinite loop in case updateOffset creates new moment
// objects.
if (updateInProgress === false) {
@@ -182,16 +183,20 @@
return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
}
+ function absFloor (number) {
+ if (number < 0) {
+ return Math.ceil(number);
+ } else {
+ return Math.floor(number);
+ }
+ }
+
function toInt(argumentForCoercion) {
var coercedNumber = +argumentForCoercion,
value = 0;
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
- if (coercedNumber >= 0) {
- value = Math.floor(coercedNumber);
- } else {
- value = Math.ceil(coercedNumber);
- }
+ value = absFloor(coercedNumber);
}
return value;
@@ -289,9 +294,7 @@
function defineLocale (name, values) {
if (values !== null) {
values.abbr = name;
- if (!locales[name]) {
- locales[name] = new Locale();
- }
+ locales[name] = locales[name] || new Locale();
locales[name].set(values);
// backwards compat for now: also set the locale
@@ -395,16 +398,14 @@
}
function zeroFill(number, targetLength, forceSign) {
- var output = '' + Math.abs(number),
+ var absNumber = '' + Math.abs(number),
+ zerosToFill = targetLength - absNumber.length,
sign = number >= 0;
-
- while (output.length < targetLength) {
- output = '0' + output;
- }
- return (sign ? (forceSign ? '+' : '') : '-') + output;
+ return (sign ? (forceSign ? '+' : '') : '-') +
+ Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}
- var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;
+ var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
@@ -472,10 +473,7 @@
}
format = expandFormat(format, m.localeData());
-
- if (!formatFunctions[format]) {
- formatFunctions[format] = makeFormatFunction(format);
- }
+ formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
return formatFunctions[format](m);
}
@@ -519,8 +517,15 @@
var regexes = {};
+ function isFunction (sth) {
+ // https://github.com/moment/moment/issues/2325
+ return typeof sth === 'function' &&
+ Object.prototype.toString.call(sth) === '[object Function]';
+ }
+
+
function addRegexToken (token, regex, strictRegex) {
- regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict) {
return (isStrict && strictRegex) ? strictRegex : regex;
};
}
@@ -728,12 +733,11 @@
}
function deprecate(msg, fn) {
- var firstTime = true,
- msgWithStack = msg + '\n' + (new Error()).stack;
+ var firstTime = true;
return extend(function () {
if (firstTime) {
- warn(msgWithStack);
+ warn(msg + '\n' + (new Error()).stack);
firstTime = false;
}
return fn.apply(this, arguments);
@@ -781,14 +785,14 @@
getParsingFlags(config).iso = true;
for (i = 0, l = isoDates.length; i < l; i++) {
if (isoDates[i][1].exec(string)) {
- // match[5] should be 'T' or undefined
- config._f = isoDates[i][0] + (match[6] || ' ');
+ config._f = isoDates[i][0];
break;
}
}
for (i = 0, l = isoTimes.length; i < l; i++) {
if (isoTimes[i][1].exec(string)) {
- config._f += isoTimes[i][0];
+ // match[6] should be 'T' or space
+ config._f += (match[6] || ' ') + isoTimes[i][0];
break;
}
}
@@ -867,7 +871,10 @@
addRegexToken('YYYYY', match1to6, match6);
addRegexToken('YYYYYY', match1to6, match6);
- addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);
+ addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+ addParseToken('YYYY', function (input, array) {
+ array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
+ });
addParseToken('YY', function (input, array) {
array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
});
@@ -994,18 +1001,18 @@
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
- var d = createUTCDate(year, 0, 1).getUTCDay();
- var daysToAdd;
- var dayOfYear;
+ var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
+ if (d < firstDayOfWeek) {
+ d += 7;
+ }
- d = d === 0 ? 7 : d;
- weekday = weekday != null ? weekday : firstDayOfWeek;
- daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
- dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
+ weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
+
+ dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
return {
- year : dayOfYear > 0 ? year : year - 1,
- dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+ year: dayOfYear > 0 ? year : year - 1,
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
};
}
@@ -1291,9 +1298,19 @@
}
function createFromConfig (config) {
+ var res = new Moment(checkOverflow(prepareConfig(config)));
+ if (res._nextDay) {
+ // Adding is smart enough around DST
+ res.add(1, 'd');
+ res._nextDay = undefined;
+ }
+
+ return res;
+ }
+
+ function prepareConfig (config) {
var input = config._i,
- format = config._f,
- res;
+ format = config._f;
config._locale = config._locale || locale_locales__getLocale(config._l);
@@ -1317,14 +1334,7 @@
configFromInput(config);
}
- res = new Moment(checkOverflow(config));
- if (res._nextDay) {
- // Adding is smart enough around DST
- res.add(1, 'd');
- res._nextDay = undefined;
- }
-
- return res;
+ return config;
}
function configFromInput(config) {
@@ -1404,7 +1414,7 @@
}
res = moments[0];
for (i = 1; i < moments.length; ++i) {
- if (moments[i][fn](res)) {
+ if (!moments[i].isValid() || moments[i][fn](res)) {
res = moments[i];
}
}
@@ -1516,7 +1526,6 @@
} else {
return local__createLocal(input).local();
}
- return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();
}
function getDateOffset (m) {
@@ -1616,12 +1625,7 @@
}
function hasAlignedHourOffset (input) {
- if (!input) {
- input = 0;
- }
- else {
- input = local__createLocal(input).utcOffset();
- }
+ input = input ? local__createLocal(input).utcOffset() : 0;
return (this.utcOffset() - input) % 60 === 0;
}
@@ -1634,12 +1638,24 @@
}
function isDaylightSavingTimeShifted () {
- if (this._a) {
- var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);
- return this.isValid() && compareArrays(this._a, other.toArray()) > 0;
+ if (typeof this._isDSTShifted !== 'undefined') {
+ return this._isDSTShifted;
}
- return false;
+ var c = {};
+
+ copyConfig(c, this);
+ c = prepareConfig(c);
+
+ if (c._a) {
+ var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
+ this._isDSTShifted = this.isValid() &&
+ compareArrays(c._a, other.toArray()) > 0;
+ } else {
+ this._isDSTShifted = false;
+ }
+
+ return this._isDSTShifted;
}
function isLocal () {
@@ -1799,7 +1815,7 @@
var add_subtract__add = createAdder(1, 'add');
var add_subtract__subtract = createAdder(-1, 'subtract');
- function moment_calendar__calendar (time) {
+ function moment_calendar__calendar (time, formats) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're local/utc/offset or not.
var now = time || local__createLocal(),
@@ -1811,7 +1827,7 @@
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(this.localeData().calendar(format, this, local__createLocal(now)));
+ return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
}
function clone () {
@@ -1858,14 +1874,6 @@
}
}
- function absFloor (number) {
- if (number < 0) {
- return Math.ceil(number);
- } else {
- return Math.floor(number);
- }
- }
-
function diff (input, units, asFloat) {
var that = cloneWithOffset(input, this),
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
@@ -2056,6 +2064,19 @@
return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
}
+ function toObject () {
+ var m = this;
+ return {
+ years: m.year(),
+ months: m.month(),
+ date: m.date(),
+ hours: m.hours(),
+ minutes: m.minutes(),
+ seconds: m.seconds(),
+ milliseconds: m.milliseconds()
+ };
+ }
+
function moment_valid__isValid () {
return valid__isValid(this);
}
@@ -2227,18 +2248,20 @@
// HELPERS
function parseWeekday(input, locale) {
- if (typeof input === 'string') {
- if (!isNaN(input)) {
- input = parseInt(input, 10);
- }
- else {
- input = locale.weekdaysParse(input);
- if (typeof input !== 'number') {
- return null;
- }
- }
+ if (typeof input !== 'string') {
+ return input;
+ }
+
+ if (!isNaN(input)) {
+ return parseInt(input, 10);
+ }
+
+ input = locale.weekdaysParse(input);
+ if (typeof input === 'number') {
+ return input;
}
- return input;
+
+ return null;
}
// LOCALES
@@ -2261,9 +2284,7 @@
function localeWeekdaysParse (weekdayName) {
var i, mom, regex;
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- }
+ this._weekdaysParse = this._weekdaysParse || [];
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
@@ -2410,12 +2431,26 @@
return ~~(this.millisecond() / 10);
});
- function millisecond__milliseconds (token) {
- addFormatToken(0, [token, 3], 0, 'millisecond');
- }
+ addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+ addFormatToken(0, ['SSSS', 4], 0, function () {
+ return this.millisecond() * 10;
+ });
+ addFormatToken(0, ['SSSSS', 5], 0, function () {
+ return this.millisecond() * 100;
+ });
+ addFormatToken(0, ['SSSSSS', 6], 0, function () {
+ return this.millisecond() * 1000;
+ });
+ addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+ return this.millisecond() * 10000;
+ });
+ addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+ return this.millisecond() * 100000;
+ });
+ addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+ return this.millisecond() * 1000000;
+ });
- millisecond__milliseconds('SSS');
- millisecond__milliseconds('SSSS');
// ALIASES
@@ -2426,11 +2461,19 @@
addRegexToken('S', match1to3, match1);
addRegexToken('SS', match1to3, match2);
addRegexToken('SSS', match1to3, match3);
- addRegexToken('SSSS', matchUnsigned);
- addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {
+
+ var token;
+ for (token = 'SSSS'; token.length <= 9; token += 'S') {
+ addRegexToken(token, matchUnsigned);
+ }
+
+ function parseMs(input, array) {
array[MILLISECOND] = toInt(('0.' + input) * 1000);
- });
+ }
+ for (token = 'S'; token.length <= 9; token += 'S') {
+ addParseToken(token, parseMs);
+ }
// MOMENTS
var getSetMillisecond = makeGetSet('Milliseconds', false);
@@ -2477,6 +2520,7 @@
momentPrototype__proto.startOf = startOf;
momentPrototype__proto.subtract = add_subtract__subtract;
momentPrototype__proto.toArray = toArray;
+ momentPrototype__proto.toObject = toObject;
momentPrototype__proto.toDate = toDate;
momentPrototype__proto.toISOString = moment_format__toISOString;
momentPrototype__proto.toJSON = moment_format__toISOString;
@@ -2576,19 +2620,23 @@
LT : 'h:mm A',
L : 'MM/DD/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM D, YYYY LT'
+ LLL : 'MMMM D, YYYY h:mm A',
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
};
function longDateFormat (key) {
- var output = this._longDateFormat[key];
- if (!output && this._longDateFormat[key.toUpperCase()]) {
- output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
- return val.slice(1);
- });
- this._longDateFormat[key] = output;
+ var format = this._longDateFormat[key],
+ formatUpper = this._longDateFormat[key.toUpperCase()];
+
+ if (format || !formatUpper) {
+ return format;
}
- return output;
+
+ this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+ return val.slice(1);
+ });
+
+ return this._longDateFormat[key];
}
var defaultInvalidDate = 'Invalid date';
@@ -2797,12 +2845,29 @@
return duration_add_subtract__addSubtract(this, input, value, -1);
}
+ function absCeil (number) {
+ if (number < 0) {
+ return Math.floor(number);
+ } else {
+ return Math.ceil(number);
+ }
+ }
+
function bubble () {
var milliseconds = this._milliseconds;
var days = this._days;
var months = this._months;
var data = this._data;
- var seconds, minutes, hours, years = 0;
+ var seconds, minutes, hours, years, monthsFromDays;
+
+ // if we have a mix of positive and negative values, bubble down first
+ // check: https://github.com/moment/moment/issues/2166
+ if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+ (milliseconds <= 0 && days <= 0 && months <= 0))) {
+ milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+ days = 0;
+ months = 0;
+ }
// The following code bubbles up values, see the tests for
// examples of what that means.
@@ -2819,17 +2884,13 @@
days += absFloor(hours / 24);
- // Accurately convert days to years, assume start from year 0.
- years = absFloor(daysToYears(days));
- days -= absFloor(yearsToDays(years));
-
- // 30 days to a month
- // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
- months += absFloor(days / 30);
- days %= 30;
+ // convert days to months
+ monthsFromDays = absFloor(daysToMonths(days));
+ months += monthsFromDays;
+ days -= absCeil(monthsToDays(monthsFromDays));
// 12 months -> 1 year
- years += absFloor(months / 12);
+ years = absFloor(months / 12);
months %= 12;
data.days = days;
@@ -2839,15 +2900,15 @@
return this;
}
- function daysToYears (days) {
+ function daysToMonths (days) {
// 400 years have 146097 days (taking into account leap year rules)
- return days * 400 / 146097;
+ // 400 years have 12 months === 4800
+ return days * 4800 / 146097;
}
- function yearsToDays (years) {
- // years * 365 + absFloor(years / 4) -
- // absFloor(years / 100) + absFloor(years / 400);
- return years * 146097 / 400;
+ function monthsToDays (months) {
+ // the reverse of daysToMonths
+ return months * 146097 / 4800;
}
function as (units) {
@@ -2859,11 +2920,11 @@
if (units === 'month' || units === 'year') {
days = this._days + milliseconds / 864e5;
- months = this._months + daysToYears(days) * 12;
+ months = this._months + daysToMonths(days);
return units === 'month' ? months : months / 12;
} else {
// handle milliseconds separately because of floating point math errors (issue #1867)
- days = this._days + Math.round(yearsToDays(this._months / 12));
+ days = this._days + Math.round(monthsToDays(this._months));
switch (units) {
case 'week' : return days / 7 + milliseconds / 6048e5;
case 'day' : return days + milliseconds / 864e5;
@@ -2913,7 +2974,7 @@
};
}
- var duration_get__milliseconds = makeGetter('milliseconds');
+ var milliseconds = makeGetter('milliseconds');
var seconds = makeGetter('seconds');
var minutes = makeGetter('minutes');
var hours = makeGetter('hours');
@@ -2991,13 +3052,36 @@
var iso_string__abs = Math.abs;
function iso_string__toISOString() {
+ // for ISO strings we do not use the normal bubbling rules:
+ // * milliseconds bubble up until they become hours
+ // * days do not bubble at all
+ // * months bubble up until they become years
+ // This is because there is no context-free conversion between hours and days
+ // (think of clock changes)
+ // and also not between days and months (28-31 days per month)
+ var seconds = iso_string__abs(this._milliseconds) / 1000;
+ var days = iso_string__abs(this._days);
+ var months = iso_string__abs(this._months);
+ var minutes, hours, years;
+
+ // 3600 seconds -> 60 minutes -> 1 hour
+ minutes = absFloor(seconds / 60);
+ hours = absFloor(minutes / 60);
+ seconds %= 60;
+ minutes %= 60;
+
+ // 12 months -> 1 year
+ years = absFloor(months / 12);
+ months %= 12;
+
+
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
- var Y = iso_string__abs(this.years());
- var M = iso_string__abs(this.months());
- var D = iso_string__abs(this.days());
- var h = iso_string__abs(this.hours());
- var m = iso_string__abs(this.minutes());
- var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);
+ var Y = years;
+ var M = months;
+ var D = days;
+ var h = hours;
+ var m = minutes;
+ var s = seconds;
var total = this.asSeconds();
if (!total) {
@@ -3034,7 +3118,7 @@
duration_prototype__proto.valueOf = duration_as__valueOf;
duration_prototype__proto._bubble = bubble;
duration_prototype__proto.get = duration_get__get;
- duration_prototype__proto.milliseconds = duration_get__milliseconds;
+ duration_prototype__proto.milliseconds = milliseconds;
duration_prototype__proto.seconds = seconds;
duration_prototype__proto.minutes = minutes;
duration_prototype__proto.hours = hours;
@@ -3074,12 +3158,12 @@
;
//! moment.js
- //! version : 2.10.3
+ //! version : 2.10.6
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
- utils_hooks__hooks.version = '2.10.3';
+ utils_hooks__hooks.version = '2.10.6';
setHookCallback(local__createLocal);
@@ -3130,11 +3214,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Vandag om] LT',
@@ -3182,11 +3266,11 @@
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
@@ -3256,8 +3340,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
@@ -3320,11 +3404,11 @@
weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[اليوم على الساعة] LT',
@@ -3427,8 +3511,8 @@
LTS : 'HH:mm:ss',
L : 'D/\u200FM/\u200FYYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
@@ -3513,11 +3597,11 @@
weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
@@ -3630,11 +3714,11 @@
weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сёння ў] LT',
@@ -3721,11 +3805,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
@@ -3828,8 +3912,8 @@
LTS : 'A h:mm:ss সময়',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm সময়',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
},
calendar : {
sameDay : '[আজ] LT',
@@ -3864,7 +3948,7 @@
return bn__symbolMap[match];
});
},
- meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,
+ meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,
isPM: function (input) {
return /^(দুপুর|বিকেল|রাত)$/.test(input);
},
@@ -3875,7 +3959,7 @@
if (hour < 4) {
return 'রাত';
} else if (hour < 10) {
- return 'শকাল';
+ return 'সকাল';
} else if (hour < 17) {
return 'দুপুর';
} else if (hour < 20) {
@@ -3927,11 +4011,11 @@
weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
longDateFormat : {
LT : 'A h:mm',
- LTS : 'LT:ss',
+ LTS : 'A h:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm'
},
calendar : {
sameDay : '[དི་རིང] LT',
@@ -4048,8 +4132,8 @@
LTS : 'h[e]mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D [a viz] MMMM YYYY',
- LLL : 'D [a viz] MMMM YYYY LT',
- LLLL : 'dddd, D [a viz] MMMM YYYY LT'
+ LLL : 'D [a viz] MMMM YYYY h[e]mm A',
+ LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
},
calendar : {
sameDay : '[Hiziv da] LT',
@@ -4151,11 +4235,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
@@ -4230,8 +4314,8 @@
LTS : 'LT:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -4361,11 +4445,11 @@
weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes v] LT',
@@ -4441,11 +4525,11 @@
weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
- LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT',
- LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT'
+ LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+ LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
},
calendar : {
sameDay: '[Паян] LT [сехетре]',
@@ -4494,11 +4578,11 @@
// time formats are the same as en-gb
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Heddiw am] LT',
@@ -4561,11 +4645,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd [d.] D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[I dag kl.] LT',
@@ -4629,8 +4713,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
@@ -4693,8 +4777,8 @@
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
@@ -4761,8 +4845,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendarEl : {
sameDay : '[Σήμερα {}] LT',
@@ -4824,8 +4908,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
@@ -4880,8 +4964,8 @@
LTS : 'h:mm:ss A',
L : 'YYYY-MM-DD',
LL : 'D MMMM, YYYY',
- LLL : 'D MMMM, YYYY LT',
- LLLL : 'dddd, D MMMM, YYYY LT'
+ LLL : 'D MMMM, YYYY h:mm A',
+ LLLL : 'dddd, D MMMM, YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
@@ -4932,8 +5016,8 @@
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
@@ -4987,11 +5071,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D[-an de] MMMM, YYYY',
- LLL : 'D[-an de] MMMM, YYYY LT',
- LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'
+ LLL : 'D[-an de] MMMM, YYYY HH:mm',
+ LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
},
meridiemParse: /[ap]\.t\.m/i,
isPM: function (input) {
@@ -5056,11 +5140,11 @@
weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY H:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -5135,11 +5219,11 @@
weekdaysMin : 'P_E_T_K_N_R_L'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Täna,] LT',
@@ -5184,15 +5268,15 @@
weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY[ko] MMMM[ren] D[a]',
- LLL : 'YYYY[ko] MMMM[ren] D[a] LT',
- LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',
+ LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
+ LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
l : 'YYYY-M-D',
ll : 'YYYY[ko] MMM D[a]',
- lll : 'YYYY[ko] MMM D[a] LT',
- llll : 'ddd, YYYY[ko] MMM D[a] LT'
+ lll : 'YYYY[ko] MMM D[a] HH:mm',
+ llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
},
calendar : {
sameDay : '[gaur] LT[etan]',
@@ -5261,11 +5345,11 @@
weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
meridiemParse: /قبل از ظهر|بعد از ظهر/,
isPM: function (input) {
@@ -5377,12 +5461,12 @@
LTS : 'HH.mm.ss',
L : 'DD.MM.YYYY',
LL : 'Do MMMM[ta] YYYY',
- LLL : 'Do MMMM[ta] YYYY, [klo] LT',
- LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',
+ LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
+ LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
l : 'D.M.YYYY',
ll : 'Do MMM YYYY',
- lll : 'Do MMM YYYY, [klo] LT',
- llll : 'ddd, Do MMM YYYY, [klo] LT'
+ lll : 'Do MMM YYYY, [klo] HH.mm',
+ llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
},
calendar : {
sameDay : '[tänään] [klo] LT',
@@ -5427,11 +5511,11 @@
weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D. MMMM, YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D. MMMM, YYYY HH:mm'
},
calendar : {
sameDay : '[Í dag kl.] LT',
@@ -5476,11 +5560,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -5505,9 +5589,9 @@
y : 'un an',
yy : '%d ans'
},
- ordinalParse: /\d{1,2}(er|)/,
+ ordinalParse: /\d{1,2}(er|e)/,
ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
+ return number + (number === 1 ? 'er' : 'e');
}
});
@@ -5523,11 +5607,11 @@
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -5583,11 +5667,11 @@
weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[hjoed om] LT',
@@ -5634,11 +5718,11 @@
weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
@@ -5700,15 +5784,15 @@
weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [ב]MMMM YYYY',
- LLL : 'D [ב]MMMM YYYY LT',
- LLLL : 'dddd, D [ב]MMMM YYYY LT',
+ LLL : 'D [ב]MMMM YYYY HH:mm',
+ LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
l : 'D/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay : '[היום ב־]LT',
@@ -5797,8 +5881,8 @@
LTS : 'A h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
},
calendar : {
sameDay : '[आज] LT',
@@ -5934,11 +6018,11 @@
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
@@ -6044,11 +6128,11 @@
weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'YYYY.MM.DD.',
LL : 'YYYY. MMMM D.',
- LLL : 'YYYY. MMMM D., LT',
- LLLL : 'YYYY. MMMM D., dddd LT'
+ LLL : 'YYYY. MMMM D. H:mm',
+ LLLL : 'YYYY. MMMM D., dddd H:mm'
},
meridiemParse: /de|du/i,
isPM: function (input) {
@@ -6127,11 +6211,11 @@
weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY թ.',
- LLL : 'D MMMM YYYY թ., LT',
- LLLL : 'dddd, D MMMM YYYY թ., LT'
+ LLL : 'D MMMM YYYY թ., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
},
calendar : {
sameDay: '[այսօր] LT',
@@ -6209,11 +6293,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|siang|sore|malam/,
meridiemHour : function (hour, meridiem) {
@@ -6347,11 +6431,11 @@
weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd, D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H:mm',
+ LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
},
calendar : {
sameDay : '[í dag kl.] LT',
@@ -6397,11 +6481,11 @@
weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Oggi alle] LT',
@@ -6455,11 +6539,11 @@
weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
longDateFormat : {
LT : 'Ah時m分',
- LTS : 'LTs秒',
+ LTS : 'Ah時m分s秒',
L : 'YYYY/MM/DD',
LL : 'YYYY年M月D日',
- LLL : 'YYYY年M月D日LT',
- LLLL : 'YYYY年M月D日LT dddd'
+ LLL : 'YYYY年M月D日Ah時m分',
+ LLLL : 'YYYY年M月D日Ah時m分 dddd'
},
meridiemParse: /午前|午後/i,
isPM : function (input) {
@@ -6510,11 +6594,11 @@
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /enjing|siyang|sonten|ndalu/,
meridiemHour : function (hour, meridiem) {
@@ -6605,8 +6689,8 @@
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[დღეს] LT[-ზე]',
@@ -6673,11 +6757,11 @@
weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
@@ -6727,8 +6811,8 @@
LTS : 'A h시 m분 s초',
L : 'YYYY.MM.DD',
LL : 'YYYY년 MMMM D일',
- LLL : 'YYYY년 MMMM D일 LT',
- LLLL : 'YYYY년 MMMM D일 dddd LT'
+ LLL : 'YYYY년 MMMM D일 A h시 m분',
+ LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
},
calendar : {
sameDay : '오늘 LT',
@@ -6845,8 +6929,8 @@
LTS: 'H:mm:ss [Auer]',
L: 'DD.MM.YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm [Auer]',
+ LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
},
calendar: {
sameDay: '[Haut um] LT',
@@ -6912,6 +6996,16 @@
return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
}
}
+ function lt__monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
+ 'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')
+ },
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
+ return months[nounCase][m.month()];
+ }
function translateSingular(number, withoutSuffix, key, isFuture) {
return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
}
@@ -6942,22 +7036,22 @@
}
var lt = _moment__default.defineLocale('lt', {
- months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
+ months : lt__monthsCaseReplace,
monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
weekdays : relativeWeekDay,
weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY [m.] MMMM D [d.]',
- LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',
- LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',
+ LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
l : 'YYYY-MM-DD',
ll : 'YYYY [m.] MMMM D [d.]',
- lll : 'YYYY [m.] MMMM D [d.], LT [val.]',
- llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'
+ lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
},
calendar : {
sameDay : '[Šiandien] LT',
@@ -7040,11 +7134,11 @@
weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY.',
LL : 'YYYY. [gada] D. MMMM',
- LLL : 'YYYY. [gada] D. MMMM, LT',
- LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'
+ LLL : 'YYYY. [gada] D. MMMM, HH:mm',
+ LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
},
calendar : {
sameDay : '[Šodien pulksten] LT',
@@ -7112,11 +7206,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
@@ -7187,11 +7281,11 @@
weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Денес во] LT',
@@ -7269,8 +7363,8 @@
LTS : 'A h:mm:ss -നു',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm -നു',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
},
calendar : {
sameDay : '[ഇന്ന്] LT',
@@ -7354,8 +7448,8 @@
LTS : 'A h:mm:ss वाजता',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm वाजता',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
},
calendar : {
sameDay : '[आज] LT',
@@ -7436,11 +7530,82 @@
weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
+ L : 'DD/MM/YYYY',
+ LL : 'D MMMM YYYY',
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
+ },
+ meridiemParse: /pagi|tengahari|petang|malam/,
+ meridiemHour: function (hour, meridiem) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ if (meridiem === 'pagi') {
+ return hour;
+ } else if (meridiem === 'tengahari') {
+ return hour >= 11 ? hour : hour + 12;
+ } else if (meridiem === 'petang' || meridiem === 'malam') {
+ return hour + 12;
+ }
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'tengahari';
+ } else if (hours < 19) {
+ return 'petang';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Esok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kelmarin pukul] LT',
+ lastWeek : 'dddd [lepas pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'dalam %s',
+ past : '%s yang lepas',
+ s : 'beberapa saat',
+ m : 'seminit',
+ mm : '%d minit',
+ h : 'sejam',
+ hh : '%d jam',
+ d : 'sehari',
+ dd : '%d hari',
+ M : 'sebulan',
+ MM : '%d bulan',
+ y : 'setahun',
+ yy : '%d tahun'
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+ });
+
+ //! moment.js locale configuration
+ //! locale : Bahasa Malaysia (ms-MY)
+ //! author : Weldan Jamili : https://github.com/weldan
+
+ var locale_ms = _moment__default.defineLocale('ms', {
+ months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
+ monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
+ weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
+ weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
+ weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|tengahari|petang|malam/,
meridiemHour: function (hour, meridiem) {
@@ -7535,8 +7700,8 @@
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ယနေ.] LT [မှာ]',
@@ -7590,11 +7755,11 @@
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'H.mm',
- LTS : 'LT.ss',
+ LTS : 'H.mm.ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H.mm',
+ LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'
},
calendar : {
sameDay: '[i dag kl.] LT',
@@ -7667,8 +7832,8 @@
LTS : 'Aको h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, Aको h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
},
preparse: function (string) {
return string.replace(/[१२३४५६७८९०]/g, function (match) {
@@ -7760,11 +7925,11 @@
weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[vandaag om] LT',
@@ -7811,11 +7976,11 @@
weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[I dag klokka] LT',
@@ -7894,11 +8059,11 @@
weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Dziś o] LT',
@@ -7954,11 +8119,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY [às] LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'
+ LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -7975,7 +8140,7 @@
relativeTime : {
future : 'em %s',
past : '%s atrás',
- s : 'segundos',
+ s : 'poucos segundos',
m : 'um minuto',
mm : '%d minutos',
h : 'uma hora',
@@ -8003,11 +8168,11 @@
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -8072,7 +8237,7 @@
weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
@@ -8171,11 +8336,11 @@
monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сегодня в] LT',
@@ -8275,8 +8440,8 @@
LTS : 'a h:mm:ss',
L : 'YYYY/MM/DD',
LL : 'YYYY MMMM D',
- LLL : 'YYYY MMMM D, LT',
- LLLL : 'YYYY MMMM D [වැනි] dddd, LTS'
+ LLL : 'YYYY MMMM D, a h:mm',
+ LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
},
calendar : {
sameDay : '[අද] LT[ට]',
@@ -8393,11 +8558,11 @@
weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes o] LT',
@@ -8544,11 +8709,11 @@
weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danes ob] LT',
@@ -8631,11 +8796,11 @@
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Sot në] LT',
@@ -8703,11 +8868,11 @@
weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[данас у] LT',
@@ -8800,11 +8965,11 @@
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
@@ -8874,11 +9039,11 @@
weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Idag] LT',
@@ -8930,11 +9095,11 @@
weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, HH:mm',
+ LLLL : 'dddd, D MMMM YYYY, HH:mm'
},
calendar : {
sameDay : '[இன்று] LT',
@@ -9014,11 +9179,11 @@
weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
longDateFormat : {
LT : 'H นาฬิกา m นาที',
- LTS : 'LT s วินาที',
+ LTS : 'H นาฬิกา m นาที s วินาที',
L : 'YYYY/MM/DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY เวลา LT',
- LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'
+ LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
+ LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
},
meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
isPM: function (input) {
@@ -9068,11 +9233,11 @@
weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'MM/D/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM DD, YYYY LT'
+ LLL : 'MMMM D, YYYY HH:mm',
+ LLLL : 'dddd, MMMM DD, YYYY HH:mm'
},
calendar : {
sameDay: '[Ngayon sa] LT',
@@ -9141,11 +9306,11 @@
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
@@ -9187,6 +9352,80 @@
});
//! moment.js locale configuration
+ //! locale : talossan (tzl)
+ //! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
+
+
+ var tzl = _moment__default.defineLocale('tzl', {
+ months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
+ monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
+ weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
+ weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
+ weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'LT.ss',
+ L : 'DD.MM.YYYY',
+ LL : 'D. MMMM [dallas] YYYY',
+ LLL : 'D. MMMM [dallas] YYYY LT',
+ LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'd\'o' : 'D\'O';
+ } else {
+ return isLower ? 'd\'a' : 'D\'A';
+ }
+ },
+ calendar : {
+ sameDay : '[oxhi à] LT',
+ nextDay : '[demà à] LT',
+ nextWeek : 'dddd [à] LT',
+ lastDay : '[ieiri à] LT',
+ lastWeek : '[sür el] dddd [lasteu à] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'osprei %s',
+ past : 'ja%s',
+ s : tzl__processRelativeTime,
+ m : tzl__processRelativeTime,
+ mm : tzl__processRelativeTime,
+ h : tzl__processRelativeTime,
+ hh : tzl__processRelativeTime,
+ d : tzl__processRelativeTime,
+ dd : tzl__processRelativeTime,
+ M : tzl__processRelativeTime,
+ MM : tzl__processRelativeTime,
+ y : tzl__processRelativeTime,
+ yy : tzl__processRelativeTime
+ },
+ ordinalParse: /\d{1,2}\./,
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+
+ function tzl__processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 's': ['viensas secunds', '\'iensas secunds'],
+ 'm': ['\'n míut', '\'iens míut'],
+ 'mm': [number + ' míuts', ' ' + number + ' míuts'],
+ 'h': ['\'n þora', '\'iensa þora'],
+ 'hh': [number + ' þoras', ' ' + number + ' þoras'],
+ 'd': ['\'n ziua', '\'iensa ziua'],
+ 'dd': [number + ' ziuas', ' ' + number + ' ziuas'],
+ 'M': ['\'n mes', '\'iens mes'],
+ 'MM': [number + ' mesen', ' ' + number + ' mesen'],
+ 'y': ['\'n ar', '\'iens ar'],
+ 'yy': [number + ' ars', ' ' + number + ' ars']
+ };
+ return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());
+ }
+
+ //! moment.js locale configuration
//! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
//! author : Abdel Said : https://github.com/abdelsaid
@@ -9198,11 +9437,11 @@
weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[asdkh g] LT',
@@ -9245,11 +9484,11 @@
weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
@@ -9344,11 +9583,11 @@
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY р.',
- LLL : 'D MMMM YYYY р., LT',
- LLLL : 'dddd, D MMMM YYYY р., LT'
+ LLL : 'D MMMM YYYY р., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY р., HH:mm'
},
calendar : {
sameDay: processHoursFunction('[Сьогодні '),
@@ -9434,11 +9673,11 @@
weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'D MMMM YYYY, dddd LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'D MMMM YYYY, dddd HH:mm'
},
calendar : {
sameDay : '[Бугун соат] LT [да]',
@@ -9481,15 +9720,15 @@
weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM [năm] YYYY',
- LLL : 'D MMMM [năm] YYYY LT',
- LLLL : 'dddd, D MMMM [năm] YYYY LT',
+ LLL : 'D MMMM [năm] YYYY HH:mm',
+ LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
l : 'DD/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay: '[Hôm nay lúc] LT',
@@ -9540,12 +9779,12 @@
LTS : 'Ah点m分s秒',
L : 'YYYY-MM-DD',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah点mm分',
+ LLLL : 'YYYY年MMMD日ddddAh点mm分',
l : 'YYYY-MM-DD',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah点mm分',
+ llll : 'YYYY年MMMD日ddddAh点mm分'
},
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
meridiemHour: function (hour, meridiem) {
@@ -9655,12 +9894,12 @@
LTS : 'Ah點m分s秒',
L : 'YYYY年MMMD日',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah點mm分',
+ LLLL : 'YYYY年MMMD日ddddAh點mm分',
l : 'YYYY年MMMD日',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah點mm分',
+ llll : 'YYYY年MMMD日ddddAh點mm分'
},
meridiemParse: /早上|上午|中午|下午|晚上/,
meridiemHour : function (hour, meridiem) {
@@ -9731,6 +9970,7 @@
});
var moment_with_locales = _moment__default;
+ moment_with_locales.locale('en');
return moment_with_locales;
diff --git a/bower_components/moment/min/tests.js b/bower_components/moment/min/tests.js
index 0d7bb95..596227c 100644
--- a/bower_components/moment/min/tests.js
+++ b/bower_components/moment/min/tests.js
@@ -3246,7 +3246,7 @@
assert.equal(moment(a).calendar(), 'আজ রাত ২:০০ সময়', 'today at the same time');
assert.equal(moment(a).add({m: 25}).calendar(), 'আজ রাত ২:২৫ সময়', 'Now plus 25 min');
- assert.equal(moment(a).add({h: 3}).calendar(), 'আজ শকাল ৫:০০ সময়', 'Now plus 3 hour');
+ assert.equal(moment(a).add({h: 3}).calendar(), 'আজ সকাল ৫:০০ সময়', 'Now plus 3 hour');
assert.equal(moment(a).add({d: 1}).calendar(), 'আগামীকাল রাত ২:০০ সময়', 'tomorrow at the same time');
assert.equal(moment(a).subtract({h: 1}).calendar(), 'আজ রাত ১:০০ সময়', 'Now minus 1 hour');
assert.equal(moment(a).subtract({d: 1}).calendar(), 'গতকাল রাত ২:০০ সময়', 'yesterday at the same time');
@@ -3293,14 +3293,14 @@
test('meridiem', function (assert) {
assert.equal(moment([2011, 2, 23, 2, 30]).format('a'), 'রাত', 'before dawn');
- assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'শকাল', 'morning');
+ assert.equal(moment([2011, 2, 23, 9, 30]).format('a'), 'সকাল', 'morning');
assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');
assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকেল', 'evening');
assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকেল', 'late evening');
assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');
assert.equal(moment([2011, 2, 23, 2, 30]).format('A'), 'রাত', 'before dawn');
- assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'শকাল', 'morning');
+ assert.equal(moment([2011, 2, 23, 9, 30]).format('A'), 'সকাল', 'morning');
assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');
assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকেল', 'evening');
assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকেল', 'late evening');
@@ -11379,20 +11379,20 @@
test('format', function (assert) {
var a = [
- ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14 2010, 3:25:50 pm'],
+ ['dddd, MMMM Do YYYY, h:mm:ss a', 'dimanche, février 14e 2010, 3:25:50 pm'],
['ddd, hA', 'dim., 3PM'],
- ['M Mo MM MMMM MMM', '2 2 02 février févr.'],
+ ['M Mo MM MMMM MMM', '2 2e 02 février févr.'],
['YYYY YY', '2010 10'],
- ['D Do DD', '14 14 14'],
- ['d do dddd ddd dd', '0 0 dimanche dim. Di'],
- ['DDD DDDo DDDD', '45 45 045'],
- ['w wo ww', '8 8 08'],
+ ['D Do DD', '14 14e 14'],
+ ['d do dddd ddd dd', '0 0e dimanche dim. Di'],
+ ['DDD DDDo DDDD', '45 45e 045'],
+ ['w wo ww', '8 8e 08'],
['h hh', '3 03'],
['H HH', '15 15'],
['m mm', '25 25'],
['s ss', '50 50'],
['a A', 'pm PM'],
- ['[the] DDDo [day of the year]', 'the 45 day of the year'],
+ ['[the] DDDo [day of the year]', 'the 45e day of the year'],
['LTS', '15:25:50'],
['L', '2010-02-14'],
['LL', '14 février 2010'],
@@ -11413,39 +11413,39 @@
test('format ordinal', function (assert) {
assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');
- assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
- assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
- assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
- assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
- assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
- assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
- assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
- assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
- assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');
+ assert.equal(moment([2011, 0, 2]).format('DDDo'), '2e', '2e');
+ assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');
+ assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');
+ assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');
+ assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');
+ assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');
+ assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');
+ assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');
+ assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');
- assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
- assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
- assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
- assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
- assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
- assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
- assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
- assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
- assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
- assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');
+ assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');
+ assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');
+ assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');
+ assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');
+ assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');
+ assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');
+ assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');
+ assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');
+ assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');
+ assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');
- assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
- assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
- assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
- assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
- assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
- assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
- assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
- assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
- assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
- assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');
+ assert.equal(moment([2011, 0, 21]).format('DDDo'), '21e', '21e');
+ assert.equal(moment([2011, 0, 22]).format('DDDo'), '22e', '22e');
+ assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');
+ assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');
+ assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');
+ assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');
+ assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');
+ assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');
+ assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');
+ assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');
- assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
+ assert.equal(moment([2011, 0, 31]).format('DDDo'), '31e', '31e');
});
test('format month', function (assert) {
@@ -11624,9 +11624,9 @@
test('weeks year starting sunday format', function (assert) {
assert.equal(moment([2012, 0, 1]).format('w ww wo'), '1 01 1er', 'Jan 1 2012 should be week 1');
assert.equal(moment([2012, 0, 7]).format('w ww wo'), '1 01 1er', 'Jan 7 2012 should be week 1');
- assert.equal(moment([2012, 0, 8]).format('w ww wo'), '2 02 2', 'Jan 8 2012 should be week 2');
- assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');
- assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');
+ assert.equal(moment([2012, 0, 8]).format('w ww wo'), '2 02 2e', 'Jan 8 2012 should be week 2');
+ assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2e', 'Jan 14 2012 should be week 2');
+ assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3e', 'Jan 15 2012 should be week 3');
});
test('lenient ordinal parsing', function (assert) {
@@ -13923,11 +13923,11 @@
['LTS', '15:25:50'],
['L', '2010.02.14.'],
['LL', '2010. február 14.'],
- ['LLL', '2010. február 14., 15:25'],
+ ['LLL', '2010. február 14. 15:25'],
['LLLL', '2010. február 14., vasárnap 15:25'],
['l', '2010.2.14.'],
['ll', '2010. feb 14.'],
- ['lll', '2010. feb 14., 15:25'],
+ ['lll', '2010. feb 14. 15:25'],
['llll', '2010. feb 14., vas 15:25']
],
b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
@@ -17751,7 +17751,7 @@
localeModule('lt');
test('parse', function (assert) {
- var tests = 'sausio sau_vasario vas_kovo kov_balandžio bal_gegužės geg_birželio bir_liepos lie_rugpjūčio rgp_rugsėjo rgs_spalio spa_lapkričio lap_gruodžio grd'.split('_'), i;
+ var tests = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;
function equalTest(input, mmm, i) {
assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));
}
@@ -17772,7 +17772,7 @@
var a = [
['dddd, Do MMMM YYYY, h:mm:ss a', 'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],
['ddd, hA', 'Sek, 3PM'],
- ['M Mo MM MMMM MMM', '2 2-oji 02 vasario vas'],
+ ['M Mo MM MMMM MMM', '2 2-oji 02 vasaris vas'],
['YYYY YY', '2010 10'],
['D Do DD', '14 14-oji 14'],
['d do dddd ddd dd', '0 0-oji sekmadienis Sek S'],
@@ -17786,13 +17786,13 @@
['DDDo [metų diena]', '45-oji metų diena'],
['LTS', '15:25:50'],
['L', '2010-02-14'],
- ['LL', '2010 m. vasario 14 d.'],
- ['LLL', '2010 m. vasario 14 d., 15:25 val.'],
- ['LLLL', '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],
+ ['LL', '2010 m. vasaris 14 d.'],
+ ['LLL', '2010 m. vasaris 14 d., 15:25 val.'],
+ ['LLLL', '2010 m. vasaris 14 d., sekmadienis, 15:25 val.'],
['l', '2010-02-14'],
- ['ll', '2010 m. vasario 14 d.'],
- ['lll', '2010 m. vasario 14 d., 15:25 val.'],
- ['llll', '2010 m. vasario 14 d., Sek, 15:25 val.']
+ ['ll', '2010 m. vasaris 14 d.'],
+ ['lll', '2010 m. vasaris 14 d., 15:25 val.'],
+ ['llll', '2010 m. vasaris 14 d., Sek, 15:25 val.']
],
b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
i;
@@ -17839,7 +17839,7 @@
});
test('format month', function (assert) {
- var expected = 'sausio sau_vasario vas_kovo kov_balandžio bal_gegužės geg_birželio bir_liepos lie_rugpjūčio rgp_rugsėjo rgs_spalio spa_lapkričio lap_gruodžio grd'.split('_'), i;
+ var expected = 'sausis sau_vasaris vas_kovas kov_balandis bal_gegužė geg_birželis bir_liepa lie_rugpjūtis rgp_rugsėjis rgs_spalis spa_lapkritis lap_gruodis grd'.split('_'), i;
for (i = 0; i < expected.length; i++) {
assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);
}
@@ -20389,6 +20389,382 @@
});
}
+ localeModule('ms');
+
+ test('parse', function (assert) {
+ var i,
+ tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');
+
+ function equalTest(input, mmm, i) {
+ assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));
+ }
+
+ for (i = 0; i < 12; i++) {
+ tests[i] = tests[i].split(' ');
+ equalTest(tests[i][0], 'MMM', i);
+ equalTest(tests[i][1], 'MMM', i);
+ equalTest(tests[i][0], 'MMMM', i);
+ equalTest(tests[i][1], 'MMMM', i);
+ equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
+ equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
+ equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
+ equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
+ }
+ });
+
+ test('format', function (assert) {
+ var a = [
+ ['dddd, MMMM Do YYYY, h:mm:ss a', 'Ahad, Februari 14 2010, 3:25:50 petang'],
+ ['ddd, hA', 'Ahd, 3petang'],
+ ['M Mo MM MMMM MMM', '2 2 02 Februari Feb'],
+ ['YYYY YY', '2010 10'],
+ ['D Do DD', '14 14 14'],
+ ['d do dddd ddd dd', '0 0 Ahad Ahd Ah'],
+ ['DDD DDDo DDDD', '45 45 045'],
+ ['w wo ww', '7 7 07'],
+ ['h hh', '3 03'],
+ ['H HH', '15 15'],
+ ['m mm', '25 25'],
+ ['s ss', '50 50'],
+ ['a A', 'petang petang'],
+ ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],
+ ['LTS', '15.25.50'],
+ ['L', '14/02/2010'],
+ ['LL', '14 Februari 2010'],
+ ['LLL', '14 Februari 2010 pukul 15.25'],
+ ['LLLL', 'Ahad, 14 Februari 2010 pukul 15.25'],
+ ['l', '14/2/2010'],
+ ['ll', '14 Feb 2010'],
+ ['lll', '14 Feb 2010 pukul 15.25'],
+ ['llll', 'Ahd, 14 Feb 2010 pukul 15.25']
+ ],
+ b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
+ i;
+
+ for (i = 0; i < a.length; i++) {
+ assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
+ }
+ });
+
+ test('format ordinal', function (assert) {
+ assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');
+ assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');
+ assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');
+ assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');
+ assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');
+ assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');
+ assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');
+ assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');
+ assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');
+ assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');
+
+ assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');
+ assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');
+ assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');
+ assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');
+ assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');
+ assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');
+ assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');
+ assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');
+ assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');
+ assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');
+
+ assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');
+ assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');
+ assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');
+ assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');
+ assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');
+ assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');
+ assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');
+ assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');
+ assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');
+ assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');
+
+ assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');
+ });
+
+ test('format month', function (assert) {
+ var i,
+ expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');
+
+ for (i = 0; i < expected.length; i++) {
+ assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);
+ }
+ });
+
+ test('format week', function (assert) {
+ var i,
+ expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');
+
+ for (i = 0; i < expected.length; i++) {
+ assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);
+ }
+ });
+
+ test('from', function (assert) {
+ var start = moment([2007, 1, 28]);
+
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'beberapa saat', '44 saat = beberapa saat');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'seminit', '45 saat = seminit');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'seminit', '89 saat = seminit');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 minit', '90 saat = 2 minit');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 minit', '44 minit = 44 minit');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'sejam', '45 minit = sejam');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'sejam', '89 minit = sejam');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 jam', '90 minit = 2 jam');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 jam', '5 jam = 5 jam');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 jam', '21 jam = 21 jam');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'sehari', '22 jam = sehari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'sehari', '35 jam = sehari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 hari', '36 jam = 2 hari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'sehari', '1 hari = sehari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 hari', '5 hari = 5 hari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 hari', '25 hari = 25 hari');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'sebulan', '26 hari = sebulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'sebulan', '30 hari = sebulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'sebulan', '45 hari = sebulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 bulan', '46 hari = 2 bulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 bulan', '75 hari = 2 bulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 bulan', '76 hari = 3 bulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'sebulan', '1 bulan = sebulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 bulan', '5 bulan = 5 bulan');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun', '345 hari = setahun');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun', '548 hari = 2 tahun');
+ assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'setahun', '1 tahun = setahun');
+ assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 tahun', '5 tahun = 5 tahun');
+ });
+
+ test('suffix', function (assert) {
+ assert.equal(moment(30000).from(0), 'dalam beberapa saat', 'prefix');
+ assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');
+ });
+
+ test('now from now', function (assert) {
+ assert.equal(moment().fromNow(), 'beberapa saat yang lepas', 'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');
+ });
+
+ test('fromNow', function (assert) {
+ assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');
+ assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');
+ });
+
+ test('calendar day', function (assert) {
+ var a = moment().hours(2).minutes(0).seconds(0);
+
+ assert.equal(moment(a).calendar(), 'Hari ini pukul 02.00', 'hari ini pada waktu yang sama');
+ assert.equal(moment(a).add({m: 25}).calendar(), 'Hari ini pukul 02.25', 'Sekarang tambah 25 minit');
+ assert.equal(moment(a).add({h: 1}).calendar(), 'Hari ini pukul 03.00', 'Sekarang tambah 1 jam');
+ assert.equal(moment(a).add({d: 1}).calendar(), 'Esok pukul 02.00', 'esok pada waktu yang sama');
+ assert.equal(moment(a).subtract({h: 1}).calendar(), 'Hari ini pukul 01.00', 'Sekarang tolak 1 jam');
+ assert.equal(moment(a).subtract({d: 1}).calendar(), 'Kelmarin pukul 02.00', 'kelmarin pada waktu yang sama');
+ });
+
+ test('calendar next week', function (assert) {
+ var i, m;
+ for (i = 2; i < 7; i++) {
+ m = moment().add({d: i});
+ assert.equal(m.calendar(), m.format('dddd [pukul] LT'), 'Hari ini + ' + i + ' hari waktu sekarang');
+ m.hours(0).minutes(0).seconds(0).milliseconds(0);
+ assert.equal(m.calendar(), m.format('dddd [pukul] LT'), 'Hari ini + ' + i + ' hari permulaan hari');
+ m.hours(23).minutes(59).seconds(59).milliseconds(999);
+ assert.equal(m.calendar(), m.format('dddd [pukul] LT'), 'Hari ini + ' + i + ' hari tamat hari');
+ }
+ });
+
+ test('calendar last week', function (assert) {
+ var i, m;
+ for (i = 2; i < 7; i++) {
+ m = moment().subtract({d: i});
+ assert.equal(m.calendar(), m.format('dddd [lepas] [pukul] LT'), 'Hari ini - ' + i + ' hari waktu sekarang');
+ m.hours(0).minutes(0).seconds(0).milliseconds(0);
+ assert.equal(m.calendar(), m.format('dddd [lepas] [pukul] LT'), 'Hari ini - ' + i + ' hari permulaan hari');
+ m.hours(23).minutes(59).seconds(59).milliseconds(999);
+ assert.equal(m.calendar(), m.format('dddd [lepas] [pukul] LT'), 'Hari ini - ' + i + ' hari tamat hari');
+ }
+ });
+
+ test('calendar all else', function (assert) {
+ var weeksAgo = moment().subtract({w: 1}),
+ weeksFromNow = moment().add({w: 1});
+
+ assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 minggu lepas');
+ assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'dalam 1 minggu');
+
+ weeksAgo = moment().subtract({w: 2});
+ weeksFromNow = moment().add({w: 2});
+
+ assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 minggu lepas');
+ assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'dalam 2 minggu');
+ });
+
+ test('weeks year starting sunday', function (assert) {
+ assert.equal(moment([2012, 0, 1]).week(), 1, 'Jan 1 2012 sepatutnya minggu 1');
+ assert.equal(moment([2012, 0, 7]).week(), 2, 'Jan 7 2012 sepatutnya minggu 2');
+ assert.equal(moment([2012, 0, 8]).week(), 2, 'Jan 8 2012 sepatutnya minggu 2');
+ assert.equal(moment([2012, 0, 14]).week(), 3, 'Jan 14 2012 sepatutnya minggu 3');
+ assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 sepatutnya minggu 3');
+ });
+
+ test('weeks year starting monday', function (assert) {
+ assert.equal(moment([2006, 11, 31]).week(), 53, 'Dec 31 2006 sepatutnya minggu 53');
+ assert.equal(moment([2007, 0, 1]).week(), 1, 'Jan 1 2007 sepatutnya minggu 1');
+ assert.equal(moment([2007, 0, 6]).week(), 1, 'Jan 6 2007 sepatutnya minggu 1');
+ assert.equal(moment([2007, 0, 7]).week(), 1, 'Jan 7 2007 sepatutnya minggu 1');
+ assert.equal(moment([2007, 0, 13]).week(), 2, 'Jan 13 2007 sepatutnya minggu 2');
+ assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting tuesday', function (assert) {
+ assert.equal(moment([2007, 11, 30]).week(), 52, 'Dec 30 2007 sepatutnya minggu 52');
+ assert.equal(moment([2008, 0, 1]).week(), 1, 'Jan 1 2008 sepatutnya minggu 1');
+ assert.equal(moment([2008, 0, 5]).week(), 1, 'Jan 5 2008 sepatutnya minggu 1');
+ assert.equal(moment([2008, 0, 6]).week(), 1, 'Jan 6 2008 sepatutnya minggu 1');
+ assert.equal(moment([2008, 0, 12]).week(), 2, 'Jan 12 2008 sepatutnya minggu 2');
+ assert.equal(moment([2008, 0, 13]).week(), 2, 'Jan 13 2008 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting wednesday', function (assert) {
+ assert.equal(moment([2002, 11, 29]).week(), 52, 'Dec 29 2002 sepatutnya minggu 52');
+ assert.equal(moment([2003, 0, 1]).week(), 1, 'Jan 1 2003 sepatutnya minggu 1');
+ assert.equal(moment([2003, 0, 4]).week(), 1, 'Jan 4 2003 sepatutnya minggu 1');
+ assert.equal(moment([2003, 0, 5]).week(), 1, 'Jan 5 2003 sepatutnya minggu 1');
+ assert.equal(moment([2003, 0, 11]).week(), 2, 'Jan 11 2003 sepatutnya minggu 2');
+ assert.equal(moment([2003, 0, 12]).week(), 2, 'Jan 12 2003 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting thursday', function (assert) {
+ assert.equal(moment([2008, 11, 28]).week(), 52, 'Dec 28 2008 sepatutnya minggu 52');
+ assert.equal(moment([2009, 0, 1]).week(), 1, 'Jan 1 2009 sepatutnya minggu 1');
+ assert.equal(moment([2009, 0, 3]).week(), 1, 'Jan 3 2009 sepatutnya minggu 1');
+ assert.equal(moment([2009, 0, 4]).week(), 1, 'Jan 4 2009 sepatutnya minggu 1');
+ assert.equal(moment([2009, 0, 10]).week(), 2, 'Jan 10 2009 sepatutnya minggu 2');
+ assert.equal(moment([2009, 0, 11]).week(), 2, 'Jan 11 2009 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting friday', function (assert) {
+ assert.equal(moment([2009, 11, 27]).week(), 52, 'Dec 27 2009 sepatutnya minggu 52');
+ assert.equal(moment([2010, 0, 1]).week(), 1, 'Jan 1 2010 sepatutnya minggu 1');
+ assert.equal(moment([2010, 0, 2]).week(), 1, 'Jan 2 2010 sepatutnya minggu 1');
+ assert.equal(moment([2010, 0, 3]).week(), 1, 'Jan 3 2010 sepatutnya minggu 1');
+ assert.equal(moment([2010, 0, 9]).week(), 2, 'Jan 9 2010 sepatutnya minggu 2');
+ assert.equal(moment([2010, 0, 10]).week(), 2, 'Jan 10 2010 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting saturday', function (assert) {
+ assert.equal(moment([2010, 11, 26]).week(), 52, 'Dec 26 2010 sepatutnya minggu 52');
+ assert.equal(moment([2011, 0, 1]).week(), 1, 'Jan 1 2011 sepatutnya minggu 1');
+ assert.equal(moment([2011, 0, 2]).week(), 1, 'Jan 2 2011 sepatutnya minggu 1');
+ assert.equal(moment([2011, 0, 8]).week(), 2, 'Jan 8 2011 sepatutnya minggu 2');
+ assert.equal(moment([2011, 0, 9]).week(), 2, 'Jan 9 2011 sepatutnya minggu 2');
+ });
+
+ test('weeks year starting sunday format', function (assert) {
+ assert.equal(moment([2012, 0, 1]).format('w ww wo'), '1 01 1', 'Jan 1 2012 sepatutnya minggu 1');
+ assert.equal(moment([2012, 0, 7]).format('w ww wo'), '2 02 2', 'Jan 7 2012 sepatutnya minggu 2');
+ assert.equal(moment([2012, 0, 8]).format('w ww wo'), '2 02 2', 'Jan 8 2012 sepatutnya minggu 2');
+ assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');
+ assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');
+ });
+
+ test('lenient ordinal parsing', function (assert) {
+ var i, ordinalStr, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
+ testMoment = moment(ordinalStr, 'YYYY MM Do');
+ assert.equal(testMoment.year(), 2014,
+ 'lenient ordinal parsing ' + i + ' year check');
+ assert.equal(testMoment.month(), 0,
+ 'lenient ordinal parsing ' + i + ' month check');
+ assert.equal(testMoment.date(), i,
+ 'lenient ordinal parsing ' + i + ' date check');
+ }
+ });
+
+ test('meridiem invariant', function (assert) {
+ var h, m, t1, t2;
+ for (h = 0; h < 24; ++h) {
+ for (m = 0; m < 60; m += 15) {
+ t1 = moment.utc([2000, 0, 1, h, m]);
+ t2 = moment(t1.format('A h:mm'), 'A h:mm');
+ assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),
+ 'meridiem at ' + t1.format('HH:mm'));
+ }
+ }
+ });
+
+ test('lenient ordinal parsing of number', function (assert) {
+ var i, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
+ assert.equal(testMoment.year(), 2014,
+ 'lenient ordinal parsing of number ' + i + ' year check');
+ assert.equal(testMoment.month(), 0,
+ 'lenient ordinal parsing of number ' + i + ' month check');
+ assert.equal(testMoment.date(), i,
+ 'lenient ordinal parsing of number ' + i + ' date check');
+ }
+ });
+
+ test('strict ordinal parsing', function (assert) {
+ var i, ordinalStr, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
+ testMoment = moment(ordinalStr, 'YYYY MM Do', true);
+ assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);
+ }
+ });
+
+}));
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :
+ typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
+ factory(global.moment)
+}(this, function (moment) { 'use strict';
+
+ /*global QUnit:false*/
+
+ var test = QUnit.test;
+
+ function module (name, lifecycle) {
+ QUnit.module(name, {
+ setup : function () {
+ moment.locale('en');
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
+ function localeModule (name, lifecycle) {
+ QUnit.module('locale:' + name, {
+ setup : function () {
+ moment.locale(name);
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ moment.locale('en');
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
localeModule('my');
test('parse', function (assert) {
@@ -22792,7 +23168,7 @@
test('from', function (assert) {
var start = moment([2007, 1, 28]);
- assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'segundos', '44 seconds = seconds');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'poucos segundos', '44 seconds = seconds');
assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'um minuto', '45 seconds = a minute');
assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'um minuto', '89 seconds = a minute');
assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 minutos', '90 seconds = 2 minutes');
@@ -22823,12 +23199,12 @@
});
test('suffix', function (assert) {
- assert.equal(moment(30000).from(0), 'em segundos', 'prefix');
- assert.equal(moment(0).from(30000), 'segundos atrás', 'suffix');
+ assert.equal(moment(30000).from(0), 'em poucos segundos', 'prefix');
+ assert.equal(moment(0).from(30000), 'poucos segundos atrás', 'suffix');
});
test('fromNow', function (assert) {
- assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');
+ assert.equal(moment().add({s: 30}).fromNow(), 'em poucos segundos', 'in seconds');
assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');
});
@@ -28340,6 +28716,365 @@
});
}
+ localeModule('tzl');
+
+ test('parse', function (assert) {
+ var tests = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;
+ function equalTest(input, mmm, i) {
+ assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));
+ }
+ for (i = 0; i < 12; i++) {
+ tests[i] = tests[i].split(' ');
+ equalTest(tests[i][0], 'MMM', i);
+ equalTest(tests[i][1], 'MMM', i);
+ equalTest(tests[i][0], 'MMMM', i);
+ equalTest(tests[i][1], 'MMMM', i);
+ equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);
+ equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);
+ equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);
+ equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);
+ }
+ });
+
+ test('format', function (assert) {
+ var a = [
+ ['dddd, MMMM Do YYYY, h.mm.ss a', 'Súladi, Fevraglh 14. 2010, 3.25.50 d\'o'],
+ ['ddd, hA', 'Súl, 3D\'O'],
+ ['M Mo MM MMMM MMM', '2 2. 02 Fevraglh Fev'],
+ ['YYYY YY', '2010 10'],
+ ['D Do DD', '14 14. 14'],
+ ['d do dddd ddd dd', '0 0. Súladi Súl Sú'],
+ ['DDD DDDo DDDD', '45 45. 045'],
+ ['w wo ww', '6 6. 06'],
+ ['h hh', '3 03'],
+ ['H HH', '15 15'],
+ ['m mm', '25 25'],
+ ['s ss', '50 50'],
+ ['a A', 'd\'o D\'O'],
+ ['[the] DDDo [day of the year]', 'the 45. day of the year'],
+ ['LTS', '15.25.50'],
+ ['L', '14.02.2010'],
+ ['LL', '14. Fevraglh dallas 2010'],
+ ['LLL', '14. Fevraglh dallas 2010 15.25'],
+ ['LLLL', 'Súladi, li 14. Fevraglh dallas 2010 15.25'],
+ ['l', '14.2.2010'],
+ ['ll', '14. Fev dallas 2010'],
+ ['lll', '14. Fev dallas 2010 15.25'],
+ ['llll', 'Súl, li 14. Fev dallas 2010 15.25']
+ ],
+ b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),
+ i;
+ for (i = 0; i < a.length; i++) {
+ assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);
+ }
+ });
+
+ test('format ordinal', function (assert) {
+ assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');
+ assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');
+ assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');
+ assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');
+ assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');
+ assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');
+ assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');
+ assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');
+ assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');
+ assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');
+
+ assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');
+ assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');
+ assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');
+ assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');
+ assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');
+ assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');
+ assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');
+ assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');
+ assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');
+ assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');
+
+ assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');
+ assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');
+ assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');
+ assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');
+ assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');
+ assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');
+ assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');
+ assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');
+ assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');
+ assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');
+
+ assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');
+ });
+
+ test('format month', function (assert) {
+ var expected = 'Januar Jan_Fevraglh Fev_Març Mar_Avrïu Avr_Mai Mai_Gün Gün_Julia Jul_Guscht Gus_Setemvar Set_Listopäts Lis_Noemvar Noe_Zecemvar Zec'.split('_'), i;
+ for (i = 0; i < expected.length; i++) {
+ assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);
+ }
+ });
+
+ test('format week', function (assert) {
+ var expected = 'Súladi Súl Sú_Lúneçi Lún Lú_Maitzi Mai Ma_Márcuri Már Má_Xhúadi Xhú Xh_Viénerçi Vié Vi_Sáturi Sát Sá'.split('_'), i;
+ for (i = 0; i < expected.length; i++) {
+ assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);
+ }
+ });
+
+ test('from', function (assert) {
+ var start = moment([2007, 1, 28]);
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'viensas secunds', '44 seconds = a few seconds');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), '\'n míut', '45 seconds = a minute');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), '\'n míut', '89 seconds = a minute');
+ assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 míuts', '90 seconds = 2 minutes');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 míuts', '44 minutes = 44 minutes');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), '\'n þora', '45 minutes = an hour');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), '\'n þora', '89 minutes = an hour');
+ assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 þoras', '90 minutes = 2 hours');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 þoras', '5 hours = 5 hours');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 þoras', '21 hours = 21 hours');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), '\'n ziua', '22 hours = a day');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), '\'n ziua', '35 hours = a day');
+ assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ziuas', '36 hours = 2 days');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), '\'n ziua', '1 day = a day');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ziuas', '5 days = 5 days');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ziuas', '25 days = 25 days');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), '\'n mes', '26 days = a month');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), '\'n mes', '30 days = a month');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), '\'n mes', '43 days = a month');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 mesen', '46 days = 2 months');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 mesen', '75 days = 2 months');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 mesen', '76 days = 3 months');
+ assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), '\'n mes', '1 month = a month');
+ assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 mesen', '5 months = 5 months');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\'n ar', '345 days = a year');
+ assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ars', '548 days = 2 years');
+ assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), '\'n ar', '1 year = a year');
+ assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ars', '5 years = 5 years');
+ });
+
+ test('suffix', function (assert) {
+ assert.equal(moment(30000).from(0), 'osprei viensas secunds', 'prefix');
+ assert.equal(moment(0).from(30000), 'ja\'iensas secunds', 'suffix');
+ });
+
+ test('now from now', function (assert) {
+ assert.equal(moment().fromNow(), 'ja\'iensas secunds', 'now from now should display as in the past');
+ });
+
+ test('fromNow', function (assert) {
+ assert.equal(moment().add({s: 30}).fromNow(), 'osprei viensas secunds', 'in a few seconds');
+ assert.equal(moment().add({d: 5}).fromNow(), 'osprei 5 ziuas', 'in 5 days');
+ });
+
+ test('calendar day', function (assert) {
+ var a = moment().hours(2).minutes(0).seconds(0);
+
+ assert.equal(moment(a).calendar(), 'oxhi à 02.00', 'today at the same time');
+ assert.equal(moment(a).add({m: 25}).calendar(), 'oxhi à 02.25', 'Now plus 25 min');
+ assert.equal(moment(a).add({h: 1}).calendar(), 'oxhi à 03.00', 'Now plus 1 hour');
+ assert.equal(moment(a).add({d: 1}).calendar(), 'demà à 02.00', 'tomorrow at the same time');
+ assert.equal(moment(a).subtract({h: 1}).calendar(), 'oxhi à 01.00', 'Now minus 1 hour');
+ assert.equal(moment(a).subtract({d: 1}).calendar(), 'ieiri à 02.00', 'yesterday at the same time');
+ });
+
+ test('calendar next week', function (assert) {
+ var i, m;
+ for (i = 2; i < 7; i++) {
+ m = moment().add({d: i});
+ assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days current time');
+ m.hours(0).minutes(0).seconds(0).milliseconds(0);
+ assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days beginning of day');
+ m.hours(23).minutes(59).seconds(59).milliseconds(999);
+ assert.equal(m.calendar(), m.format('dddd [à] LT'), 'Today + ' + i + ' days end of day');
+ }
+ });
+
+ test('calendar last week', function (assert) {
+ var i, m;
+
+ for (i = 2; i < 7; i++) {
+ m = moment().subtract({d: i});
+ assert.equal(m.calendar(), m.format('[sür el] dddd [lasteu à] LT'), 'Today - ' + i + ' days current time');
+ m.hours(0).minutes(0).seconds(0).milliseconds(0);
+ assert.equal(m.calendar(), m.format('[sür el] dddd [lasteu à] LT'), 'Today - ' + i + ' days beginning of day');
+ m.hours(23).minutes(59).seconds(59).milliseconds(999);
+ assert.equal(m.calendar(), m.format('[sür el] dddd [lasteu à] LT'), 'Today - ' + i + ' days end of day');
+ }
+ });
+
+ test('calendar all else', function (assert) {
+ var weeksAgo = moment().subtract({w: 1}),
+ weeksFromNow = moment().add({w: 1});
+
+ assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');
+ assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');
+
+ weeksAgo = moment().subtract({w: 2});
+ weeksFromNow = moment().add({w: 2});
+
+ assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');
+ assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');
+ });
+
+ // Monday is the first day of the week.
+ // The week that contains Jan 4th is the first week of the year.
+
+ test('weeks year starting sunday', function (assert) {
+ assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan 1 2012 should be week 52');
+ assert.equal(moment([2012, 0, 2]).week(), 1, 'Jan 2 2012 should be week 1');
+ assert.equal(moment([2012, 0, 8]).week(), 1, 'Jan 8 2012 should be week 1');
+ assert.equal(moment([2012, 0, 9]).week(), 2, 'Jan 9 2012 should be week 2');
+ assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');
+ });
+
+ test('weeks year starting monday', function (assert) {
+ assert.equal(moment([2007, 0, 1]).week(), 1, 'Jan 1 2007 should be week 1');
+ assert.equal(moment([2007, 0, 7]).week(), 1, 'Jan 7 2007 should be week 1');
+ assert.equal(moment([2007, 0, 8]).week(), 2, 'Jan 8 2007 should be week 2');
+ assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');
+ assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');
+ });
+
+ test('weeks year starting tuesday', function (assert) {
+ assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');
+ assert.equal(moment([2008, 0, 1]).week(), 1, 'Jan 1 2008 should be week 1');
+ assert.equal(moment([2008, 0, 6]).week(), 1, 'Jan 6 2008 should be week 1');
+ assert.equal(moment([2008, 0, 7]).week(), 2, 'Jan 7 2008 should be week 2');
+ assert.equal(moment([2008, 0, 13]).week(), 2, 'Jan 13 2008 should be week 2');
+ assert.equal(moment([2008, 0, 14]).week(), 3, 'Jan 14 2008 should be week 3');
+ });
+
+ test('weeks year starting wednesday', function (assert) {
+ assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');
+ assert.equal(moment([2003, 0, 1]).week(), 1, 'Jan 1 2003 should be week 1');
+ assert.equal(moment([2003, 0, 5]).week(), 1, 'Jan 5 2003 should be week 1');
+ assert.equal(moment([2003, 0, 6]).week(), 2, 'Jan 6 2003 should be week 2');
+ assert.equal(moment([2003, 0, 12]).week(), 2, 'Jan 12 2003 should be week 2');
+ assert.equal(moment([2003, 0, 13]).week(), 3, 'Jan 13 2003 should be week 3');
+ });
+
+ test('weeks year starting thursday', function (assert) {
+ assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');
+ assert.equal(moment([2009, 0, 1]).week(), 1, 'Jan 1 2009 should be week 1');
+ assert.equal(moment([2009, 0, 4]).week(), 1, 'Jan 4 2009 should be week 1');
+ assert.equal(moment([2009, 0, 5]).week(), 2, 'Jan 5 2009 should be week 2');
+ assert.equal(moment([2009, 0, 11]).week(), 2, 'Jan 11 2009 should be week 2');
+ assert.equal(moment([2009, 0, 13]).week(), 3, 'Jan 12 2009 should be week 3');
+ });
+
+ test('weeks year starting friday', function (assert) {
+ assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');
+ assert.equal(moment([2010, 0, 1]).week(), 53, 'Jan 1 2010 should be week 53');
+ assert.equal(moment([2010, 0, 3]).week(), 53, 'Jan 3 2010 should be week 53');
+ assert.equal(moment([2010, 0, 4]).week(), 1, 'Jan 4 2010 should be week 1');
+ assert.equal(moment([2010, 0, 10]).week(), 1, 'Jan 10 2010 should be week 1');
+ assert.equal(moment([2010, 0, 11]).week(), 2, 'Jan 11 2010 should be week 2');
+ });
+
+ test('weeks year starting saturday', function (assert) {
+ assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');
+ assert.equal(moment([2011, 0, 1]).week(), 52, 'Jan 1 2011 should be week 52');
+ assert.equal(moment([2011, 0, 2]).week(), 52, 'Jan 2 2011 should be week 52');
+ assert.equal(moment([2011, 0, 3]).week(), 1, 'Jan 3 2011 should be week 1');
+ assert.equal(moment([2011, 0, 9]).week(), 1, 'Jan 9 2011 should be week 1');
+ assert.equal(moment([2011, 0, 10]).week(), 2, 'Jan 10 2011 should be week 2');
+ });
+
+ test('weeks year starting sunday formatted', function (assert) {
+ assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan 1 2012 should be week 52');
+ assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan 2 2012 should be week 1');
+ assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan 8 2012 should be week 1');
+ assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan 9 2012 should be week 2');
+ assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');
+ });
+
+ test('lenient ordinal parsing', function (assert) {
+ var i, ordinalStr, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
+ testMoment = moment(ordinalStr, 'YYYY MM Do');
+ assert.equal(testMoment.year(), 2014,
+ 'lenient ordinal parsing ' + i + ' year check');
+ assert.equal(testMoment.month(), 0,
+ 'lenient ordinal parsing ' + i + ' month check');
+ assert.equal(testMoment.date(), i,
+ 'lenient ordinal parsing ' + i + ' date check');
+ }
+ });
+
+ test('lenient ordinal parsing of number', function (assert) {
+ var i, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ testMoment = moment('2014 01 ' + i, 'YYYY MM Do');
+ assert.equal(testMoment.year(), 2014,
+ 'lenient ordinal parsing of number ' + i + ' year check');
+ assert.equal(testMoment.month(), 0,
+ 'lenient ordinal parsing of number ' + i + ' month check');
+ assert.equal(testMoment.date(), i,
+ 'lenient ordinal parsing of number ' + i + ' date check');
+ }
+ });
+
+ test('strict ordinal parsing', function (assert) {
+ var i, ordinalStr, testMoment;
+ for (i = 1; i <= 31; ++i) {
+ ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');
+ testMoment = moment(ordinalStr, 'YYYY MM Do', true);
+ assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);
+ }
+ });
+
+}));
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :
+ typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
+ factory(global.moment)
+}(this, function (moment) { 'use strict';
+
+ /*global QUnit:false*/
+
+ var test = QUnit.test;
+
+ function module (name, lifecycle) {
+ QUnit.module(name, {
+ setup : function () {
+ moment.locale('en');
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
+ function localeModule (name, lifecycle) {
+ QUnit.module('locale:' + name, {
+ setup : function () {
+ moment.locale(name);
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ moment.locale('en');
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
localeModule('tzm-latn');
test('parse', function (assert) {
@@ -31154,6 +31889,7 @@
// Detect Safari bug and bail. Hours on 13th March 2011 are shifted
// with 1 ahead.
if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {
+ assert.expect(0);
return;
}
@@ -31341,6 +32077,11 @@
assert.ok(moment().toDate() instanceof Date, 'undefined');
});
+ test('iso with bad input', function (assert) {
+ assert.ok(!moment('a', moment.ISO_8601).isValid(), 'iso parsing with invalid string');
+ assert.ok(!moment('a', moment.ISO_8601, true).isValid(), 'iso parsing with invalid string, strict');
+ });
+
test('iso format 24hrs', function (assert) {
assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),
'2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');
@@ -31469,6 +32210,13 @@
}
});
+ test('2 digit year with YYYY format', function (assert) {
+ assert.equal(moment('9/2/99', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/99');
+ assert.equal(moment('9/2/1999', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1999', 'D/M/YYYY ---> 9/2/1999');
+ assert.equal(moment('9/2/68', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/2068', 'D/M/YYYY ---> 9/2/68');
+ assert.equal(moment('9/2/69', 'D/M/YYYY').format('DD/MM/YYYY'), '09/02/1969', 'D/M/YYYY ---> 9/2/69');
+ });
+
test('unix timestamp format', function (assert) {
var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;
@@ -31866,7 +32614,6 @@
assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');
assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');
assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');
- assert.equal(moment('99 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');
assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');
assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');
assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');
@@ -32102,6 +32849,33 @@
assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00+00:00', 'moment.utc works with array of formats');
});
+ test('parsing invalid string weekdays', function (assert) {
+ assert.equal(false, moment('a', 'dd').isValid(),
+ 'dd with invalid weekday, non-strict');
+ assert.equal(false, moment('a', 'dd', true).isValid(),
+ 'dd with invalid weekday, strict');
+ assert.equal(false, moment('a', 'ddd').isValid(),
+ 'ddd with invalid weekday, non-strict');
+ assert.equal(false, moment('a', 'ddd', true).isValid(),
+ 'ddd with invalid weekday, strict');
+ assert.equal(false, moment('a', 'dddd').isValid(),
+ 'dddd with invalid weekday, non-strict');
+ assert.equal(false, moment('a', 'dddd', true).isValid(),
+ 'dddd with invalid weekday, strict');
+ });
+
+ test('milliseconds', function (assert) {
+ assert.equal(moment('1', 'S').millisecond(), 100);
+ assert.equal(moment('12', 'SS').millisecond(), 120);
+ assert.equal(moment('123', 'SSS').millisecond(), 123);
+ assert.equal(moment('1234', 'SSSS').millisecond(), 123);
+ assert.equal(moment('12345', 'SSSSS').millisecond(), 123);
+ assert.equal(moment('123456', 'SSSSSS').millisecond(), 123);
+ assert.equal(moment('1234567', 'SSSSSSS').millisecond(), 123);
+ assert.equal(moment('12345678', 'SSSSSSSS').millisecond(), 123);
+ assert.equal(moment('123456789', 'SSSSSSSSS').millisecond(), 123);
+ });
+
}));
(function (global, factory) {
@@ -32160,12 +32934,10 @@
}
}
- var helpers_each = each;
-
module('days in month');
test('days in month', function (assert) {
- helpers_each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {
+ each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {
var firstDay = moment([2012, i]),
lastDay = moment([2012, i, days]);
assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');
@@ -32733,7 +33505,7 @@
assert.equal(d.years(), 29227, '29227 years');
assert.equal(d.months(), 8, '8 months');
- assert.equal(d.days(), 17, '17 day'); // this should be 13
+ assert.equal(d.days(), 12, '12 day'); // if you have to change this value -- just do it
assert.equal(d.hours(), 2, '2 hours');
assert.equal(d.minutes(), 48, '48 minutes');
@@ -32746,7 +33518,7 @@
assert.equal(d.years(), -29227, '29653 years');
assert.equal(d.months(), -8, '8 day');
- assert.equal(d.days(), -17, '17 day'); // this should be 13
+ assert.equal(d.days(), -12, '12 day'); // if you have to change this value -- just do it
assert.equal(d.hours(), -2, '2 hours');
assert.equal(d.minutes(), -48, '48 minutes');
@@ -32771,6 +33543,7 @@
assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');
assert.equal(moment.duration({y: -0.5, M: 1}).toISOString(), '-P5M', 'a month after half a year ago');
assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');
+ assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');
});
test('toString acts as toISOString', function (assert) {
@@ -32780,6 +33553,7 @@
assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');
assert.equal(moment.duration({y: -0.5, M: 1}).toString(), '-P5M', 'a month after half a year ago');
assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');
+ assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');
});
test('toIsoString deprecation', function (assert) {
@@ -32883,12 +33657,12 @@
assert.equal(moment.duration({months: 13}).months(), 1, '13 months is 1 month left over');
assert.equal(moment.duration({months: 13}).years(), 1, '13 months makes 1 year');
- assert.equal(moment.duration({days: 29}).days(), 29, '29 days is 29 days');
- assert.equal(moment.duration({days: 29}).months(), 0, '29 days makes no month');
- assert.equal(moment.duration({days: 30}).days(), 0, '30 days is 0 days left over');
- assert.equal(moment.duration({days: 30}).months(), 1, '30 days is a month');
- assert.equal(moment.duration({days: 31}).days(), 1, '31 days is 1 day left over');
+ assert.equal(moment.duration({days: 30}).days(), 30, '30 days is 30 days');
+ assert.equal(moment.duration({days: 30}).months(), 0, '30 days makes no month');
+ assert.equal(moment.duration({days: 31}).days(), 0, '31 days is 0 days left over');
assert.equal(moment.duration({days: 31}).months(), 1, '31 days is a month');
+ assert.equal(moment.duration({days: 32}).days(), 1, '32 days is 1 day left over');
+ assert.equal(moment.duration({days: 32}).months(), 1, '32 days is a month');
assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');
assert.equal(moment.duration({hours: 23}).days(), 0, '23 hours makes no day');
@@ -32898,13 +33672,30 @@
assert.equal(moment.duration({hours: 25}).days(), 1, '25 hours makes 1 day');
});
+ test('bubbling consistency', function (assert) {
+ var days = 0, months = 0, newDays, newMonths, totalDays, d;
+ for (totalDays = 1; totalDays <= 500; ++totalDays) {
+ d = moment.duration(totalDays, 'days');
+ newDays = d.days();
+ newMonths = d.months() + d.years() * 12;
+ assert.ok(
+ (months === newMonths && days + 1 === newDays) ||
+ (months + 1 === newMonths && newDays === 0),
+ 'consistent total days ' + totalDays +
+ ' was ' + months + ' ' + days +
+ ' now ' + newMonths + ' ' + newDays);
+ days = newDays;
+ months = newMonths;
+ }
+ });
+
test('effective equivalency', function (assert) {
assert.deepEqual(moment.duration({seconds: 1})._data, moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');
assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data, '1 minute is the same as 60 seconds');
assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data, '1 hour is the same as 60 minutes');
assert.deepEqual(moment.duration({hours: 24})._data, moment.duration({days: 1})._data, '1 day is the same as 24 hours');
assert.deepEqual(moment.duration({days: 7})._data, moment.duration({weeks: 1})._data, '1 week is the same as 7 days');
- assert.deepEqual(moment.duration({days: 30})._data, moment.duration({months: 1})._data, '1 month is the same as 30 days');
+ assert.deepEqual(moment.duration({days: 31})._data, moment.duration({months: 1})._data, '1 month is the same as 30 days');
assert.deepEqual(moment.duration({months: 12})._data, moment.duration({years: 1})._data, '1 years is the same as 12 months');
});
@@ -33043,17 +33834,53 @@
});
test('add and bubble', function (assert) {
+ var d;
+
assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');
assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');
assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');
assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');
+
+ d = moment.duration(-1, 'day').add(1, 'hour');
+ assert.equal(d.hours(), -23, '-1 day + 1 hour == -23 hour (component)');
+ assert.equal(d.asHours(), -23, '-1 day + 1 hour == -23 hours');
+
+ d = moment.duration(-1, 'year').add(1, 'day');
+ assert.equal(d.days(), -30, '- 1 year + 1 day == -30 days (component)');
+ assert.equal(d.months(), -11, '- 1 year + 1 day == -11 months (component)');
+ assert.equal(d.years(), 0, '- 1 year + 1 day == 0 years (component)');
+ assert.equal(d.asDays(), -364, '- 1 year + 1 day == -364 days');
+
+ d = moment.duration(-1, 'year').add(1, 'hour');
+ assert.equal(d.hours(), -23, '- 1 year + 1 hour == -23 hours (component)');
+ assert.equal(d.days(), -30, '- 1 year + 1 hour == -30 days (component)');
+ assert.equal(d.months(), -11, '- 1 year + 1 hour == -11 months (component)');
+ assert.equal(d.years(), 0, '- 1 year + 1 hour == 0 years (component)');
});
test('subtract and bubble', function (assert) {
+ var d;
+
assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');
assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');
assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');
assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');
+
+ d = moment.duration(1, 'day').subtract(1, 'hour');
+ assert.equal(d.hours(), 23, '1 day - 1 hour == 23 hour (component)');
+ assert.equal(d.asHours(), 23, '1 day - 1 hour == 23 hours');
+
+ d = moment.duration(1, 'year').subtract(1, 'day');
+ assert.equal(d.days(), 30, '1 year - 1 day == 30 days (component)');
+ assert.equal(d.months(), 11, '1 year - 1 day == 11 months (component)');
+ assert.equal(d.years(), 0, '1 year - 1 day == 0 years (component)');
+ assert.equal(d.asDays(), 364, '1 year - 1 day == 364 days');
+
+ d = moment.duration(1, 'year').subtract(1, 'hour');
+ assert.equal(d.hours(), 23, '1 year - 1 hour == 23 hours (component)');
+ assert.equal(d.days(), 30, '1 year - 1 hour == 30 days (component)');
+ assert.equal(d.months(), 11, '1 year - 1 hour == 11 months (component)');
+ assert.equal(d.years(), 0, '1 year - 1 hour == 0 years (component)');
});
test('subtract', function (assert) {
@@ -33534,6 +34361,12 @@
assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');
});
+ test('calendar with custom formats', function (assert) {
+ assert.equal(moment().calendar(null, {sameDay: '[Today]'}), 'Today', 'Today');
+ assert.equal(moment().add(1, 'days').calendar(null, {nextDay: '[Tomorrow]'}), 'Tomorrow', 'Tomorrow');
+ assert.equal(moment([1985, 1, 4]).calendar(null, {sameElse: 'YYYY-MM-DD'}), '1985-02-04', 'Else');
+ });
+
test('invalid', function (assert) {
assert.equal(moment.invalid().format(), 'Invalid date');
assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');
@@ -33549,6 +34382,47 @@
assert.equal(moment([2000, 0, 2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan 2 2000 is Q1');
});
+ test('full expanded format is returned from abbreviated formats', function (assert) {
+ var locales = '';
+
+ locales += 'af ar-ma ar-sa ar-tn ar az be bg bn bo br bs';
+ locales += 'ca cs cv cy da de-at de el en-au en-ca en-gb';
+ locales += 'en eo es et eu fa fi fo fr-ca fr fy gl he hi';
+ locales += 'hr hu hy-am id is it ja jv ka km ko lb lt lv';
+ locales += 'me mk ml mr ms-my my nb ne nl nn pl pt-rb pt';
+ locales += 'ro ru si sk sl sq sr-cyrl sr sv ta th tl-ph';
+ locales += 'tr tzm-latn tzm uk uz vi zh-cn zh-tw';
+
+ locales.split(' ').forEach(function (locale) {
+ var data, tokens;
+ data = moment().locale(locale).localeData()._longDateFormat;
+ tokens = Object.keys(data);
+ tokens.forEach(function (token) {
+ // Check each format string to make sure it does not contain any
+ // tokens that need to be expanded.
+ tokens.forEach(function (i) {
+ // strip escaped sequences
+ var format = data[i].replace(/(\[[^\]]*\])/g, '');
+ assert.equal(false, !!~format.indexOf(token), 'locale ' + locale + ' contains ' + token + ' in ' + i);
+ });
+ });
+ });
+ });
+
+ test('milliseconds', function (assert) {
+ var m = moment('123', 'SSS');
+
+ assert.equal(m.format('S'), '1');
+ assert.equal(m.format('SS'), '12');
+ assert.equal(m.format('SSS'), '123');
+ assert.equal(m.format('SSSS'), '1230');
+ assert.equal(m.format('SSSSS'), '12300');
+ assert.equal(m.format('SSSSSS'), '123000');
+ assert.equal(m.format('SSSSSSS'), '1230000');
+ assert.equal(m.format('SSSSSSSS'), '12300000');
+ assert.equal(m.format('SSSSSSSSS'), '123000000');
+ });
+
}));
(function (global, factory) {
@@ -34226,6 +35100,19 @@
assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');
});
+ test('is after invalid', function (assert) {
+ var m = moment(), invalid = moment.invalid();
+ assert.equal(m.isAfter(invalid), false, 'valid moment is not after invalid moment');
+ assert.equal(invalid.isAfter(m), false, 'invalid moment is not after valid moment');
+ assert.equal(m.isAfter(invalid, 'year'), false, 'invalid moment year');
+ assert.equal(m.isAfter(invalid, 'month'), false, 'invalid moment month');
+ assert.equal(m.isAfter(invalid, 'day'), false, 'invalid moment day');
+ assert.equal(m.isAfter(invalid, 'hour'), false, 'invalid moment hour');
+ assert.equal(m.isAfter(invalid, 'minute'), false, 'invalid moment minute');
+ assert.equal(m.isAfter(invalid, 'second'), false, 'invalid moment second');
+ assert.equal(m.isAfter(invalid, 'milliseconds'), false, 'invalid moment milliseconds');
+ });
+
}));
(function (global, factory) {
@@ -34439,6 +35326,19 @@
assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');
});
+ test('is before invalid', function (assert) {
+ var m = moment(), invalid = moment.invalid();
+ assert.equal(m.isBefore(invalid), false, 'valid moment is not before invalid moment');
+ assert.equal(invalid.isBefore(m), false, 'invalid moment is not before valid moment');
+ assert.equal(m.isBefore(invalid, 'year'), false, 'invalid moment year');
+ assert.equal(m.isBefore(invalid, 'month'), false, 'invalid moment month');
+ assert.equal(m.isBefore(invalid, 'day'), false, 'invalid moment day');
+ assert.equal(m.isBefore(invalid, 'hour'), false, 'invalid moment hour');
+ assert.equal(m.isBefore(invalid, 'minute'), false, 'invalid moment minute');
+ assert.equal(m.isBefore(invalid, 'second'), false, 'invalid moment second');
+ assert.equal(m.isBefore(invalid, 'milliseconds'), false, 'invalid moment milliseconds');
+ });
+
}));
(function (global, factory) {
@@ -35069,6 +35969,10 @@
'zoned vs (differently) zoned moment');
});
+ test('is same with invalid moments', function (assert) {
+ assert.equal(moment.invalid().isSame(moment.invalid()), false, 'invalid moments are not considered equal');
+ });
+
}));
(function (global, factory) {
@@ -35241,12 +36145,14 @@
'2010-01-30T23:59:59.999+00:00',
'2010-01-30T23:59:59.999-07:00',
'2010-01-30T00:00:00.000+07:00',
- '2010-01-30T00:00:00.000+07'
+ '2010-01-30 00:00:00.000Z'
], i;
for (i = 0; i < tests.length; i++) {
- assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid');
- assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid');
+ assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');
+ assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid in normal');
+ assert.equal(moment(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');
+ assert.equal(moment.utc(tests[i], moment.ISO_8601, true).isValid(), true, tests[i] + ' should be valid in strict');
}
});
@@ -35617,12 +36523,10 @@
}
}
- var helpers_each = each;
-
module('locale', {
setup : function () {
// TODO: Remove once locales are switched to ES6
- helpers_each([{
+ each([{
name: 'en-gb',
data: {}
}, {
@@ -36118,7 +37022,8 @@
test('min', function (assert) {
var now = moment(),
future = now.clone().add(1, 'month'),
- past = now.clone().subtract(1, 'month');
+ past = now.clone().subtract(1, 'month'),
+ invalid = moment.invalid();
assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');
assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');
@@ -36131,12 +37036,16 @@
assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');
assert.equal(moment.min([now, past]), past, 'min(now, past)');
assert.equal(moment.min([now]), now, 'min(now)');
+
+ assert.equal(moment.min([now, invalid]), invalid, 'min(now, invalid)');
+ assert.equal(moment.min([invalid, now]), invalid, 'min(invalid, now)');
});
test('max', function (assert) {
var now = moment(),
future = now.clone().add(1, 'month'),
- past = now.clone().subtract(1, 'month');
+ past = now.clone().subtract(1, 'month'),
+ invalid = moment.invalid();
assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');
assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');
@@ -36149,6 +37058,9 @@
assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');
assert.equal(moment.max([now, past]), now, 'max(now, past)');
assert.equal(moment.max([now]), now, 'max(now)');
+
+ assert.equal(moment.max([now, invalid]), invalid, 'max(now, invalid)');
+ assert.equal(moment.max([invalid, now]), invalid, 'max(invalid, now)');
});
}));
@@ -37500,6 +38412,77 @@
});
}
+ module('to type');
+
+ test('toObject', function (assert) {
+ var expected = {
+ years:2010,
+ months:3,
+ date:5,
+ hours:15,
+ minutes:10,
+ seconds:3,
+ milliseconds:123
+ };
+ assert.deepEqual(moment(expected).toObject(), expected, 'toObject invalid');
+ });
+
+ test('toArray', function (assert) {
+ var expected = [2014, 11, 26, 11, 46, 58, 17];
+ assert.deepEqual(moment(expected).toArray(), expected, 'toArray invalid');
+ });
+
+}));
+
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :
+ typeof define === 'function' && define.amd ? define(['../../moment'], factory) :
+ factory(global.moment)
+}(this, function (moment) { 'use strict';
+
+ /*global QUnit:false*/
+
+ var test = QUnit.test;
+
+ function module (name, lifecycle) {
+ QUnit.module(name, {
+ setup : function () {
+ moment.locale('en');
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
+ function localeModule (name, lifecycle) {
+ QUnit.module('locale:' + name, {
+ setup : function () {
+ moment.locale(name);
+ moment.createFromInputFallback = function () {
+ throw new Error('input not handled by moment');
+ };
+ if (lifecycle && lifecycle.setup) {
+ lifecycle.setup();
+ }
+ },
+ teardown : function () {
+ moment.locale('en');
+ if (lifecycle && lifecycle.teardown) {
+ lifecycle.teardown();
+ }
+ }
+ });
+ }
+
module('utc');
test('utc and local', function (assert) {
@@ -37519,7 +38502,7 @@
assert.equal(m.date(), 2, 'the date should be correct for local');
assert.equal(m.day(), 3, 'the day should be correct for local');
}
- offset = Math.ceil(m.utcOffset() / 60);
+ offset = Math.floor(m.utcOffset() / 60);
expected = (24 + 3 + offset) % 24;
assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');
assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');
@@ -38304,6 +39287,34 @@
assert.equal(moment([2009, 11, 28]).weekYear(), 2010);
});
+ // Verifies that the week number, week day computation is correct for all dow, doy combinations
+ test('week year roundtrip', function (assert) {
+ var dow, doy, wd, m;
+ for (dow = 0; dow < 7; ++dow) {
+ for (doy = dow; doy < dow + 7; ++doy) {
+ for (wd = 0; wd < 7; ++wd) {
+ moment.locale('dow: ' + dow + ', doy: ' + doy, {week: {dow: dow, doy: doy}});
+ // We use the 10th week as the 1st one can spill to the previous year
+ m = moment('2015 10 ' + wd, 'gggg w d', true);
+ assert.equal(m.format('gggg w d'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);
+ m = moment('2015 10 ' + wd, 'gggg w e', true);
+ assert.equal(m.format('gggg w e'), '2015 10 ' + wd, 'dow: ' + dow + ' doy: ' + doy + ' wd: ' + wd);
+ }
+ }
+ }
+ });
+
+ test('week numbers 2012/2013', function (assert) {
+ moment.locale('dow: 6, doy: 12', {week: {dow: 6, doy: 12}});
+ assert.equal(52, moment('2012-12-28', 'YYYY-MM-DD').week()); // 51 -- should be 52?
+ assert.equal(1, moment('2012-12-29', 'YYYY-MM-DD').week()); // 52 -- should be 1
+ assert.equal(1, moment('2013-01-01', 'YYYY-MM-DD').week()); // 52 -- should be 1
+ assert.equal(2, moment('2013-01-08', 'YYYY-MM-DD').week()); // 53 -- should be 2
+ assert.equal(2, moment('2013-01-11', 'YYYY-MM-DD').week()); // 53 -- should be 2
+ assert.equal(3, moment('2013-01-12', 'YYYY-MM-DD').week()); // 1 -- should be 3
+ assert.equal(52, moment().weeksInYear(2012)); // 52
+ });
+
}));
(function (global, factory) {
diff --git a/bower_components/moment/moment.js b/bower_components/moment/moment.js
index 275a3c3..23cd3ed 100644
--- a/bower_components/moment/moment.js
+++ b/bower_components/moment/moment.js
@@ -1,5 +1,5 @@
//! moment.js
-//! version : 2.10.3
+//! version : 2.10.6
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
@@ -94,6 +94,7 @@
flags.overflow < 0 &&
!flags.empty &&
!flags.invalidMonth &&
+ !flags.invalidWeekday &&
!flags.nullInput &&
!flags.invalidFormat &&
!flags.userInvalidated;
@@ -174,7 +175,7 @@
// Moment prototype object
function Moment(config) {
copyConfig(this, config);
- this._d = new Date(+config._d);
+ this._d = new Date(config._d != null ? config._d.getTime() : NaN);
// Prevent infinite loop in case updateOffset creates new moment
// objects.
if (updateInProgress === false) {
@@ -188,16 +189,20 @@
return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
}
+ function absFloor (number) {
+ if (number < 0) {
+ return Math.ceil(number);
+ } else {
+ return Math.floor(number);
+ }
+ }
+
function toInt(argumentForCoercion) {
var coercedNumber = +argumentForCoercion,
value = 0;
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
- if (coercedNumber >= 0) {
- value = Math.floor(coercedNumber);
- } else {
- value = Math.ceil(coercedNumber);
- }
+ value = absFloor(coercedNumber);
}
return value;
@@ -295,9 +300,7 @@
function defineLocale (name, values) {
if (values !== null) {
values.abbr = name;
- if (!locales[name]) {
- locales[name] = new Locale();
- }
+ locales[name] = locales[name] || new Locale();
locales[name].set(values);
// backwards compat for now: also set the locale
@@ -401,16 +404,14 @@
}
function zeroFill(number, targetLength, forceSign) {
- var output = '' + Math.abs(number),
+ var absNumber = '' + Math.abs(number),
+ zerosToFill = targetLength - absNumber.length,
sign = number >= 0;
-
- while (output.length < targetLength) {
- output = '0' + output;
- }
- return (sign ? (forceSign ? '+' : '') : '-') + output;
+ return (sign ? (forceSign ? '+' : '') : '-') +
+ Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}
- var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;
+ var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
@@ -478,10 +479,7 @@
}
format = expandFormat(format, m.localeData());
-
- if (!formatFunctions[format]) {
- formatFunctions[format] = makeFormatFunction(format);
- }
+ formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
return formatFunctions[format](m);
}
@@ -525,8 +523,15 @@
var regexes = {};
+ function isFunction (sth) {
+ // https://github.com/moment/moment/issues/2325
+ return typeof sth === 'function' &&
+ Object.prototype.toString.call(sth) === '[object Function]';
+ }
+
+
function addRegexToken (token, regex, strictRegex) {
- regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict) {
return (isStrict && strictRegex) ? strictRegex : regex;
};
}
@@ -734,12 +739,11 @@
}
function deprecate(msg, fn) {
- var firstTime = true,
- msgWithStack = msg + '\n' + (new Error()).stack;
+ var firstTime = true;
return extend(function () {
if (firstTime) {
- warn(msgWithStack);
+ warn(msg + '\n' + (new Error()).stack);
firstTime = false;
}
return fn.apply(this, arguments);
@@ -787,14 +791,14 @@
getParsingFlags(config).iso = true;
for (i = 0, l = isoDates.length; i < l; i++) {
if (isoDates[i][1].exec(string)) {
- // match[5] should be 'T' or undefined
- config._f = isoDates[i][0] + (match[6] || ' ');
+ config._f = isoDates[i][0];
break;
}
}
for (i = 0, l = isoTimes.length; i < l; i++) {
if (isoTimes[i][1].exec(string)) {
- config._f += isoTimes[i][0];
+ // match[6] should be 'T' or space
+ config._f += (match[6] || ' ') + isoTimes[i][0];
break;
}
}
@@ -873,7 +877,10 @@
addRegexToken('YYYYY', match1to6, match6);
addRegexToken('YYYYYY', match1to6, match6);
- addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);
+ addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+ addParseToken('YYYY', function (input, array) {
+ array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
+ });
addParseToken('YY', function (input, array) {
array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
});
@@ -1000,18 +1007,18 @@
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
- var d = createUTCDate(year, 0, 1).getUTCDay();
- var daysToAdd;
- var dayOfYear;
+ var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
+ if (d < firstDayOfWeek) {
+ d += 7;
+ }
+
+ weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
- d = d === 0 ? 7 : d;
- weekday = weekday != null ? weekday : firstDayOfWeek;
- daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
- dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
+ dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
return {
- year : dayOfYear > 0 ? year : year - 1,
- dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+ year: dayOfYear > 0 ? year : year - 1,
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
};
}
@@ -1297,9 +1304,19 @@
}
function createFromConfig (config) {
+ var res = new Moment(checkOverflow(prepareConfig(config)));
+ if (res._nextDay) {
+ // Adding is smart enough around DST
+ res.add(1, 'd');
+ res._nextDay = undefined;
+ }
+
+ return res;
+ }
+
+ function prepareConfig (config) {
var input = config._i,
- format = config._f,
- res;
+ format = config._f;
config._locale = config._locale || locale_locales__getLocale(config._l);
@@ -1323,14 +1340,7 @@
configFromInput(config);
}
- res = new Moment(checkOverflow(config));
- if (res._nextDay) {
- // Adding is smart enough around DST
- res.add(1, 'd');
- res._nextDay = undefined;
- }
-
- return res;
+ return config;
}
function configFromInput(config) {
@@ -1410,7 +1420,7 @@
}
res = moments[0];
for (i = 1; i < moments.length; ++i) {
- if (moments[i][fn](res)) {
+ if (!moments[i].isValid() || moments[i][fn](res)) {
res = moments[i];
}
}
@@ -1522,7 +1532,6 @@
} else {
return local__createLocal(input).local();
}
- return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();
}
function getDateOffset (m) {
@@ -1622,12 +1631,7 @@
}
function hasAlignedHourOffset (input) {
- if (!input) {
- input = 0;
- }
- else {
- input = local__createLocal(input).utcOffset();
- }
+ input = input ? local__createLocal(input).utcOffset() : 0;
return (this.utcOffset() - input) % 60 === 0;
}
@@ -1640,12 +1644,24 @@
}
function isDaylightSavingTimeShifted () {
- if (this._a) {
- var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);
- return this.isValid() && compareArrays(this._a, other.toArray()) > 0;
+ if (typeof this._isDSTShifted !== 'undefined') {
+ return this._isDSTShifted;
}
- return false;
+ var c = {};
+
+ copyConfig(c, this);
+ c = prepareConfig(c);
+
+ if (c._a) {
+ var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
+ this._isDSTShifted = this.isValid() &&
+ compareArrays(c._a, other.toArray()) > 0;
+ } else {
+ this._isDSTShifted = false;
+ }
+
+ return this._isDSTShifted;
}
function isLocal () {
@@ -1805,7 +1821,7 @@
var add_subtract__add = createAdder(1, 'add');
var add_subtract__subtract = createAdder(-1, 'subtract');
- function moment_calendar__calendar (time) {
+ function moment_calendar__calendar (time, formats) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're local/utc/offset or not.
var now = time || local__createLocal(),
@@ -1817,7 +1833,7 @@
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(this.localeData().calendar(format, this, local__createLocal(now)));
+ return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now)));
}
function clone () {
@@ -1864,14 +1880,6 @@
}
}
- function absFloor (number) {
- if (number < 0) {
- return Math.ceil(number);
- } else {
- return Math.floor(number);
- }
- }
-
function diff (input, units, asFloat) {
var that = cloneWithOffset(input, this),
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,
@@ -2062,6 +2070,19 @@
return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
}
+ function toObject () {
+ var m = this;
+ return {
+ years: m.year(),
+ months: m.month(),
+ date: m.date(),
+ hours: m.hours(),
+ minutes: m.minutes(),
+ seconds: m.seconds(),
+ milliseconds: m.milliseconds()
+ };
+ }
+
function moment_valid__isValid () {
return valid__isValid(this);
}
@@ -2233,18 +2254,20 @@
// HELPERS
function parseWeekday(input, locale) {
- if (typeof input === 'string') {
- if (!isNaN(input)) {
- input = parseInt(input, 10);
- }
- else {
- input = locale.weekdaysParse(input);
- if (typeof input !== 'number') {
- return null;
- }
- }
+ if (typeof input !== 'string') {
+ return input;
}
- return input;
+
+ if (!isNaN(input)) {
+ return parseInt(input, 10);
+ }
+
+ input = locale.weekdaysParse(input);
+ if (typeof input === 'number') {
+ return input;
+ }
+
+ return null;
}
// LOCALES
@@ -2267,9 +2290,7 @@
function localeWeekdaysParse (weekdayName) {
var i, mom, regex;
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- }
+ this._weekdaysParse = this._weekdaysParse || [];
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
@@ -2416,12 +2437,26 @@
return ~~(this.millisecond() / 10);
});
- function millisecond__milliseconds (token) {
- addFormatToken(0, [token, 3], 0, 'millisecond');
- }
+ addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+ addFormatToken(0, ['SSSS', 4], 0, function () {
+ return this.millisecond() * 10;
+ });
+ addFormatToken(0, ['SSSSS', 5], 0, function () {
+ return this.millisecond() * 100;
+ });
+ addFormatToken(0, ['SSSSSS', 6], 0, function () {
+ return this.millisecond() * 1000;
+ });
+ addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+ return this.millisecond() * 10000;
+ });
+ addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+ return this.millisecond() * 100000;
+ });
+ addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+ return this.millisecond() * 1000000;
+ });
- millisecond__milliseconds('SSS');
- millisecond__milliseconds('SSSS');
// ALIASES
@@ -2432,11 +2467,19 @@
addRegexToken('S', match1to3, match1);
addRegexToken('SS', match1to3, match2);
addRegexToken('SSS', match1to3, match3);
- addRegexToken('SSSS', matchUnsigned);
- addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {
+
+ var token;
+ for (token = 'SSSS'; token.length <= 9; token += 'S') {
+ addRegexToken(token, matchUnsigned);
+ }
+
+ function parseMs(input, array) {
array[MILLISECOND] = toInt(('0.' + input) * 1000);
- });
+ }
+ for (token = 'S'; token.length <= 9; token += 'S') {
+ addParseToken(token, parseMs);
+ }
// MOMENTS
var getSetMillisecond = makeGetSet('Milliseconds', false);
@@ -2483,6 +2526,7 @@
momentPrototype__proto.startOf = startOf;
momentPrototype__proto.subtract = add_subtract__subtract;
momentPrototype__proto.toArray = toArray;
+ momentPrototype__proto.toObject = toObject;
momentPrototype__proto.toDate = toDate;
momentPrototype__proto.toISOString = moment_format__toISOString;
momentPrototype__proto.toJSON = moment_format__toISOString;
@@ -2582,19 +2626,23 @@
LT : 'h:mm A',
L : 'MM/DD/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM D, YYYY LT'
+ LLL : 'MMMM D, YYYY h:mm A',
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
};
function longDateFormat (key) {
- var output = this._longDateFormat[key];
- if (!output && this._longDateFormat[key.toUpperCase()]) {
- output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
- return val.slice(1);
- });
- this._longDateFormat[key] = output;
+ var format = this._longDateFormat[key],
+ formatUpper = this._longDateFormat[key.toUpperCase()];
+
+ if (format || !formatUpper) {
+ return format;
}
- return output;
+
+ this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+ return val.slice(1);
+ });
+
+ return this._longDateFormat[key];
}
var defaultInvalidDate = 'Invalid date';
@@ -2803,12 +2851,29 @@
return duration_add_subtract__addSubtract(this, input, value, -1);
}
+ function absCeil (number) {
+ if (number < 0) {
+ return Math.floor(number);
+ } else {
+ return Math.ceil(number);
+ }
+ }
+
function bubble () {
var milliseconds = this._milliseconds;
var days = this._days;
var months = this._months;
var data = this._data;
- var seconds, minutes, hours, years = 0;
+ var seconds, minutes, hours, years, monthsFromDays;
+
+ // if we have a mix of positive and negative values, bubble down first
+ // check: https://github.com/moment/moment/issues/2166
+ if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+ (milliseconds <= 0 && days <= 0 && months <= 0))) {
+ milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+ days = 0;
+ months = 0;
+ }
// The following code bubbles up values, see the tests for
// examples of what that means.
@@ -2825,17 +2890,13 @@
days += absFloor(hours / 24);
- // Accurately convert days to years, assume start from year 0.
- years = absFloor(daysToYears(days));
- days -= absFloor(yearsToDays(years));
-
- // 30 days to a month
- // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
- months += absFloor(days / 30);
- days %= 30;
+ // convert days to months
+ monthsFromDays = absFloor(daysToMonths(days));
+ months += monthsFromDays;
+ days -= absCeil(monthsToDays(monthsFromDays));
// 12 months -> 1 year
- years += absFloor(months / 12);
+ years = absFloor(months / 12);
months %= 12;
data.days = days;
@@ -2845,15 +2906,15 @@
return this;
}
- function daysToYears (days) {
+ function daysToMonths (days) {
// 400 years have 146097 days (taking into account leap year rules)
- return days * 400 / 146097;
+ // 400 years have 12 months === 4800
+ return days * 4800 / 146097;
}
- function yearsToDays (years) {
- // years * 365 + absFloor(years / 4) -
- // absFloor(years / 100) + absFloor(years / 400);
- return years * 146097 / 400;
+ function monthsToDays (months) {
+ // the reverse of daysToMonths
+ return months * 146097 / 4800;
}
function as (units) {
@@ -2865,11 +2926,11 @@
if (units === 'month' || units === 'year') {
days = this._days + milliseconds / 864e5;
- months = this._months + daysToYears(days) * 12;
+ months = this._months + daysToMonths(days);
return units === 'month' ? months : months / 12;
} else {
// handle milliseconds separately because of floating point math errors (issue #1867)
- days = this._days + Math.round(yearsToDays(this._months / 12));
+ days = this._days + Math.round(monthsToDays(this._months));
switch (units) {
case 'week' : return days / 7 + milliseconds / 6048e5;
case 'day' : return days + milliseconds / 864e5;
@@ -2919,7 +2980,7 @@
};
}
- var duration_get__milliseconds = makeGetter('milliseconds');
+ var milliseconds = makeGetter('milliseconds');
var seconds = makeGetter('seconds');
var minutes = makeGetter('minutes');
var hours = makeGetter('hours');
@@ -2997,13 +3058,36 @@
var iso_string__abs = Math.abs;
function iso_string__toISOString() {
+ // for ISO strings we do not use the normal bubbling rules:
+ // * milliseconds bubble up until they become hours
+ // * days do not bubble at all
+ // * months bubble up until they become years
+ // This is because there is no context-free conversion between hours and days
+ // (think of clock changes)
+ // and also not between days and months (28-31 days per month)
+ var seconds = iso_string__abs(this._milliseconds) / 1000;
+ var days = iso_string__abs(this._days);
+ var months = iso_string__abs(this._months);
+ var minutes, hours, years;
+
+ // 3600 seconds -> 60 minutes -> 1 hour
+ minutes = absFloor(seconds / 60);
+ hours = absFloor(minutes / 60);
+ seconds %= 60;
+ minutes %= 60;
+
+ // 12 months -> 1 year
+ years = absFloor(months / 12);
+ months %= 12;
+
+
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
- var Y = iso_string__abs(this.years());
- var M = iso_string__abs(this.months());
- var D = iso_string__abs(this.days());
- var h = iso_string__abs(this.hours());
- var m = iso_string__abs(this.minutes());
- var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);
+ var Y = years;
+ var M = months;
+ var D = days;
+ var h = hours;
+ var m = minutes;
+ var s = seconds;
var total = this.asSeconds();
if (!total) {
@@ -3040,7 +3124,7 @@
duration_prototype__proto.valueOf = duration_as__valueOf;
duration_prototype__proto._bubble = bubble;
duration_prototype__proto.get = duration_get__get;
- duration_prototype__proto.milliseconds = duration_get__milliseconds;
+ duration_prototype__proto.milliseconds = milliseconds;
duration_prototype__proto.seconds = seconds;
duration_prototype__proto.minutes = minutes;
duration_prototype__proto.hours = hours;
@@ -3078,7 +3162,7 @@
// Side effect imports
- utils_hooks__hooks.version = '2.10.3';
+ utils_hooks__hooks.version = '2.10.6';
setHookCallback(local__createLocal);
diff --git a/bower_components/moment/src/lib/create/from-anything.js b/bower_components/moment/src/lib/create/from-anything.js
index 4b836c0..5a69dc5 100644
--- a/bower_components/moment/src/lib/create/from-anything.js
+++ b/bower_components/moment/src/lib/create/from-anything.js
@@ -14,9 +14,19 @@ import { configFromArray } from './from-array';
import { configFromObject } from './from-object';
function createFromConfig (config) {
+ var res = new Moment(checkOverflow(prepareConfig(config)));
+ if (res._nextDay) {
+ // Adding is smart enough around DST
+ res.add(1, 'd');
+ res._nextDay = undefined;
+ }
+
+ return res;
+}
+
+export function prepareConfig (config) {
var input = config._i,
- format = config._f,
- res;
+ format = config._f;
config._locale = config._locale || getLocale(config._l);
@@ -40,14 +50,7 @@ function createFromConfig (config) {
configFromInput(config);
}
- res = new Moment(checkOverflow(config));
- if (res._nextDay) {
- // Adding is smart enough around DST
- res.add(1, 'd');
- res._nextDay = undefined;
- }
-
- return res;
+ return config;
}
function configFromInput(config) {
diff --git a/bower_components/moment/src/lib/create/from-string.js b/bower_components/moment/src/lib/create/from-string.js
index 4bd6d59..4a7163b 100644
--- a/bower_components/moment/src/lib/create/from-string.js
+++ b/bower_components/moment/src/lib/create/from-string.js
@@ -36,14 +36,14 @@ export function configFromISO(config) {
getParsingFlags(config).iso = true;
for (i = 0, l = isoDates.length; i < l; i++) {
if (isoDates[i][1].exec(string)) {
- // match[5] should be 'T' or undefined
- config._f = isoDates[i][0] + (match[6] || ' ');
+ config._f = isoDates[i][0];
break;
}
}
for (i = 0, l = isoTimes.length; i < l; i++) {
if (isoTimes[i][1].exec(string)) {
- config._f += isoTimes[i][0];
+ // match[6] should be 'T' or space
+ config._f += (match[6] || ' ') + isoTimes[i][0];
break;
}
}
diff --git a/bower_components/moment/src/lib/create/valid.js b/bower_components/moment/src/lib/create/valid.js
index 89204f8..ad56bfe 100644
--- a/bower_components/moment/src/lib/create/valid.js
+++ b/bower_components/moment/src/lib/create/valid.js
@@ -9,6 +9,7 @@ export function isValid(m) {
flags.overflow < 0 &&
!flags.empty &&
!flags.invalidMonth &&
+ !flags.invalidWeekday &&
!flags.nullInput &&
!flags.invalidFormat &&
!flags.userInvalidated;
diff --git a/bower_components/moment/src/lib/duration/as.js b/bower_components/moment/src/lib/duration/as.js
index 258c501..03ecd6d 100644
--- a/bower_components/moment/src/lib/duration/as.js
+++ b/bower_components/moment/src/lib/duration/as.js
@@ -1,4 +1,4 @@
-import { daysToYears, yearsToDays } from './bubble';
+import { daysToMonths, monthsToDays } from './bubble';
import { normalizeUnits } from '../units/aliases';
import toInt from '../utils/to-int';
@@ -11,11 +11,11 @@ export function as (units) {
if (units === 'month' || units === 'year') {
days = this._days + milliseconds / 864e5;
- months = this._months + daysToYears(days) * 12;
+ months = this._months + daysToMonths(days);
return units === 'month' ? months : months / 12;
} else {
// handle milliseconds separately because of floating point math errors (issue #1867)
- days = this._days + Math.round(yearsToDays(this._months / 12));
+ days = this._days + Math.round(monthsToDays(this._months));
switch (units) {
case 'week' : return days / 7 + milliseconds / 6048e5;
case 'day' : return days + milliseconds / 864e5;
diff --git a/bower_components/moment/src/lib/duration/bubble.js b/bower_components/moment/src/lib/duration/bubble.js
index 3dae6b2..0c4a336 100644
--- a/bower_components/moment/src/lib/duration/bubble.js
+++ b/bower_components/moment/src/lib/duration/bubble.js
@@ -1,11 +1,22 @@
import absFloor from '../utils/abs-floor';
+import absCeil from '../utils/abs-ceil';
+import { createUTCDate } from '../create/date-from-array';
export function bubble () {
var milliseconds = this._milliseconds;
var days = this._days;
var months = this._months;
var data = this._data;
- var seconds, minutes, hours, years = 0;
+ var seconds, minutes, hours, years, monthsFromDays;
+
+ // if we have a mix of positive and negative values, bubble down first
+ // check: https://github.com/moment/moment/issues/2166
+ if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
+ (milliseconds <= 0 && days <= 0 && months <= 0))) {
+ milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
+ days = 0;
+ months = 0;
+ }
// The following code bubbles up values, see the tests for
// examples of what that means.
@@ -22,17 +33,13 @@ export function bubble () {
days += absFloor(hours / 24);
- // Accurately convert days to years, assume start from year 0.
- years = absFloor(daysToYears(days));
- days -= absFloor(yearsToDays(years));
-
- // 30 days to a month
- // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
- months += absFloor(days / 30);
- days %= 30;
+ // convert days to months
+ monthsFromDays = absFloor(daysToMonths(days));
+ months += monthsFromDays;
+ days -= absCeil(monthsToDays(monthsFromDays));
// 12 months -> 1 year
- years += absFloor(months / 12);
+ years = absFloor(months / 12);
months %= 12;
data.days = days;
@@ -42,13 +49,13 @@ export function bubble () {
return this;
}
-export function daysToYears (days) {
+export function daysToMonths (days) {
// 400 years have 146097 days (taking into account leap year rules)
- return days * 400 / 146097;
+ // 400 years have 12 months === 4800
+ return days * 4800 / 146097;
}
-export function yearsToDays (years) {
- // years * 365 + absFloor(years / 4) -
- // absFloor(years / 100) + absFloor(years / 400);
- return years * 146097 / 400;
+export function monthsToDays (months) {
+ // the reverse of daysToMonths
+ return months * 146097 / 4800;
}
diff --git a/bower_components/moment/src/lib/duration/iso-string.js b/bower_components/moment/src/lib/duration/iso-string.js
index 2670a9d..f33a968 100644
--- a/bower_components/moment/src/lib/duration/iso-string.js
+++ b/bower_components/moment/src/lib/duration/iso-string.js
@@ -1,13 +1,37 @@
+import absFloor from '../utils/abs-floor';
var abs = Math.abs;
export function toISOString() {
+ // for ISO strings we do not use the normal bubbling rules:
+ // * milliseconds bubble up until they become hours
+ // * days do not bubble at all
+ // * months bubble up until they become years
+ // This is because there is no context-free conversion between hours and days
+ // (think of clock changes)
+ // and also not between days and months (28-31 days per month)
+ var seconds = abs(this._milliseconds) / 1000;
+ var days = abs(this._days);
+ var months = abs(this._months);
+ var minutes, hours, years;
+
+ // 3600 seconds -> 60 minutes -> 1 hour
+ minutes = absFloor(seconds / 60);
+ hours = absFloor(minutes / 60);
+ seconds %= 60;
+ minutes %= 60;
+
+ // 12 months -> 1 year
+ years = absFloor(months / 12);
+ months %= 12;
+
+
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
- var Y = abs(this.years());
- var M = abs(this.months());
- var D = abs(this.days());
- var h = abs(this.hours());
- var m = abs(this.minutes());
- var s = abs(this.seconds() + this.milliseconds() / 1000);
+ var Y = years;
+ var M = months;
+ var D = days;
+ var h = hours;
+ var m = minutes;
+ var s = seconds;
var total = this.asSeconds();
if (!total) {
diff --git a/bower_components/moment/src/lib/format/format.js b/bower_components/moment/src/lib/format/format.js
index 565da01..5378170 100644
--- a/bower_components/moment/src/lib/format/format.js
+++ b/bower_components/moment/src/lib/format/format.js
@@ -1,6 +1,6 @@
import zeroFill from '../utils/zero-fill';
-export var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;
+export var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
@@ -68,10 +68,7 @@ export function formatMoment(m, format) {
}
format = expandFormat(format, m.localeData());
-
- if (!formatFunctions[format]) {
- formatFunctions[format] = makeFormatFunction(format);
- }
+ formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
return formatFunctions[format](m);
}
diff --git a/bower_components/moment/src/lib/locale/formats.js b/bower_components/moment/src/lib/locale/formats.js
index 22b75ad..6d83b03 100644
--- a/bower_components/moment/src/lib/locale/formats.js
+++ b/bower_components/moment/src/lib/locale/formats.js
@@ -3,17 +3,21 @@ export var defaultLongDateFormat = {
LT : 'h:mm A',
L : 'MM/DD/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM D, YYYY LT'
+ LLL : 'MMMM D, YYYY h:mm A',
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
};
export function longDateFormat (key) {
- var output = this._longDateFormat[key];
- if (!output && this._longDateFormat[key.toUpperCase()]) {
- output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
- return val.slice(1);
- });
- this._longDateFormat[key] = output;
+ var format = this._longDateFormat[key],
+ formatUpper = this._longDateFormat[key.toUpperCase()];
+
+ if (format || !formatUpper) {
+ return format;
}
- return output;
+
+ this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
+ return val.slice(1);
+ });
+
+ return this._longDateFormat[key];
}
diff --git a/bower_components/moment/src/lib/locale/locales.js b/bower_components/moment/src/lib/locale/locales.js
index 0e58ded..a32e5ac 100644
--- a/bower_components/moment/src/lib/locale/locales.js
+++ b/bower_components/moment/src/lib/locale/locales.js
@@ -78,9 +78,7 @@ export function getSetGlobalLocale (key, values) {
export function defineLocale (name, values) {
if (values !== null) {
values.abbr = name;
- if (!locales[name]) {
- locales[name] = new Locale();
- }
+ locales[name] = locales[name] || new Locale();
locales[name].set(values);
// backwards compat for now: also set the locale
diff --git a/bower_components/moment/src/lib/moment/calendar.js b/bower_components/moment/src/lib/moment/calendar.js
index 66d70ad..c9df803 100644
--- a/bower_components/moment/src/lib/moment/calendar.js
+++ b/bower_components/moment/src/lib/moment/calendar.js
@@ -1,7 +1,7 @@
import { createLocal } from '../create/local';
import { cloneWithOffset } from '../units/offset';
-export function calendar (time) {
+export function calendar (time, formats) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're local/utc/offset or not.
var now = time || createLocal(),
@@ -13,5 +13,5 @@ export function calendar (time) {
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(this.localeData().calendar(format, this, createLocal(now)));
+ return this.format(formats && formats[format] || this.localeData().calendar(format, this, createLocal(now)));
}
diff --git a/bower_components/moment/src/lib/moment/constructor.js b/bower_components/moment/src/lib/moment/constructor.js
index f735593..f5f3da0 100644
--- a/bower_components/moment/src/lib/moment/constructor.js
+++ b/bower_components/moment/src/lib/moment/constructor.js
@@ -58,7 +58,7 @@ var updateInProgress = false;
// Moment prototype object
export function Moment(config) {
copyConfig(this, config);
- this._d = new Date(+config._d);
+ this._d = new Date(config._d != null ? config._d.getTime() : NaN);
// Prevent infinite loop in case updateOffset creates new moment
// objects.
if (updateInProgress === false) {
diff --git a/bower_components/moment/src/lib/moment/min-max.js b/bower_components/moment/src/lib/moment/min-max.js
index c4a88d2..912cbfe 100644
--- a/bower_components/moment/src/lib/moment/min-max.js
+++ b/bower_components/moment/src/lib/moment/min-max.js
@@ -33,7 +33,7 @@ function pickBy(fn, moments) {
}
res = moments[0];
for (i = 1; i < moments.length; ++i) {
- if (moments[i][fn](res)) {
+ if (!moments[i].isValid() || moments[i][fn](res)) {
res = moments[i];
}
}
diff --git a/bower_components/moment/src/lib/moment/prototype.js b/bower_components/moment/src/lib/moment/prototype.js
index 5601bc0..d17f743 100644
--- a/bower_components/moment/src/lib/moment/prototype.js
+++ b/bower_components/moment/src/lib/moment/prototype.js
@@ -14,7 +14,7 @@ import { getSet } from './get-set';
import { locale, localeData, lang } from './locale';
import { prototypeMin, prototypeMax } from './min-max';
import { startOf, endOf } from './start-end-of';
-import { valueOf, toDate, toArray, unix } from './to-type';
+import { valueOf, toDate, toArray, toObject, unix } from './to-type';
import { isValid, parsingFlags, invalidAt } from './valid';
proto.add = add;
@@ -44,6 +44,7 @@ proto.set = getSet;
proto.startOf = startOf;
proto.subtract = subtract;
proto.toArray = toArray;
+proto.toObject = toObject;
proto.toDate = toDate;
proto.toISOString = toISOString;
proto.toJSON = toISOString;
diff --git a/bower_components/moment/src/lib/moment/to-type.js b/bower_components/moment/src/lib/moment/to-type.js
index edc1338..3008d95 100644
--- a/bower_components/moment/src/lib/moment/to-type.js
+++ b/bower_components/moment/src/lib/moment/to-type.js
@@ -14,3 +14,16 @@ export function toArray () {
var m = this;
return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
}
+
+export function toObject () {
+ var m = this;
+ return {
+ years: m.year(),
+ months: m.month(),
+ date: m.date(),
+ hours: m.hours(),
+ minutes: m.minutes(),
+ seconds: m.seconds(),
+ milliseconds: m.milliseconds()
+ };
+}
diff --git a/bower_components/moment/src/lib/parse/regex.js b/bower_components/moment/src/lib/parse/regex.js
index 23091a0..9e7d678 100644
--- a/bower_components/moment/src/lib/parse/regex.js
+++ b/bower_components/moment/src/lib/parse/regex.js
@@ -22,8 +22,15 @@ import hasOwnProp from '../utils/has-own-prop';
var regexes = {};
+function isFunction (sth) {
+ // https://github.com/moment/moment/issues/2325
+ return typeof sth === 'function' &&
+ Object.prototype.toString.call(sth) === '[object Function]';
+}
+
+
export function addRegexToken (token, regex, strictRegex) {
- regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {
+ regexes[token] = isFunction(regex) ? regex : function (isStrict) {
return (isStrict && strictRegex) ? strictRegex : regex;
};
}
diff --git a/bower_components/moment/src/lib/units/day-of-week.js b/bower_components/moment/src/lib/units/day-of-week.js
index 7af2408..a82f126 100644
--- a/bower_components/moment/src/lib/units/day-of-week.js
+++ b/bower_components/moment/src/lib/units/day-of-week.js
@@ -57,18 +57,20 @@ addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
// HELPERS
function parseWeekday(input, locale) {
- if (typeof input === 'string') {
- if (!isNaN(input)) {
- input = parseInt(input, 10);
- }
- else {
- input = locale.weekdaysParse(input);
- if (typeof input !== 'number') {
- return null;
- }
- }
+ if (typeof input !== 'string') {
+ return input;
+ }
+
+ if (!isNaN(input)) {
+ return parseInt(input, 10);
}
- return input;
+
+ input = locale.weekdaysParse(input);
+ if (typeof input === 'number') {
+ return input;
+ }
+
+ return null;
}
// LOCALES
@@ -91,9 +93,7 @@ export function localeWeekdaysMin (m) {
export function localeWeekdaysParse (weekdayName) {
var i, mom, regex;
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- }
+ this._weekdaysParse = this._weekdaysParse || [];
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
diff --git a/bower_components/moment/src/lib/units/day-of-year.js b/bower_components/moment/src/lib/units/day-of-year.js
index 7c4d286..0c34fa3 100644
--- a/bower_components/moment/src/lib/units/day-of-year.js
+++ b/bower_components/moment/src/lib/units/day-of-year.js
@@ -26,18 +26,18 @@ addParseToken(['DDD', 'DDDD'], function (input, array, config) {
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
export function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
- var d = createUTCDate(year, 0, 1).getUTCDay();
- var daysToAdd;
- var dayOfYear;
+ var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear;
+ if (d < firstDayOfWeek) {
+ d += 7;
+ }
- d = d === 0 ? 7 : d;
- weekday = weekday != null ? weekday : firstDayOfWeek;
- daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
- dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
+ weekday = weekday != null ? 1 * weekday : firstDayOfWeek;
+
+ dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday;
return {
- year : dayOfYear > 0 ? year : year - 1,
- dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
+ year: dayOfYear > 0 ? year : year - 1,
+ dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
};
}
diff --git a/bower_components/moment/src/lib/units/millisecond.js b/bower_components/moment/src/lib/units/millisecond.js
index 2fb73af..134d88e 100644
--- a/bower_components/moment/src/lib/units/millisecond.js
+++ b/bower_components/moment/src/lib/units/millisecond.js
@@ -16,12 +16,26 @@ addFormatToken(0, ['SS', 2], 0, function () {
return ~~(this.millisecond() / 10);
});
-function milliseconds (token) {
- addFormatToken(0, [token, 3], 0, 'millisecond');
-}
+addFormatToken(0, ['SSS', 3], 0, 'millisecond');
+addFormatToken(0, ['SSSS', 4], 0, function () {
+ return this.millisecond() * 10;
+});
+addFormatToken(0, ['SSSSS', 5], 0, function () {
+ return this.millisecond() * 100;
+});
+addFormatToken(0, ['SSSSSS', 6], 0, function () {
+ return this.millisecond() * 1000;
+});
+addFormatToken(0, ['SSSSSSS', 7], 0, function () {
+ return this.millisecond() * 10000;
+});
+addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
+ return this.millisecond() * 100000;
+});
+addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
+ return this.millisecond() * 1000000;
+});
-milliseconds('SSS');
-milliseconds('SSSS');
// ALIASES
@@ -32,11 +46,19 @@ addUnitAlias('millisecond', 'ms');
addRegexToken('S', match1to3, match1);
addRegexToken('SS', match1to3, match2);
addRegexToken('SSS', match1to3, match3);
-addRegexToken('SSSS', matchUnsigned);
-addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {
+
+var token;
+for (token = 'SSSS'; token.length <= 9; token += 'S') {
+ addRegexToken(token, matchUnsigned);
+}
+
+function parseMs(input, array) {
array[MILLISECOND] = toInt(('0.' + input) * 1000);
-});
+}
+for (token = 'S'; token.length <= 9; token += 'S') {
+ addParseToken(token, parseMs);
+}
// MOMENTS
export var getSetMillisecond = makeGetSet('Milliseconds', false);
diff --git a/bower_components/moment/src/lib/units/offset.js b/bower_components/moment/src/lib/units/offset.js
index 75aeb02..33288c0 100644
--- a/bower_components/moment/src/lib/units/offset.js
+++ b/bower_components/moment/src/lib/units/offset.js
@@ -1,11 +1,12 @@
import zeroFill from '../utils/zero-fill';
import { createDuration } from '../duration/create';
import { addSubtract } from '../moment/add-subtract';
-import { isMoment } from '../moment/constructor';
+import { isMoment, copyConfig } from '../moment/constructor';
import { addFormatToken } from '../format/format';
import { addRegexToken, matchOffset } from '../parse/regex';
import { addParseToken } from '../parse/token';
import { createLocal } from '../create/local';
+import { prepareConfig } from '../create/from-anything';
import { createUTC } from '../create/utc';
import isDate from '../utils/is-date';
import toInt from '../utils/to-int';
@@ -67,7 +68,6 @@ export function cloneWithOffset(input, model) {
} else {
return createLocal(input).local();
}
- return model._isUTC ? createLocal(input).zone(model._offset || 0) : createLocal(input).local();
}
function getDateOffset (m) {
@@ -167,12 +167,7 @@ export function setOffsetToParsedOffset () {
}
export function hasAlignedHourOffset (input) {
- if (!input) {
- input = 0;
- }
- else {
- input = createLocal(input).utcOffset();
- }
+ input = input ? createLocal(input).utcOffset() : 0;
return (this.utcOffset() - input) % 60 === 0;
}
@@ -185,12 +180,24 @@ export function isDaylightSavingTime () {
}
export function isDaylightSavingTimeShifted () {
- if (this._a) {
- var other = this._isUTC ? createUTC(this._a) : createLocal(this._a);
- return this.isValid() && compareArrays(this._a, other.toArray()) > 0;
+ if (typeof this._isDSTShifted !== 'undefined') {
+ return this._isDSTShifted;
+ }
+
+ var c = {};
+
+ copyConfig(c, this);
+ c = prepareConfig(c);
+
+ if (c._a) {
+ var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
+ this._isDSTShifted = this.isValid() &&
+ compareArrays(c._a, other.toArray()) > 0;
+ } else {
+ this._isDSTShifted = false;
}
- return false;
+ return this._isDSTShifted;
}
export function isLocal () {
diff --git a/bower_components/moment/src/lib/units/year.js b/bower_components/moment/src/lib/units/year.js
index 4d8a03b..cc32b55 100644
--- a/bower_components/moment/src/lib/units/year.js
+++ b/bower_components/moment/src/lib/units/year.js
@@ -29,7 +29,10 @@ addRegexToken('YYYY', match1to4, match4);
addRegexToken('YYYYY', match1to6, match6);
addRegexToken('YYYYYY', match1to6, match6);
-addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);
+addParseToken(['YYYYY', 'YYYYYY'], YEAR);
+addParseToken('YYYY', function (input, array) {
+ array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
+});
addParseToken('YY', function (input, array) {
array[YEAR] = hooks.parseTwoDigitYear(input);
});
@@ -57,4 +60,3 @@ export var getSetYear = makeGetSet('FullYear', false);
export function getIsLeapYear () {
return isLeapYear(this.year());
}
-
diff --git a/bower_components/moment/src/lib/utils/abs-ceil.js b/bower_components/moment/src/lib/utils/abs-ceil.js
new file mode 100644
index 0000000..7cf9329
--- /dev/null
+++ b/bower_components/moment/src/lib/utils/abs-ceil.js
@@ -0,0 +1,7 @@
+export default function absCeil (number) {
+ if (number < 0) {
+ return Math.floor(number);
+ } else {
+ return Math.ceil(number);
+ }
+}
diff --git a/bower_components/moment/src/lib/utils/deprecate.js b/bower_components/moment/src/lib/utils/deprecate.js
index a076ad7..df4286b 100644
--- a/bower_components/moment/src/lib/utils/deprecate.js
+++ b/bower_components/moment/src/lib/utils/deprecate.js
@@ -8,12 +8,11 @@ function warn(msg) {
}
export function deprecate(msg, fn) {
- var firstTime = true,
- msgWithStack = msg + '\n' + (new Error()).stack;
+ var firstTime = true;
return extend(function () {
if (firstTime) {
- warn(msgWithStack);
+ warn(msg + '\n' + (new Error()).stack);
firstTime = false;
}
return fn.apply(this, arguments);
diff --git a/bower_components/moment/src/lib/utils/to-int.js b/bower_components/moment/src/lib/utils/to-int.js
index 945e019..fb48941 100644
--- a/bower_components/moment/src/lib/utils/to-int.js
+++ b/bower_components/moment/src/lib/utils/to-int.js
@@ -1,13 +1,11 @@
+import absFloor from './abs-floor';
+
export default function toInt(argumentForCoercion) {
var coercedNumber = +argumentForCoercion,
value = 0;
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
- if (coercedNumber >= 0) {
- value = Math.floor(coercedNumber);
- } else {
- value = Math.ceil(coercedNumber);
- }
+ value = absFloor(coercedNumber);
}
return value;
diff --git a/bower_components/moment/src/lib/utils/zero-fill.js b/bower_components/moment/src/lib/utils/zero-fill.js
index af45dd9..7009ec9 100644
--- a/bower_components/moment/src/lib/utils/zero-fill.js
+++ b/bower_components/moment/src/lib/utils/zero-fill.js
@@ -1,9 +1,7 @@
export default function zeroFill(number, targetLength, forceSign) {
- var output = '' + Math.abs(number),
+ var absNumber = '' + Math.abs(number),
+ zerosToFill = targetLength - absNumber.length,
sign = number >= 0;
-
- while (output.length < targetLength) {
- output = '0' + output;
- }
- return (sign ? (forceSign ? '+' : '') : '-') + output;
+ return (sign ? (forceSign ? '+' : '') : '-') +
+ Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}
diff --git a/bower_components/moment/src/locale/af.js b/bower_components/moment/src/locale/af.js
index 8a490ef..13b8d7b 100644
--- a/bower_components/moment/src/locale/af.js
+++ b/bower_components/moment/src/locale/af.js
@@ -23,11 +23,11 @@ export default moment.defineLocale('af', {
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Vandag om] LT',
diff --git a/bower_components/moment/src/locale/ar-ma.js b/bower_components/moment/src/locale/ar-ma.js
index 374468e..fe79651 100644
--- a/bower_components/moment/src/locale/ar-ma.js
+++ b/bower_components/moment/src/locale/ar-ma.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('ar-ma', {
weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[اليوم على الساعة] LT',
diff --git a/bower_components/moment/src/locale/ar-sa.js b/bower_components/moment/src/locale/ar-sa.js
index a0ef282..d32b0ce 100644
--- a/bower_components/moment/src/locale/ar-sa.js
+++ b/bower_components/moment/src/locale/ar-sa.js
@@ -39,8 +39,8 @@ export default moment.defineLocale('ar-sa', {
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
diff --git a/bower_components/moment/src/locale/ar-tn.js b/bower_components/moment/src/locale/ar-tn.js
index acb3e08..5dd0edb 100644
--- a/bower_components/moment/src/locale/ar-tn.js
+++ b/bower_components/moment/src/locale/ar-tn.js
@@ -11,11 +11,11 @@ export default moment.defineLocale('ar-tn', {
weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[اليوم على الساعة] LT',
diff --git a/bower_components/moment/src/locale/ar.js b/bower_components/moment/src/locale/ar.js
index 689bc8f..e8555a0 100644
--- a/bower_components/moment/src/locale/ar.js
+++ b/bower_components/moment/src/locale/ar.js
@@ -72,8 +72,8 @@ export default moment.defineLocale('ar', {
LTS : 'HH:mm:ss',
L : 'D/\u200FM/\u200FYYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
meridiemParse: /ص|م/,
isPM : function (input) {
diff --git a/bower_components/moment/src/locale/az.js b/bower_components/moment/src/locale/az.js
index ecf9352..b30c12d 100644
--- a/bower_components/moment/src/locale/az.js
+++ b/bower_components/moment/src/locale/az.js
@@ -33,11 +33,11 @@ export default moment.defineLocale('az', {
weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
diff --git a/bower_components/moment/src/locale/be.js b/bower_components/moment/src/locale/be.js
index c145116..54e7e4a 100644
--- a/bower_components/moment/src/locale/be.js
+++ b/bower_components/moment/src/locale/be.js
@@ -57,11 +57,11 @@ export default moment.defineLocale('be', {
weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сёння ў] LT',
diff --git a/bower_components/moment/src/locale/bg.js b/bower_components/moment/src/locale/bg.js
index a1f1f72..d017ae5 100644
--- a/bower_components/moment/src/locale/bg.js
+++ b/bower_components/moment/src/locale/bg.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('bg', {
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Днес в] LT',
diff --git a/bower_components/moment/src/locale/bn.js b/bower_components/moment/src/locale/bn.js
index 3a16085..c5893dd 100644
--- a/bower_components/moment/src/locale/bn.js
+++ b/bower_components/moment/src/locale/bn.js
@@ -40,8 +40,8 @@ export default moment.defineLocale('bn', {
LTS : 'A h:mm:ss সময়',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm সময়',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
},
calendar : {
sameDay : '[আজ] LT',
@@ -76,7 +76,7 @@ export default moment.defineLocale('bn', {
return symbolMap[match];
});
},
- meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,
+ meridiemParse: /রাত|সকাল|দুপুর|বিকেল|রাত/,
isPM: function (input) {
return /^(দুপুর|বিকেল|রাত)$/.test(input);
},
@@ -87,7 +87,7 @@ export default moment.defineLocale('bn', {
if (hour < 4) {
return 'রাত';
} else if (hour < 10) {
- return 'শকাল';
+ return 'সকাল';
} else if (hour < 17) {
return 'দুপুর';
} else if (hour < 20) {
diff --git a/bower_components/moment/src/locale/bo.js b/bower_components/moment/src/locale/bo.js
index 102bf3a..6da128d 100644
--- a/bower_components/moment/src/locale/bo.js
+++ b/bower_components/moment/src/locale/bo.js
@@ -37,11 +37,11 @@ export default moment.defineLocale('bo', {
weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
longDateFormat : {
LT : 'A h:mm',
- LTS : 'LT:ss',
+ LTS : 'A h:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm'
},
calendar : {
sameDay : '[དི་རིང] LT',
diff --git a/bower_components/moment/src/locale/br.js b/bower_components/moment/src/locale/br.js
index d6b501d..f95afb3 100644
--- a/bower_components/moment/src/locale/br.js
+++ b/bower_components/moment/src/locale/br.js
@@ -59,8 +59,8 @@ export default moment.defineLocale('br', {
LTS : 'h[e]mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D [a viz] MMMM YYYY',
- LLL : 'D [a viz] MMMM YYYY LT',
- LLLL : 'dddd, D [a viz] MMMM YYYY LT'
+ LLL : 'D [a viz] MMMM YYYY h[e]mm A',
+ LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
},
calendar : {
sameDay : '[Hiziv da] LT',
diff --git a/bower_components/moment/src/locale/bs.js b/bower_components/moment/src/locale/bs.js
index 62b7f8e..8ac94f0 100644
--- a/bower_components/moment/src/locale/bs.js
+++ b/bower_components/moment/src/locale/bs.js
@@ -66,11 +66,11 @@ export default moment.defineLocale('bs', {
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
diff --git a/bower_components/moment/src/locale/ca.js b/bower_components/moment/src/locale/ca.js
index f03f450..d0c1a45 100644
--- a/bower_components/moment/src/locale/ca.js
+++ b/bower_components/moment/src/locale/ca.js
@@ -15,8 +15,8 @@ export default moment.defineLocale('ca', {
LTS : 'LT:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/src/locale/cs.js b/bower_components/moment/src/locale/cs.js
index 9388ee8..57b750b 100644
--- a/bower_components/moment/src/locale/cs.js
+++ b/bower_components/moment/src/locale/cs.js
@@ -78,11 +78,11 @@ export default moment.defineLocale('cs', {
weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes v] LT',
diff --git a/bower_components/moment/src/locale/cv.js b/bower_components/moment/src/locale/cv.js
index 09db067..f1cafe1 100644
--- a/bower_components/moment/src/locale/cv.js
+++ b/bower_components/moment/src/locale/cv.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('cv', {
weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
- LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT',
- LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], LT'
+ LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
+ LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
},
calendar : {
sameDay: '[Паян] LT [сехетре]',
diff --git a/bower_components/moment/src/locale/cy.js b/bower_components/moment/src/locale/cy.js
index 2d574a6..b674ba4 100644
--- a/bower_components/moment/src/locale/cy.js
+++ b/bower_components/moment/src/locale/cy.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('cy', {
// time formats are the same as en-gb
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[Heddiw am] LT',
diff --git a/bower_components/moment/src/locale/da.js b/bower_components/moment/src/locale/da.js
index 9ee0113..a98c4bc 100644
--- a/bower_components/moment/src/locale/da.js
+++ b/bower_components/moment/src/locale/da.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('da', {
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd [d.] D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[I dag kl.] LT',
diff --git a/bower_components/moment/src/locale/de-at.js b/bower_components/moment/src/locale/de-at.js
index 4aae191..5a28e7f 100644
--- a/bower_components/moment/src/locale/de-at.js
+++ b/bower_components/moment/src/locale/de-at.js
@@ -31,8 +31,8 @@ export default moment.defineLocale('de-at', {
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
diff --git a/bower_components/moment/src/locale/de.js b/bower_components/moment/src/locale/de.js
index 58c0c30..205d683 100644
--- a/bower_components/moment/src/locale/de.js
+++ b/bower_components/moment/src/locale/de.js
@@ -30,8 +30,8 @@ export default moment.defineLocale('de', {
LTS: 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY HH:mm',
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Heute um] LT [Uhr]',
diff --git a/bower_components/moment/src/locale/el.js b/bower_components/moment/src/locale/el.js
index 8830ada..83a3421 100644
--- a/bower_components/moment/src/locale/el.js
+++ b/bower_components/moment/src/locale/el.js
@@ -34,8 +34,8 @@ export default moment.defineLocale('el', {
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendarEl : {
sameDay : '[Σήμερα {}] LT',
diff --git a/bower_components/moment/src/locale/en-au.js b/bower_components/moment/src/locale/en-au.js
index a06b6cb..13c4702 100644
--- a/bower_components/moment/src/locale/en-au.js
+++ b/bower_components/moment/src/locale/en-au.js
@@ -14,8 +14,8 @@ export default moment.defineLocale('en-au', {
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/src/locale/en-ca.js b/bower_components/moment/src/locale/en-ca.js
index b33f8ab..9273cf6 100644
--- a/bower_components/moment/src/locale/en-ca.js
+++ b/bower_components/moment/src/locale/en-ca.js
@@ -15,8 +15,8 @@ export default moment.defineLocale('en-ca', {
LTS : 'h:mm:ss A',
L : 'YYYY-MM-DD',
LL : 'D MMMM, YYYY',
- LLL : 'D MMMM, YYYY LT',
- LLLL : 'dddd, D MMMM, YYYY LT'
+ LLL : 'D MMMM, YYYY h:mm A',
+ LLLL : 'dddd, D MMMM, YYYY h:mm A'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/src/locale/en-gb.js b/bower_components/moment/src/locale/en-gb.js
index 09961dd..82a643f 100644
--- a/bower_components/moment/src/locale/en-gb.js
+++ b/bower_components/moment/src/locale/en-gb.js
@@ -15,8 +15,8 @@ export default moment.defineLocale('en-gb', {
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Today at] LT',
diff --git a/bower_components/moment/src/locale/eo.js b/bower_components/moment/src/locale/eo.js
index 54ecf79..d36d570 100644
--- a/bower_components/moment/src/locale/eo.js
+++ b/bower_components/moment/src/locale/eo.js
@@ -14,11 +14,11 @@ export default moment.defineLocale('eo', {
weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D[-an de] MMMM, YYYY',
- LLL : 'D[-an de] MMMM, YYYY LT',
- LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'
+ LLL : 'D[-an de] MMMM, YYYY HH:mm',
+ LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm'
},
meridiemParse: /[ap]\.t\.m/i,
isPM: function (input) {
diff --git a/bower_components/moment/src/locale/es.js b/bower_components/moment/src/locale/es.js
index c9ea1f5..f9faafe 100644
--- a/bower_components/moment/src/locale/es.js
+++ b/bower_components/moment/src/locale/es.js
@@ -21,11 +21,11 @@ export default moment.defineLocale('es', {
weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY H:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/src/locale/et.js b/bower_components/moment/src/locale/et.js
index 68cbad9..401ab57 100644
--- a/bower_components/moment/src/locale/et.js
+++ b/bower_components/moment/src/locale/et.js
@@ -32,11 +32,11 @@ export default moment.defineLocale('et', {
weekdaysMin : 'P_E_T_K_N_R_L'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Täna,] LT',
diff --git a/bower_components/moment/src/locale/eu.js b/bower_components/moment/src/locale/eu.js
index 2a05907..08a006c 100644
--- a/bower_components/moment/src/locale/eu.js
+++ b/bower_components/moment/src/locale/eu.js
@@ -12,15 +12,15 @@ export default moment.defineLocale('eu', {
weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY[ko] MMMM[ren] D[a]',
- LLL : 'YYYY[ko] MMMM[ren] D[a] LT',
- LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',
+ LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm',
+ LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm',
l : 'YYYY-M-D',
ll : 'YYYY[ko] MMM D[a]',
- lll : 'YYYY[ko] MMM D[a] LT',
- llll : 'ddd, YYYY[ko] MMM D[a] LT'
+ lll : 'YYYY[ko] MMM D[a] HH:mm',
+ llll : 'ddd, YYYY[ko] MMM D[a] HH:mm'
},
calendar : {
sameDay : '[gaur] LT[etan]',
diff --git a/bower_components/moment/src/locale/fa.js b/bower_components/moment/src/locale/fa.js
index e898adf..96e670b 100644
--- a/bower_components/moment/src/locale/fa.js
+++ b/bower_components/moment/src/locale/fa.js
@@ -36,11 +36,11 @@ export default moment.defineLocale('fa', {
weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
meridiemParse: /قبل از ظهر|بعد از ظهر/,
isPM: function (input) {
diff --git a/bower_components/moment/src/locale/fi.js b/bower_components/moment/src/locale/fi.js
index ee38516..ed92940 100644
--- a/bower_components/moment/src/locale/fi.js
+++ b/bower_components/moment/src/locale/fi.js
@@ -58,12 +58,12 @@ export default moment.defineLocale('fi', {
LTS : 'HH.mm.ss',
L : 'DD.MM.YYYY',
LL : 'Do MMMM[ta] YYYY',
- LLL : 'Do MMMM[ta] YYYY, [klo] LT',
- LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',
+ LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm',
+ LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm',
l : 'D.M.YYYY',
ll : 'Do MMM YYYY',
- lll : 'Do MMM YYYY, [klo] LT',
- llll : 'ddd, Do MMM YYYY, [klo] LT'
+ lll : 'Do MMM YYYY, [klo] HH.mm',
+ llll : 'ddd, Do MMM YYYY, [klo] HH.mm'
},
calendar : {
sameDay : '[tänään] [klo] LT',
diff --git a/bower_components/moment/src/locale/fo.js b/bower_components/moment/src/locale/fo.js
index 28a8e17..2425fc9 100644
--- a/bower_components/moment/src/locale/fo.js
+++ b/bower_components/moment/src/locale/fo.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('fo', {
weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D. MMMM, YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D. MMMM, YYYY HH:mm'
},
calendar : {
sameDay : '[Í dag kl.] LT',
diff --git a/bower_components/moment/src/locale/fr-ca.js b/bower_components/moment/src/locale/fr-ca.js
index ef95bd2..9294b66 100644
--- a/bower_components/moment/src/locale/fr-ca.js
+++ b/bower_components/moment/src/locale/fr-ca.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('fr-ca', {
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
@@ -41,9 +41,9 @@ export default moment.defineLocale('fr-ca', {
y : 'un an',
yy : '%d ans'
},
- ordinalParse: /\d{1,2}(er|)/,
+ ordinalParse: /\d{1,2}(er|e)/,
ordinal : function (number) {
- return number + (number === 1 ? 'er' : '');
+ return number + (number === 1 ? 'er' : 'e');
}
});
diff --git a/bower_components/moment/src/locale/fr.js b/bower_components/moment/src/locale/fr.js
index 7492f85..deb2f63 100644
--- a/bower_components/moment/src/locale/fr.js
+++ b/bower_components/moment/src/locale/fr.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('fr', {
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
diff --git a/bower_components/moment/src/locale/fy.js b/bower_components/moment/src/locale/fy.js
index 2ccf179..7c8af61 100644
--- a/bower_components/moment/src/locale/fy.js
+++ b/bower_components/moment/src/locale/fy.js
@@ -21,11 +21,11 @@ export default moment.defineLocale('fy', {
weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[hjoed om] LT',
diff --git a/bower_components/moment/src/locale/gl.js b/bower_components/moment/src/locale/gl.js
index 4413809..02c652c 100644
--- a/bower_components/moment/src/locale/gl.js
+++ b/bower_components/moment/src/locale/gl.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('gl', {
weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd D MMMM YYYY H:mm'
},
calendar : {
sameDay : function () {
diff --git a/bower_components/moment/src/locale/he.js b/bower_components/moment/src/locale/he.js
index dd4f2d2..e353158 100644
--- a/bower_components/moment/src/locale/he.js
+++ b/bower_components/moment/src/locale/he.js
@@ -14,15 +14,15 @@ export default moment.defineLocale('he', {
weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [ב]MMMM YYYY',
- LLL : 'D [ב]MMMM YYYY LT',
- LLLL : 'dddd, D [ב]MMMM YYYY LT',
+ LLL : 'D [ב]MMMM YYYY HH:mm',
+ LLLL : 'dddd, D [ב]MMMM YYYY HH:mm',
l : 'D/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay : '[היום ב־]LT',
diff --git a/bower_components/moment/src/locale/hi.js b/bower_components/moment/src/locale/hi.js
index 3d56839..07eae1d 100644
--- a/bower_components/moment/src/locale/hi.js
+++ b/bower_components/moment/src/locale/hi.js
@@ -40,8 +40,8 @@ export default moment.defineLocale('hi', {
LTS : 'A h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm बजे'
},
calendar : {
sameDay : '[आज] LT',
diff --git a/bower_components/moment/src/locale/hr.js b/bower_components/moment/src/locale/hr.js
index eab62df..5dd529a 100644
--- a/bower_components/moment/src/locale/hr.js
+++ b/bower_components/moment/src/locale/hr.js
@@ -65,11 +65,11 @@ export default moment.defineLocale('hr', {
weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danas u] LT',
diff --git a/bower_components/moment/src/locale/hu.js b/bower_components/moment/src/locale/hu.js
index 9359a3c..bc13509 100644
--- a/bower_components/moment/src/locale/hu.js
+++ b/bower_components/moment/src/locale/hu.js
@@ -46,11 +46,11 @@ export default moment.defineLocale('hu', {
weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'YYYY.MM.DD.',
LL : 'YYYY. MMMM D.',
- LLL : 'YYYY. MMMM D., LT',
- LLLL : 'YYYY. MMMM D., dddd LT'
+ LLL : 'YYYY. MMMM D. H:mm',
+ LLLL : 'YYYY. MMMM D., dddd H:mm'
},
meridiemParse: /de|du/i,
isPM: function (input) {
diff --git a/bower_components/moment/src/locale/hy-am.js b/bower_components/moment/src/locale/hy-am.js
index fdaac2f..dd78e6a 100644
--- a/bower_components/moment/src/locale/hy-am.js
+++ b/bower_components/moment/src/locale/hy-am.js
@@ -31,11 +31,11 @@ export default moment.defineLocale('hy-am', {
weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY թ.',
- LLL : 'D MMMM YYYY թ., LT',
- LLLL : 'dddd, D MMMM YYYY թ., LT'
+ LLL : 'D MMMM YYYY թ., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY թ., HH:mm'
},
calendar : {
sameDay: '[այսօր] LT',
diff --git a/bower_components/moment/src/locale/id.js b/bower_components/moment/src/locale/id.js
index 8af7f02..7bf359f 100644
--- a/bower_components/moment/src/locale/id.js
+++ b/bower_components/moment/src/locale/id.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('id', {
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|siang|sore|malam/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/src/locale/is.js b/bower_components/moment/src/locale/is.js
index 13b8815..833907d 100644
--- a/bower_components/moment/src/locale/is.js
+++ b/bower_components/moment/src/locale/is.js
@@ -79,11 +79,11 @@ export default moment.defineLocale('is', {
weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd, D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H:mm',
+ LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm'
},
calendar : {
sameDay : '[í dag kl.] LT',
diff --git a/bower_components/moment/src/locale/it.js b/bower_components/moment/src/locale/it.js
index 63f34ac..d2d764c 100644
--- a/bower_components/moment/src/locale/it.js
+++ b/bower_components/moment/src/locale/it.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('it', {
weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Oggi alle] LT',
diff --git a/bower_components/moment/src/locale/ja.js b/bower_components/moment/src/locale/ja.js
index 1f9b865..6cdc4fc 100644
--- a/bower_components/moment/src/locale/ja.js
+++ b/bower_components/moment/src/locale/ja.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('ja', {
weekdaysMin : '日_月_火_水_木_金_土'.split('_'),
longDateFormat : {
LT : 'Ah時m分',
- LTS : 'LTs秒',
+ LTS : 'Ah時m分s秒',
L : 'YYYY/MM/DD',
LL : 'YYYY年M月D日',
- LLL : 'YYYY年M月D日LT',
- LLLL : 'YYYY年M月D日LT dddd'
+ LLL : 'YYYY年M月D日Ah時m分',
+ LLLL : 'YYYY年M月D日Ah時m分 dddd'
},
meridiemParse: /午前|午後/i,
isPM : function (input) {
diff --git a/bower_components/moment/src/locale/jv.js b/bower_components/moment/src/locale/jv.js
index b5401a0..8596944 100644
--- a/bower_components/moment/src/locale/jv.js
+++ b/bower_components/moment/src/locale/jv.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('jv', {
weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /enjing|siyang|sonten|ndalu/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/src/locale/ka.js b/bower_components/moment/src/locale/ka.js
index a750b2a..b1454b8 100644
--- a/bower_components/moment/src/locale/ka.js
+++ b/bower_components/moment/src/locale/ka.js
@@ -36,8 +36,8 @@ export default moment.defineLocale('ka', {
LTS : 'h:mm:ss A',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY h:mm A',
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
},
calendar : {
sameDay : '[დღეს] LT[-ზე]',
diff --git a/bower_components/moment/src/locale/km.js b/bower_components/moment/src/locale/km.js
index db9147e..389d1f6 100644
--- a/bower_components/moment/src/locale/km.js
+++ b/bower_components/moment/src/locale/km.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('km', {
weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),
longDateFormat: {
LT: 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd, D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',
diff --git a/bower_components/moment/src/locale/ko.js b/bower_components/moment/src/locale/ko.js
index a56aee0..268e782 100644
--- a/bower_components/moment/src/locale/ko.js
+++ b/bower_components/moment/src/locale/ko.js
@@ -19,8 +19,8 @@ export default moment.defineLocale('ko', {
LTS : 'A h시 m분 s초',
L : 'YYYY.MM.DD',
LL : 'YYYY년 MMMM D일',
- LLL : 'YYYY년 MMMM D일 LT',
- LLLL : 'YYYY년 MMMM D일 dddd LT'
+ LLL : 'YYYY년 MMMM D일 A h시 m분',
+ LLLL : 'YYYY년 MMMM D일 dddd A h시 m분'
},
calendar : {
sameDay : '오늘 LT',
diff --git a/bower_components/moment/src/locale/lb.js b/bower_components/moment/src/locale/lb.js
index 6cc6d55..3f20eea 100644
--- a/bower_components/moment/src/locale/lb.js
+++ b/bower_components/moment/src/locale/lb.js
@@ -80,8 +80,8 @@ export default moment.defineLocale('lb', {
LTS: 'H:mm:ss [Auer]',
L: 'DD.MM.YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm [Auer]',
+ LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]'
},
calendar: {
sameDay: '[Haut um] LT',
diff --git a/bower_components/moment/src/locale/lt.js b/bower_components/moment/src/locale/lt.js
index 8095163..6487c68 100644
--- a/bower_components/moment/src/locale/lt.js
+++ b/bower_components/moment/src/locale/lt.js
@@ -24,6 +24,16 @@ function translateSeconds(number, withoutSuffix, key, isFuture) {
return isFuture ? 'kelių sekundžių' : 'kelias sekundes';
}
}
+function monthsCaseReplace(m, format) {
+ var months = {
+ 'nominative': 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'),
+ 'accusative': 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_')
+ },
+ nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+ 'accusative' :
+ 'nominative';
+ return months[nounCase][m.month()];
+}
function translateSingular(number, withoutSuffix, key, isFuture) {
return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
}
@@ -54,22 +64,22 @@ function relativeWeekDay(moment, format) {
}
export default moment.defineLocale('lt', {
- months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),
+ months : monthsCaseReplace,
monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),
weekdays : relativeWeekDay,
weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),
weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'YYYY [m.] MMMM D [d.]',
- LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',
- LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',
+ LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]',
l : 'YYYY-MM-DD',
ll : 'YYYY [m.] MMMM D [d.]',
- lll : 'YYYY [m.] MMMM D [d.], LT [val.]',
- llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'
+ lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]',
+ llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]'
},
calendar : {
sameDay : '[Šiandien] LT',
diff --git a/bower_components/moment/src/locale/lv.js b/bower_components/moment/src/locale/lv.js
index b37cb5c..53aec40 100644
--- a/bower_components/moment/src/locale/lv.js
+++ b/bower_components/moment/src/locale/lv.js
@@ -48,11 +48,11 @@ export default moment.defineLocale('lv', {
weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY.',
LL : 'YYYY. [gada] D. MMMM',
- LLL : 'YYYY. [gada] D. MMMM, LT',
- LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'
+ LLL : 'YYYY. [gada] D. MMMM, HH:mm',
+ LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm'
},
calendar : {
sameDay : '[Šodien pulksten] LT',
diff --git a/bower_components/moment/src/locale/me.js b/bower_components/moment/src/locale/me.js
index 2c356da..a509658 100644
--- a/bower_components/moment/src/locale/me.js
+++ b/bower_components/moment/src/locale/me.js
@@ -35,11 +35,11 @@ export default moment.defineLocale('me', {
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
diff --git a/bower_components/moment/src/locale/mk.js b/bower_components/moment/src/locale/mk.js
index 80c522d..3d2bb93 100644
--- a/bower_components/moment/src/locale/mk.js
+++ b/bower_components/moment/src/locale/mk.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('mk', {
weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'D.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY H:mm',
+ LLLL : 'dddd, D MMMM YYYY H:mm'
},
calendar : {
sameDay : '[Денес во] LT',
diff --git a/bower_components/moment/src/locale/ml.js b/bower_components/moment/src/locale/ml.js
index cbb9056..7bafa7a 100644
--- a/bower_components/moment/src/locale/ml.js
+++ b/bower_components/moment/src/locale/ml.js
@@ -15,8 +15,8 @@ export default moment.defineLocale('ml', {
LTS : 'A h:mm:ss -നു',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm -നു',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm -നു'
},
calendar : {
sameDay : '[ഇന്ന്] LT',
diff --git a/bower_components/moment/src/locale/mr.js b/bower_components/moment/src/locale/mr.js
index 24011a3..7a2b8e0 100644
--- a/bower_components/moment/src/locale/mr.js
+++ b/bower_components/moment/src/locale/mr.js
@@ -40,8 +40,8 @@ export default moment.defineLocale('mr', {
LTS : 'A h:mm:ss वाजता',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, A h:mm वाजता',
+ LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
},
calendar : {
sameDay : '[आज] LT',
diff --git a/bower_components/moment/src/locale/ms-my.js b/bower_components/moment/src/locale/ms-my.js
index 10bce03..1490a1f 100644
--- a/bower_components/moment/src/locale/ms-my.js
+++ b/bower_components/moment/src/locale/ms-my.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('ms-my', {
weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
longDateFormat : {
LT : 'HH.mm',
- LTS : 'LT.ss',
+ LTS : 'HH.mm.ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY [pukul] LT',
- LLLL : 'dddd, D MMMM YYYY [pukul] LT'
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
},
meridiemParse: /pagi|tengahari|petang|malam/,
meridiemHour: function (hour, meridiem) {
diff --git a/bower_components/moment/src/locale/ms.js b/bower_components/moment/src/locale/ms.js
new file mode 100644
index 0000000..59fb9a2
--- /dev/null
+++ b/bower_components/moment/src/locale/ms.js
@@ -0,0 +1,73 @@
+//! moment.js locale configuration
+//! locale : Bahasa Malaysia (ms-MY)
+//! author : Weldan Jamili : https://github.com/weldan
+
+import moment from '../moment';
+
+export default moment.defineLocale('ms', {
+ months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),
+ monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),
+ weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),
+ weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),
+ weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'HH.mm.ss',
+ L : 'DD/MM/YYYY',
+ LL : 'D MMMM YYYY',
+ LLL : 'D MMMM YYYY [pukul] HH.mm',
+ LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm'
+ },
+ meridiemParse: /pagi|tengahari|petang|malam/,
+ meridiemHour: function (hour, meridiem) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ if (meridiem === 'pagi') {
+ return hour;
+ } else if (meridiem === 'tengahari') {
+ return hour >= 11 ? hour : hour + 12;
+ } else if (meridiem === 'petang' || meridiem === 'malam') {
+ return hour + 12;
+ }
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours < 11) {
+ return 'pagi';
+ } else if (hours < 15) {
+ return 'tengahari';
+ } else if (hours < 19) {
+ return 'petang';
+ } else {
+ return 'malam';
+ }
+ },
+ calendar : {
+ sameDay : '[Hari ini pukul] LT',
+ nextDay : '[Esok pukul] LT',
+ nextWeek : 'dddd [pukul] LT',
+ lastDay : '[Kelmarin pukul] LT',
+ lastWeek : 'dddd [lepas pukul] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'dalam %s',
+ past : '%s yang lepas',
+ s : 'beberapa saat',
+ m : 'seminit',
+ mm : '%d minit',
+ h : 'sejam',
+ hh : '%d jam',
+ d : 'sehari',
+ dd : '%d hari',
+ M : 'sebulan',
+ MM : '%d bulan',
+ y : 'setahun',
+ yy : '%d tahun'
+ },
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
+ }
+});
+
diff --git a/bower_components/moment/src/locale/my.js b/bower_components/moment/src/locale/my.js
index 54af140..d9dff81 100644
--- a/bower_components/moment/src/locale/my.js
+++ b/bower_components/moment/src/locale/my.js
@@ -40,8 +40,8 @@ export default moment.defineLocale('my', {
LTS: 'HH:mm:ss',
L: 'DD/MM/YYYY',
LL: 'D MMMM YYYY',
- LLL: 'D MMMM YYYY LT',
- LLLL: 'dddd D MMMM YYYY LT'
+ LLL: 'D MMMM YYYY HH:mm',
+ LLLL: 'dddd D MMMM YYYY HH:mm'
},
calendar: {
sameDay: '[ယနေ.] LT [မှာ]',
diff --git a/bower_components/moment/src/locale/nb.js b/bower_components/moment/src/locale/nb.js
index cadc224..d5f15a9 100644
--- a/bower_components/moment/src/locale/nb.js
+++ b/bower_components/moment/src/locale/nb.js
@@ -13,11 +13,11 @@ export default moment.defineLocale('nb', {
weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'H.mm',
- LTS : 'LT.ss',
+ LTS : 'H.mm.ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY [kl.] LT',
- LLLL : 'dddd D. MMMM YYYY [kl.] LT'
+ LLL : 'D. MMMM YYYY [kl.] H.mm',
+ LLLL : 'dddd D. MMMM YYYY [kl.] H.mm'
},
calendar : {
sameDay: '[i dag kl.] LT',
diff --git a/bower_components/moment/src/locale/ne.js b/bower_components/moment/src/locale/ne.js
index 966db26..e229357 100644
--- a/bower_components/moment/src/locale/ne.js
+++ b/bower_components/moment/src/locale/ne.js
@@ -40,8 +40,8 @@ export default moment.defineLocale('ne', {
LTS : 'Aको h:mm:ss बजे',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, Aको h:mm बजे',
+ LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे'
},
preparse: function (string) {
return string.replace(/[१२३४५६७८९०]/g, function (match) {
diff --git a/bower_components/moment/src/locale/nl.js b/bower_components/moment/src/locale/nl.js
index f493a76..6669531 100644
--- a/bower_components/moment/src/locale/nl.js
+++ b/bower_components/moment/src/locale/nl.js
@@ -21,11 +21,11 @@ export default moment.defineLocale('nl', {
weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD-MM-YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[vandaag om] LT',
diff --git a/bower_components/moment/src/locale/nn.js b/bower_components/moment/src/locale/nn.js
index b3f76c5..3f284b3 100644
--- a/bower_components/moment/src/locale/nn.js
+++ b/bower_components/moment/src/locale/nn.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('nn', {
weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[I dag klokka] LT',
diff --git a/bower_components/moment/src/locale/pl.js b/bower_components/moment/src/locale/pl.js
index e458ea5..e6a3a5a 100644
--- a/bower_components/moment/src/locale/pl.js
+++ b/bower_components/moment/src/locale/pl.js
@@ -46,11 +46,11 @@ export default moment.defineLocale('pl', {
weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Dziś o] LT',
diff --git a/bower_components/moment/src/locale/pt-br.js b/bower_components/moment/src/locale/pt-br.js
index e08e847..c002fdb 100644
--- a/bower_components/moment/src/locale/pt-br.js
+++ b/bower_components/moment/src/locale/pt-br.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('pt-br', {
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY [às] LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'
+ LLL : 'D [de] MMMM [de] YYYY [às] HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
@@ -33,7 +33,7 @@ export default moment.defineLocale('pt-br', {
relativeTime : {
future : 'em %s',
past : '%s atrás',
- s : 'segundos',
+ s : 'poucos segundos',
m : 'um minuto',
mm : '%d minutos',
h : 'uma hora',
diff --git a/bower_components/moment/src/locale/pt.js b/bower_components/moment/src/locale/pt.js
index 71e37c6..0a38d46 100644
--- a/bower_components/moment/src/locale/pt.js
+++ b/bower_components/moment/src/locale/pt.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('pt', {
weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D [de] MMMM [de] YYYY',
- LLL : 'D [de] MMMM [de] YYYY LT',
- LLLL : 'dddd, D [de] MMMM [de] YYYY LT'
+ LLL : 'D [de] MMMM [de] YYYY HH:mm',
+ LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm'
},
calendar : {
sameDay: '[Hoje às] LT',
diff --git a/bower_components/moment/src/locale/ro.js b/bower_components/moment/src/locale/ro.js
index de6cebf..56413d8 100644
--- a/bower_components/moment/src/locale/ro.js
+++ b/bower_components/moment/src/locale/ro.js
@@ -28,7 +28,7 @@ export default moment.defineLocale('ro', {
weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY H:mm',
diff --git a/bower_components/moment/src/locale/ru.js b/bower_components/moment/src/locale/ru.js
index 8a210a4..0687888 100644
--- a/bower_components/moment/src/locale/ru.js
+++ b/bower_components/moment/src/locale/ru.js
@@ -64,11 +64,11 @@ export default moment.defineLocale('ru', {
monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY г.',
- LLL : 'D MMMM YYYY г., LT',
- LLLL : 'dddd, D MMMM YYYY г., LT'
+ LLL : 'D MMMM YYYY г., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
},
calendar : {
sameDay: '[Сегодня в] LT',
diff --git a/bower_components/moment/src/locale/si.js b/bower_components/moment/src/locale/si.js
index 4f5995c..15c9f15 100644
--- a/bower_components/moment/src/locale/si.js
+++ b/bower_components/moment/src/locale/si.js
@@ -16,8 +16,8 @@ export default moment.defineLocale('si', {
LTS : 'a h:mm:ss',
L : 'YYYY/MM/DD',
LL : 'YYYY MMMM D',
- LLL : 'YYYY MMMM D, LT',
- LLLL : 'YYYY MMMM D [වැනි] dddd, LTS'
+ LLL : 'YYYY MMMM D, a h:mm',
+ LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss'
},
calendar : {
sameDay : '[අද] LT[ට]',
diff --git a/bower_components/moment/src/locale/sk.js b/bower_components/moment/src/locale/sk.js
index 4ac38c3..079725c 100644
--- a/bower_components/moment/src/locale/sk.js
+++ b/bower_components/moment/src/locale/sk.js
@@ -79,11 +79,11 @@ export default moment.defineLocale('sk', {
weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),
longDateFormat : {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd D. MMMM YYYY H:mm'
},
calendar : {
sameDay: '[dnes o] LT',
diff --git a/bower_components/moment/src/locale/sl.js b/bower_components/moment/src/locale/sl.js
index e572338..0cb6701 100644
--- a/bower_components/moment/src/locale/sl.js
+++ b/bower_components/moment/src/locale/sl.js
@@ -83,11 +83,11 @@ export default moment.defineLocale('sl', {
weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),
longDateFormat : {
LT : 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L : 'DD. MM. YYYY',
LL : 'D. MMMM YYYY',
- LLL : 'D. MMMM YYYY LT',
- LLLL : 'dddd, D. MMMM YYYY LT'
+ LLL : 'D. MMMM YYYY H:mm',
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
},
calendar : {
sameDay : '[danes ob] LT',
diff --git a/bower_components/moment/src/locale/sq.js b/bower_components/moment/src/locale/sq.js
index 76172b4..d8a9c02 100644
--- a/bower_components/moment/src/locale/sq.js
+++ b/bower_components/moment/src/locale/sq.js
@@ -21,11 +21,11 @@ export default moment.defineLocale('sq', {
},
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[Sot në] LT',
diff --git a/bower_components/moment/src/locale/sr-cyrl.js b/bower_components/moment/src/locale/sr-cyrl.js
index 1da53e3..2ce8eea 100644
--- a/bower_components/moment/src/locale/sr-cyrl.js
+++ b/bower_components/moment/src/locale/sr-cyrl.js
@@ -35,11 +35,11 @@ export default moment.defineLocale('sr-cyrl', {
weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[данас у] LT',
diff --git a/bower_components/moment/src/locale/sr.js b/bower_components/moment/src/locale/sr.js
index 210c739..233e467 100644
--- a/bower_components/moment/src/locale/sr.js
+++ b/bower_components/moment/src/locale/sr.js
@@ -35,11 +35,11 @@ export default moment.defineLocale('sr', {
weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
longDateFormat: {
LT: 'H:mm',
- LTS : 'LT:ss',
+ LTS : 'H:mm:ss',
L: 'DD. MM. YYYY',
LL: 'D. MMMM YYYY',
- LLL: 'D. MMMM YYYY LT',
- LLLL: 'dddd, D. MMMM YYYY LT'
+ LLL: 'D. MMMM YYYY H:mm',
+ LLLL: 'dddd, D. MMMM YYYY H:mm'
},
calendar: {
sameDay: '[danas u] LT',
diff --git a/bower_components/moment/src/locale/sv.js b/bower_components/moment/src/locale/sv.js
index 6fc1c26..1e841f6 100644
--- a/bower_components/moment/src/locale/sv.js
+++ b/bower_components/moment/src/locale/sv.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('sv', {
weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'YYYY-MM-DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Idag] LT',
diff --git a/bower_components/moment/src/locale/ta.js b/bower_components/moment/src/locale/ta.js
index 4341c3e..6879be4 100644
--- a/bower_components/moment/src/locale/ta.js
+++ b/bower_components/moment/src/locale/ta.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('ta', {
weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY, LT',
- LLLL : 'dddd, D MMMM YYYY, LT'
+ LLL : 'D MMMM YYYY, HH:mm',
+ LLLL : 'dddd, D MMMM YYYY, HH:mm'
},
calendar : {
sameDay : '[இன்று] LT',
diff --git a/bower_components/moment/src/locale/th.js b/bower_components/moment/src/locale/th.js
index 2382d25..265680c 100644
--- a/bower_components/moment/src/locale/th.js
+++ b/bower_components/moment/src/locale/th.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('th', {
weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),
longDateFormat : {
LT : 'H นาฬิกา m นาที',
- LTS : 'LT s วินาที',
+ LTS : 'H นาฬิกา m นาที s วินาที',
L : 'YYYY/MM/DD',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY เวลา LT',
- LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'
+ LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที',
+ LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที'
},
meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,
isPM: function (input) {
diff --git a/bower_components/moment/src/locale/tl-ph.js b/bower_components/moment/src/locale/tl-ph.js
index a1b24a7..1cd4842 100644
--- a/bower_components/moment/src/locale/tl-ph.js
+++ b/bower_components/moment/src/locale/tl-ph.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('tl-ph', {
weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'MM/D/YYYY',
LL : 'MMMM D, YYYY',
- LLL : 'MMMM D, YYYY LT',
- LLLL : 'dddd, MMMM DD, YYYY LT'
+ LLL : 'MMMM D, YYYY HH:mm',
+ LLLL : 'dddd, MMMM DD, YYYY HH:mm'
},
calendar : {
sameDay: '[Ngayon sa] LT',
diff --git a/bower_components/moment/src/locale/tr.js b/bower_components/moment/src/locale/tr.js
index 78f2b69..e908bc0 100644
--- a/bower_components/moment/src/locale/tr.js
+++ b/bower_components/moment/src/locale/tr.js
@@ -34,11 +34,11 @@ export default moment.defineLocale('tr', {
weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd, D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
},
calendar : {
sameDay : '[bugün saat] LT',
diff --git a/bower_components/moment/src/locale/tzl.js b/bower_components/moment/src/locale/tzl.js
new file mode 100644
index 0000000..cae8534
--- /dev/null
+++ b/bower_components/moment/src/locale/tzl.js
@@ -0,0 +1,78 @@
+//! moment.js locale configuration
+//! locale : talossan (tzl)
+//! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun
+
+
+import moment from '../moment';
+
+// After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals.
+// This is currently too difficult (maybe even impossible) to add.
+export default moment.defineLocale('tzl', {
+ months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'),
+ monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'),
+ weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'),
+ weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'),
+ weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'),
+ longDateFormat : {
+ LT : 'HH.mm',
+ LTS : 'LT.ss',
+ L : 'DD.MM.YYYY',
+ LL : 'D. MMMM [dallas] YYYY',
+ LLL : 'D. MMMM [dallas] YYYY LT',
+ LLLL : 'dddd, [li] D. MMMM [dallas] YYYY LT'
+ },
+ meridiem : function (hours, minutes, isLower) {
+ if (hours > 11) {
+ return isLower ? 'd\'o' : 'D\'O';
+ } else {
+ return isLower ? 'd\'a' : 'D\'A';
+ }
+ },
+ calendar : {
+ sameDay : '[oxhi à] LT',
+ nextDay : '[demà à] LT',
+ nextWeek : 'dddd [à] LT',
+ lastDay : '[ieiri à] LT',
+ lastWeek : '[sür el] dddd [lasteu à] LT',
+ sameElse : 'L'
+ },
+ relativeTime : {
+ future : 'osprei %s',
+ past : 'ja%s',
+ s : processRelativeTime,
+ m : processRelativeTime,
+ mm : processRelativeTime,
+ h : processRelativeTime,
+ hh : processRelativeTime,
+ d : processRelativeTime,
+ dd : processRelativeTime,
+ M : processRelativeTime,
+ MM : processRelativeTime,
+ y : processRelativeTime,
+ yy : processRelativeTime
+ },
+ ordinalParse: /\d{1,2}\./,
+ ordinal : '%d.',
+ week : {
+ dow : 1, // Monday is the first day of the week.
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
+ }
+});
+
+function processRelativeTime(number, withoutSuffix, key, isFuture) {
+ var format = {
+ 's': ['viensas secunds', '\'iensas secunds'],
+ 'm': ['\'n míut', '\'iens míut'],
+ 'mm': [number + ' míuts', ' ' + number + ' míuts'],
+ 'h': ['\'n þora', '\'iensa þora'],
+ 'hh': [number + ' þoras', ' ' + number + ' þoras'],
+ 'd': ['\'n ziua', '\'iensa ziua'],
+ 'dd': [number + ' ziuas', ' ' + number + ' ziuas'],
+ 'M': ['\'n mes', '\'iens mes'],
+ 'MM': [number + ' mesen', ' ' + number + ' mesen'],
+ 'y': ['\'n ar', '\'iens ar'],
+ 'yy': [number + ' ars', ' ' + number + ' ars']
+ };
+ return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1].trim());
+}
+
diff --git a/bower_components/moment/src/locale/tzm-latn.js b/bower_components/moment/src/locale/tzm-latn.js
index 153e51f..e2631d9 100644
--- a/bower_components/moment/src/locale/tzm-latn.js
+++ b/bower_components/moment/src/locale/tzm-latn.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('tzm-latn', {
weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[asdkh g] LT',
diff --git a/bower_components/moment/src/locale/tzm.js b/bower_components/moment/src/locale/tzm.js
index b53adb0..a06a27d 100644
--- a/bower_components/moment/src/locale/tzm.js
+++ b/bower_components/moment/src/locale/tzm.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('tzm', {
weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS: 'LT:ss',
+ LTS: 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'dddd D MMMM YYYY LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',
diff --git a/bower_components/moment/src/locale/uk.js b/bower_components/moment/src/locale/uk.js
index 6fd7a1e..fe1f7d2 100644
--- a/bower_components/moment/src/locale/uk.js
+++ b/bower_components/moment/src/locale/uk.js
@@ -64,11 +64,11 @@ export default moment.defineLocale('uk', {
weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD.MM.YYYY',
LL : 'D MMMM YYYY р.',
- LLL : 'D MMMM YYYY р., LT',
- LLLL : 'dddd, D MMMM YYYY р., LT'
+ LLL : 'D MMMM YYYY р., HH:mm',
+ LLLL : 'dddd, D MMMM YYYY р., HH:mm'
},
calendar : {
sameDay: processHoursFunction('[Сьогодні '),
diff --git a/bower_components/moment/src/locale/uz.js b/bower_components/moment/src/locale/uz.js
index 3732bfd..646b5e6 100644
--- a/bower_components/moment/src/locale/uz.js
+++ b/bower_components/moment/src/locale/uz.js
@@ -12,11 +12,11 @@ export default moment.defineLocale('uz', {
weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
- LLL : 'D MMMM YYYY LT',
- LLLL : 'D MMMM YYYY, dddd LT'
+ LLL : 'D MMMM YYYY HH:mm',
+ LLLL : 'D MMMM YYYY, dddd HH:mm'
},
calendar : {
sameDay : '[Бугун соат] LT [да]',
diff --git a/bower_components/moment/src/locale/vi.js b/bower_components/moment/src/locale/vi.js
index 18ca9f3..0fafda7 100644
--- a/bower_components/moment/src/locale/vi.js
+++ b/bower_components/moment/src/locale/vi.js
@@ -12,15 +12,15 @@ export default moment.defineLocale('vi', {
weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),
longDateFormat : {
LT : 'HH:mm',
- LTS : 'LT:ss',
+ LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM [năm] YYYY',
- LLL : 'D MMMM [năm] YYYY LT',
- LLLL : 'dddd, D MMMM [năm] YYYY LT',
+ LLL : 'D MMMM [năm] YYYY HH:mm',
+ LLLL : 'dddd, D MMMM [năm] YYYY HH:mm',
l : 'DD/M/YYYY',
ll : 'D MMM YYYY',
- lll : 'D MMM YYYY LT',
- llll : 'ddd, D MMM YYYY LT'
+ lll : 'D MMM YYYY HH:mm',
+ llll : 'ddd, D MMM YYYY HH:mm'
},
calendar : {
sameDay: '[Hôm nay lúc] LT',
diff --git a/bower_components/moment/src/locale/zh-cn.js b/bower_components/moment/src/locale/zh-cn.js
index dfc0d04..790ea8b 100644
--- a/bower_components/moment/src/locale/zh-cn.js
+++ b/bower_components/moment/src/locale/zh-cn.js
@@ -16,12 +16,12 @@ export default moment.defineLocale('zh-cn', {
LTS : 'Ah点m分s秒',
L : 'YYYY-MM-DD',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah点mm分',
+ LLLL : 'YYYY年MMMD日ddddAh点mm分',
l : 'YYYY-MM-DD',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah点mm分',
+ llll : 'YYYY年MMMD日ddddAh点mm分'
},
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
meridiemHour: function (hour, meridiem) {
diff --git a/bower_components/moment/src/locale/zh-tw.js b/bower_components/moment/src/locale/zh-tw.js
index 918700a..4ff48f8 100644
--- a/bower_components/moment/src/locale/zh-tw.js
+++ b/bower_components/moment/src/locale/zh-tw.js
@@ -15,12 +15,12 @@ export default moment.defineLocale('zh-tw', {
LTS : 'Ah點m分s秒',
L : 'YYYY年MMMD日',
LL : 'YYYY年MMMD日',
- LLL : 'YYYY年MMMD日LT',
- LLLL : 'YYYY年MMMD日ddddLT',
+ LLL : 'YYYY年MMMD日Ah點mm分',
+ LLLL : 'YYYY年MMMD日ddddAh點mm分',
l : 'YYYY年MMMD日',
ll : 'YYYY年MMMD日',
- lll : 'YYYY年MMMD日LT',
- llll : 'YYYY年MMMD日ddddLT'
+ lll : 'YYYY年MMMD日Ah點mm分',
+ llll : 'YYYY年MMMD日ddddAh點mm分'
},
meridiemParse: /早上|上午|中午|下午|晚上/,
meridiemHour : function (hour, meridiem) {
diff --git a/bower_components/moment/src/moment.js b/bower_components/moment/src/moment.js
index 4407eb9..15fe0e6 100644
--- a/bower_components/moment/src/moment.js
+++ b/bower_components/moment/src/moment.js
@@ -1,12 +1,12 @@
//! moment.js
-//! version : 2.10.3
+//! version : 2.10.6
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
import { hooks as moment, setHookCallback } from './lib/utils/hooks';
-moment.version = '2.10.3';
+moment.version = '2.10.6';
import {
min,
diff --git a/docs/extending.txt b/docs/extending.txt
index 9db5344..bb94003 100644
--- a/docs/extending.txt
+++ b/docs/extending.txt
@@ -8,7 +8,7 @@
Extending Nikola
================
-:Version: 7.6.0
+:Version: 7.6.4
:Author: Roberto Alsina <ralsina@netmanagers.com.ar>
.. class:: alert alert-info pull-right
@@ -34,7 +34,9 @@ of Nikola.
Command Plugins
---------------
-When you run ``nikola --help`` you will see something like this::
+When you run ``nikola --help`` you will see something like this:
+
+.. code-block:: console
$ nikola help
Nikola is a tool to create static websites and blogs. For full documentation and more
@@ -146,7 +148,9 @@ For your own plugin, just change the values in a sensible way. The
httpd.serve_forever()
As mentioned above, a plugin can have options, which the user can see by doing
-``nikola help command`` and can later use, for example::
+``nikola help command`` and can later use, for example:
+
+.. code-block:: console
$ nikola help serve
Purpose: start the test webserver
@@ -242,6 +246,7 @@ a stub for a hypothetical system called "Templater":
template search mechanism."""
pass
+You can see a real example in `the Jinja plugin <https://github.com/getnikola/nikola/blob/master/nikola/plugins/template/jinja.py>`__
Task Plugins
------------
@@ -257,7 +262,7 @@ T
and ``TaskMultiplier`` plugins that take a task and create
more tasks out of it.
-::
+.. code-block:: console
$ nikola list
Scanning posts....done!
@@ -361,7 +366,7 @@ PageCompiler Plugins
--------------------
These plugins implement markup languages, they take sources for posts or pages and
-create HTML or other output files. A good example is the ``misaka`` plugin.
+create HTML or other output files. A good example is `the misaka plugin. <https://github.com/getnikola/plugins/tree/master/v7/misaka>`__
They must provide:
@@ -381,12 +386,27 @@ metadata contained in the file.
RestExtension Plugins
---------------------
-Implement directives for reStructuredText, see ``media.py`` for a simple example.
+Implement directives for reStructuredText, see `media.py <https://github.com/getnikola/nikola/blob/master/nikola/plugins/compile/rest/media.py>`__ for a simple example.
+
+If your output depends on a config value, you need to make your post record a dependency on a pseudo-path, like this:
+
+.. code-block:: text
+
+ ####MAGIC####CONFIG:OPTIONNAME
+
+Then, whenever the ``OPTIONNAME`` option is changed in conf.py, the file will be rebuilt.
+
+If your directive depends or may depend on the whole timeline (like the post-list directive, where adding new posts
+to the site could make it stale), you should record a dependency on the
+pseudo-path ``####MAGIC####TIMELINE``.
MarkdownExtension Plugins
-------------------------
-Implement Markdown extensions, see ``mdx_nikola.py`` for a simple example.
+Implement Markdown extensions, see `mdx_nikola.py <https://github.com/getnikola/nikola/blob/master/nikola/plugins/compile/markdown/mdx_nikola.py>`__ for a simple example.
+
+Note that python markdown extensions are often also available as separate packages. This is only meant to ship extensions
+along with Nikola.
SignalHandler Plugins
---------------------
@@ -424,13 +444,15 @@ Currently Nikola emits the following signals:
'undeployed': # all files not deployed since they are either future posts/drafts
}
+One example is the `deploy_hooks plugin. <https://github.com/getnikola/plugins/tree/master/v6/deploy_hooks>`__
+
ConfigPlugin Plugins
--------------------
Does nothing specific, can be used to modify the site object (and thus the config).
Put all the magic you want in ``set_site()``, and don’t forget to run the one
-from ``super()``.
+from ``super()``. Example plugin: `navstories <https://github.com/getnikola/plugins/tree/master/v7/navstories>`__
PostScanner Plugins
-------------------
diff --git a/docs/man/nikola.1.gz b/docs/man/nikola.1.gz
index e2425f4..db17fa8 100644
--- a/docs/man/nikola.1.gz
+++ b/docs/man/nikola.1.gz
Binary files differ
diff --git a/docs/man/nikola.rst b/docs/man/nikola.rst
index 036170d..633cb33 100644
--- a/docs/man/nikola.rst
+++ b/docs/man/nikola.rst
@@ -6,7 +6,7 @@ Nikola
A Static Site and Blog Generator
--------------------------------
-:Version: Nikola v7.6.0
+:Version: Nikola v7.6.4
:Manual section: 1
:Manual group: User Commands
@@ -94,7 +94,7 @@ The most basic commands needed to get by are:
deploy the site using the ``DEPLOY_COMMANDS`` setting
``nikola github_deploy```
deploy the site to GitHub Pages
-``nikola serve [-p PORT] [-a ADDRESS] [-b|--browser] [-6|--ipv6]``
+``nikola serve [-p PORT] [-a ADDRESS] [-d|--detach] [-b|--browser] [-6|--ipv6]``
start development web server
``nikola auto [-p PORT] [-a ADDRESS] [-b|--browser] [-6|--ipv6]``
start development web server with automated rebuilds and reloads
diff --git a/docs/manual.txt b/docs/manual.txt
index d287099..09f428a 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -3,11 +3,12 @@
.. date: 2012-03-30 23:00:00 UTC-03:00
.. link:
.. description:
+.. tags: mathjax
The Nikola Handbook
===================
-:Version: 7.6.0
+:Version: 7.6.4
.. class:: alert alert-info pull-right
@@ -17,7 +18,7 @@ The Nikola Handbook
All You Need to Know
--------------------
-After you have Nikola `installed <#installing-nikola>`_:
+After you have Nikola `installed <https://getnikola.com/getting-started.html>`_:
Create an empty site (with a setup wizard):
``nikola init mysite``
@@ -36,7 +37,7 @@ Edit the post:
Build the site:
``nikola build``
-Start the test server and open a browser (http://127.0.0.1:8000/):
+Start the test server and open a browser:
``nikola serve -b``
@@ -158,268 +159,48 @@ Lock-in
With Nikola, you own your files, and you can do anything with them.
-Features
---------
+Components
+----------
-Nikola has a very defined feature set: it has every feature I needed for my own sites.
-Hopefully, it will be enough for others, and anyway, I am open to suggestions.
+Nikola provides the following features:
-If you want to create a blog or a site, Nikola provides:
+* Blog support, including:
-* Front page (and older posts pages)
-* RSS Feeds
-* Pages and feeds for each tag you used
-* Custom search
-* Full yearly archives
+ * Indexes
+ * RSS and Atom feeds
+ * Tags and categories, with pages and feeds
+ * Archives with custom granularity (yearly or monthly)
+ * `Comments`_
+ * Client-side tag clouds (needs manual configuration)
+
+* Static pages (not part of the blog)
+* `Math`_ rendering (via MathJax)
* Custom output paths for generated pages
+* Pretty URLs (without ``.html``) that don’t need web server support
* Easy page template customization
-* Static pages (not part of the blog)
-* Internationalization support (my own blog is English/Spanish)
-* Google sitemap generation
-* Custom deployment (if it's a command, you can use it)
-* A (very) basic look and feel you can customize, and is even text-mode friendly
-* The input format is light markup (`reStructuredText <https://getnikola.com/quickstart.html>`__ or
- `Markdown <http://daringfireball.net/projects/markdown/>`_)
+* Internationalization support (my own blog is English and Spanish)
+* Sitemap generation (for search engines)
+* Custom deployment (if it’s a command, you can use it)
+* GitHub Pages deployment
+* Themes, easy appearance customization
+* `Multiple input formats <#supported-input-formats>`_, including reStructuredText and Markdown
* Easy-to-create image galleries
-* Support for displaying source code
+* Image thumbnail generation
+* Support for displaying source code listings
* Image slideshows
-* Client-side cloud tags
-
-Also:
-
-* A preview web server
-* "Live" re-rendering while you edit
-* "Smart" builds: only what changed gets rebuilt (usually in seconds)
-* Easy to extend with minimal Python knowledge.
-
-Installing Nikola
------------------
-
-This is currently lacking on detail. Considering the niche Nikola is aimed at,
-I suspect that's not a problem yet. So, when I say "get", the specific details
-of how to "get" something for your specific operating system are left to you.
-
-The short version is::
-
- pip install nikola
-
-Note that you need Python v2.7 or newer OR v3.3 or newer.
-
-Some features require **extra dependencies**. You can install them all in bulk
-by doing::
-
- pip install nikola[extras]
-
-Alternatively, you can install those packages one-by-one, when required (Nikola
-will tell you what packages are needed)
-
-After that, run ``nikola init --demo sitename`` and that will run the setup
-wizard, which will create a folder called ``sitename`` containing a functional
-demo site.
-
-Linux packages
-~~~~~~~~~~~~~~
-
-Nikola is packaged for some Linux distributions, you may get that instead of
-installing via ``pip``. Keep in mind that those packages might be
-**outdated** and that we don’t support versions that are too old. Proceed with
-care!
-
-* Arch Linux (AUR): `python-nikola`__ / `python2-nikola`__ for the
- latest stable release or `python-nikola-git`__ / `python2-nikola-git`__ for the
- GitHub master. (official Nikola-supported packages)
-* Fedora: `python-nikola`__ (incl. python3-nikola)
-* Debian and derivatives: `nikola`__
-* Gentoo: `www-apps/nikola`__
-
-__ https://aur.archlinux.org/packages/python-nikola/
-__ https://aur.archlinux.org/packages/python2-nikola/
-__ https://aur.archlinux.org/packages/python-nikola-git/
-__ https://aur.archlinux.org/packages/python2-nikola-git/
-__ https://admin.fedoraproject.org/pkgdb/package/python-nikola/
-__ https://packages.debian.org/sid/nikola
-__ https://packages.gentoo.org/package/www-apps/nikola
-
-libxml/libxslt (files missing) errors
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you get errors about various files missing while compiling ``lxml``, you must install headers for the ``libxml``, ``libxslt`` and ``zlib`` libraries, like so:
-
-Debian systems::
-
- sudo apt-get install libxml2-dev libxslt1-dev zlib1g-dev
-
-Red Hat/RPM-based systems::
-
- sudo yum install libxslt-devel libxml2-devel zlib-devel
-
-Python.h not found
-~~~~~~~~~~~~~~~~~~
-
-If you get an error to the effect of ``Python.h not found``, you need to
-install development packages for Python.
-
-Debian systems::
-
- sudo apt-get install python-dev
-
-Red Hat/RPM-based systems::
-
- sudo yum install python-devel
-
-Note that many other distros/operating systems (including Arch Linux,
-\*BSD and OS X) do not require such packages, as C headers are included
-with the base distribution of Python.
-
-Installation on Windows and Windows support
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Nikola supports Windows! Keep in mind, though, that there are some
-caveats:
-
-#. ``lxml`` and ``Pillow`` require compiled extensions. Compiling them on
- Windows is hard for most people. Fortunately, compiled packages exist.
- Check their `PyPI <https://pypi.python.org/>`_ pages to find official packages,
- `the unofficial Gohlke binaries <http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_
- site, or get them somewhere else. If you are using virtualenvs, using those
- pre-built packages is possible through ``virtualenv --system-site-packages``.
-#. Windows has some differences over POSIX, which may cause some features to
- work incorrectly under Windows. If any problems occur, please do not
- hesitate to report them. Some of the differences include:
-
- * ``\`` as path separator (instead of ``/``)
- * the concept of HDD partitions and letters (instead of
- seamless mounting under one root)
- * some characters in paths are disallowed (although this shouldn’t cause
- problems)
- * CR+LF (aka ``\r\n``) as the line separator (instead of LF ``\n``)
-
-#. Most of our developers run Linux on a daily basis and may not have the full
- knowledge required to resolve issues relating to Windows.
+* Custom search
+* Asset (CSS/JS) bundling
+* gzip compression (for sending via your web server)
+* Open Graph, Twitter Cards
+* Hyphenation
+* Custom `post processing filters`_ (eg. for minifying files or better typography)
Getting Started
---------------
-To create posts and pages in Nikola, you write them in one of the supported input formats.
-Those source files are later converted to HTML
-The recommended formats are reStructuredText and Markdown, but there is also support
-for Textile and WikiCreole and even for just writing HTML. For more details,
-read `Configuring other input formats`_.
-
-.. note:: There is a great `quick tutorial to learn reStructuredText. <https://getnikola.com/quickstart.html>`__
-
-First, let's see how you "build" your site. Nikola comes with a minimal site to get you started.
-
-The tool used to do builds is called `doit <http://pydoit.org>`__, and it rebuilds the
-files that are not up to date, so your site always reflects your latest content. To do our
-first build, just run "nikola build"::
-
- $ nikola build
- Scanning posts....done!
- . render_posts:stories/manual.html
- . render_posts:posts/1.html
- . render_posts:stories/1.html
- . render_archive:output/2012/index.html
- . render_archive:output/archive.html
- . render_indexes:output/index.html
- . render_pages:output/posts/welcome-to-nikola.html
- . render_pages:output/stories/about-nikola.html
- . render_pages:output/stories/handbook.html
- . render_rss:output/rss.xml
- . render_sources:output/stories/about-nikola.txt
- ⋮
- ⋮
- ⋮
-
-Nikola will print a line for every output file it generates. If we do it again, that
-will be much much shorter::
-
- $ nikola build
- Scanning posts....done!
-
-That is because `doit <http://pydoit.org>`__ is smart enough not to generate
-all the pages again, unless you changed something that the page requires. So, if you change
-the text of a post, or its title, that post page, and all index pages where it is mentioned,
-will be recreated. If you change the post page template, then all the post pages will be rebuilt.
+.. class:: lead
-Nikola is mostly a series of doit *tasks*, and you can see them by doing ``nikola list``::
-
- $ nikola list
- Scanning posts....done!
- build_bundles
- copy_assets
- copy_files
- deploy
- redirect
- render_archive
- render_galleries
- render_indexes
- render_listings
- render_pages
- render_posts
- render_rss
- render_site
- render_sources
- render_tags
- sitemap
-
-You can make Nikola redo everything by calling ``nikola forget`` and then ``nikola build`` (or ``nikola build -a``,
-you can make it do just a specific part of the site using task names, for example ``nikola build render_pages``,
-and even individual files like ``nikola build output/index.html``
-
-Nikola also has other commands besides ``build``::
-
- $ nikola help
- Nikola is a tool to create static websites and blogs. For full documentation and more information, please visit https://getnikola.com/
-
-
- Available commands:
- nikola auto automatically detect site changes, rebuild and optionally refresh a browser
- nikola bootswatch_theme given a swatch name from bootswatch.com and a parent theme, creates a custom theme
- nikola build run tasks
- nikola check check links and files in the generated site
- nikola clean clean action / remove targets
- nikola console start an interactive Python console with access to your site
- nikola deploy deploy the site
- nikola doit_auto automatically execute tasks when a dependency changes
- nikola dumpdb dump dependency DB
- nikola forget clear successful run status from internal DB
- nikola github_deploy deploy the site to GitHub pages
- nikola help show help
- nikola ignore ignore task (skip) on subsequent runs
- nikola import_wordpress import a WordPress dump
- nikola init create a Nikola site in the specified folder
- nikola install_theme install theme into current site
- nikola list list tasks from dodo file
- nikola new_page create a new page in the site
- nikola new_post create a new blog post or site page
- nikola orphans list all orphans
- nikola plugin manage plugins
- nikola serve start the test webserver
- nikola strace use strace to list file_deps and targets
- nikola tabcompletion generate script for tab-completion
- nikola version print the Nikola version number
-
- nikola help show help / reference
- nikola help <command> show command usage
- nikola help <task-name> show task usage
-
-The ``serve`` command starts a web server so you can see the site you are creating::
-
- $ nikola serve -b
- Serving HTTP on 127.0.0.1 port 8000 ...
-
-
-After you do this, a web browser opens at http://127.0.0.1:8000/ and you should see
-the sample site. This is useful as a "preview" of your work.
-
-By default, the ``serve`` command runs the web server on port 8000 on the IP address 127.0.0.1.
-You can pass in an IP address and port number explicitly using ``-a IP_ADDRESS``
-(short version of ``--address``) or ``-p PORT_NUMBER`` (short version of ``--port``)
-Example usage::
-
- $ nikola serve --address 0.0.0.0 --port 8080
- Serving HTTP on 0.0.0.0 port 8080 ...
+To set Nikola up and create your first site, read the `Getting Started Guide <https://getnikola.com/getting-started.html>`_.
Creating a Blog Post
--------------------
@@ -435,25 +216,35 @@ easier to keep it in a single location.
The contents of your post have to be written (by default) in `reStructuredText <http://docutils.sf.net>`__
but you can use a lot of different markups using the ``-f`` option.
-Currently Nikola supports reStructuredText, Markdown, IPython Notebooks, HTML as input,
+Currently, Nikola supports reStructuredText, Markdown, IPython (Jupyter) Notebooks, HTML as input,
can also use Pandoc for conversion, and has support for BBCode, CreoleWiki, txt2tags, Textile
-and more via `plugins <https://plugins.getnikola.com>`__.
-For more details, read `Configuring other input formats`_.
+and more via plugins — for more details, read the `input format documentation
+<#multiple-input-formats>`__.
+You can learn reStructuredText syntax with the `reST quickstart <https://getnikola.com/quickstart.html>`__.
+
+Please note that Nikola does not guarantee support for encodings other than
+UTF-8. We recommend converting your input files to that encoding. It will
+prevent bugs, and Nikola will write UTF-8 output anyway.
You can control what markup compiler is used for each file extension with the ``COMPILERS``
option. The default configuration expects them to be placed in ``posts`` but that can be
changed (see below, the ``POSTS`` and ``PAGES`` options)
-This is how it works::
+This is how it works:
+
+.. code:: console
$ nikola new_post
Creating New Post
-----------------
- Enter title: How to make money
- Your post's text is at: posts/how-to-make-money.txt
+ Title: How to make money
+ Scanning posts....done!
+ INFO: new_post: Your post's text is at: posts/how-to-make-money.rst
-The content of that file is as follows::
+The content of that file is as follows:
+
+.. code:: restructuredtext
.. title: How to make money
.. slug: how-to-make-money
@@ -481,7 +272,9 @@ supports them (for example: ``.. author: John Doe``)
To add these metadata fields to all new posts by default, you can set the
variable ``ADDITIONAL_METADATA`` in your configuration. For example, you can
add the author metadata to all new posts by default, by adding the following
-to your configuration::
+to your configuration:
+
+.. code:: python
ADDITIONAL_METADATA = {
'author': 'John Doe'
@@ -492,63 +285,70 @@ to your configuration::
Nikola will also use other metadata fields:
author
- Author of the post, will be used in the RSS feed and possibly in the post
- display (theme-dependent)
+ Author of the post, will be used in the RSS feed and possibly in the post
+ display (theme-dependent)
annotations / noannotations
- Override the value of the ``ANNOTATIONS`` option for this specific post or page.
+ Override the value of the ``ANNOTATIONS`` option for this specific post or page.
category
- Like tags, except each post can have only one, and they usually have
- more descriptive names.
+ Like tags, except each post can have only one, and they usually have
+ more descriptive names.
filters
- See the `Post Processing Filters`_ section.
+ See the `Post Processing Filters`_ section.
hidetitle
- Set "True" if you do not want to see the **page** title as a
- heading of the output html file (does not work for posts).
+ Set "True" if you do not want to see the **page** title as a
+ heading of the output html file (does not work for posts).
nocomments
- Set to "True" to disable comments. Example::
+ Set to "True" to disable comments. Example:
+
+ .. code:: restructuredtext
- .. nocomments: True
+ .. nocomments: True
password
- The post will be encrypted and invisible until the reader enters the password.
- Also, the post's sourcecode will not be available.
+ The post will be encrypted and invisible until the reader enters the password.
+ Also, the post's sourcecode will not be available.
- WARNING: **DO NOT** use for real confidential data. The algorithm used (RC4) is insecure. The implementation may also be easily brute-forced. Please consider using something else if you need *real* encryption!
+ WARNING: **DO NOT** use for real confidential data. The algorithm used (RC4) is insecure. The implementation may also be easily brute-forced. Please consider using something else if you need *real* encryption!
- More information: `Issue #1547 <https://github.com/getnikola/nikola/issues/1547>`_
+ More information: `Issue #1547 <https://github.com/getnikola/nikola/issues/1547>`_
previewimage
- Designate a preview or other representative image path relative to BASE_URL
- for use with Open Graph for posts. Adds the image when sharing on social
- media and many other uses.
+ Designate a preview or other representative image path relative to BASE_URL
+ for use with Open Graph for posts. Adds the image when sharing on social
+ media and many other uses.
- .. previewimage: images/looks_great_on_facebook.png
+ .. code:: restructuredtext
- The image can be of any size and dimension (services will crop and adapt)
- but should less than 1 MB and be larger than 300x300 (ideally 600x600).
+ .. previewimage: images/looks_great_on_facebook.png
+
+ The image can be of any size and dimension (services will crop and adapt)
+ but should less than 1 MB and be larger than 300x300 (ideally 600x600).
template
- Will change the template used to render this page/post specific page. Example::
+ Change the template used to render this page/post specific page. That
+ template needs to either be part of the theme, or be placed in a
+ ``templates/`` folder inside your site.
- .. template: story.tmpl
+ .. code:: restructuredtext
- That template needs to either be part of the theme, or be placed in a ``templates/``
- folder inside your site.
+ .. template: story.tmpl
- enclosure
- Add an enclosure to this post when it's used in RSS. See `more information about enclosures <http://en.wikipedia.org/wiki/RSS_enclosure>`__
+ enclosure
+ Add an enclosure to this post when it's used in RSS. See `more information about enclosures <http://en.wikipedia.org/wiki/RSS_enclosure>`__
.. note:: The Two-File Format
Nikola originally used a separate ``.meta`` file. That will still work!
The format of the meta files is the same as shown above (i.e. only
the 7 base fields, in the order listed above), but without the
- explanations::
+ explanations:
+
+ .. code:: text
How to make money
how-to-make-money
@@ -558,9 +358,11 @@ to your configuration::
all metadata you want, complete with the explanations — they look just like
the beginning of our reST files.
- .. title: How to make money
- .. slug: how-to-make-money
- .. date: 2012-09-15 19:52:05 UTC
+ .. code:: restructuredtext
+
+ .. title: How to make money
+ .. slug: how-to-make-money
+ .. date: 2012-09-15 19:52:05 UTC
Both file formats are supported; however, the new format is preferred, if
possible.
@@ -578,7 +380,9 @@ TRANSLATIONS_PATTERN variable in your configuration file.
The default is to put the language code before the file extension,
so the German translation of ``some_file.rst`` should be named
``some_file.de.rst``. This is because the TRANSLATIONS_PATTERN variable is by
-default set to::
+default set to:
+
+.. code:: python
TRANSLATIONS_PATTERN = "{path}.{lang}.{ext}"
@@ -588,46 +392,18 @@ default set to::
specified in the TRANSLATIONS variable.
You can edit these files with your favourite text editor, and once you are happy
-with the contents, generate the pages as explained in `Getting Started`_
-
-Currently supported languages are:
-
-* Basque
-* Bulgarian
-* Catalan
-* Chinese (Simplified)
-* Croatian
-* Czech
-* Dutch
-* English
-* Esperanto
-* Estonian
-* Finnish
-* French
-* German
-* Greek
-* Hindi
-* Italian
-* Japanese
-* Norwegian Bokmål
-* Persian
-* Polish
-* Portuguese (Brasil)
-* Russian
-* Slovak
-* Slovene
-* Spanish
-* Turkish
-* Urdu
-
-If you wish to add support for more languages, check out the instructions
-at the `theming guide <https://getnikola.com/theming.html>`_.
+with the contents, generate the pages using ``nikola build``.
+
+Nikola supports multiple languages for a post (we have almost 40 translations!). If you wish to
+add support for more languages, check out `the Transifex page for Nikola <https://www.transifex.com/projects/p/nikola/>`_
The post page is generated using the ``post.tmpl`` template, which you can use
to customize the output.
The place where the post will be placed by ``new_post`` is based on the ``POSTS``
-and ``PAGES`` configuration options::
+and ``PAGES`` configuration options:
+
+.. code:: python
# POSTS and PAGES contains (wildcard, destination, template) tuples.
#
@@ -668,19 +444,26 @@ supplied) that ends with the extension of your desired markup format (as
defined in ``COMPILERS`` in ``conf.py``) as the directory that the new post will be
written into. If no such entry can be found, the post won’t be created.
-The ``new_post`` command supports some options::
+The ``new_post`` command supports some options:
+
+.. code:: text
$ nikola help new_post
- Purpose: Create a new blog post or site page.
+ Purpose: create a new blog post or site page
Usage: nikola new_post [options] [path]
Options:
- -p, --page Create a page instead of a blog post.
- -t ARG, --title=ARG Title for the page/post.
- --tags=ARG Comma-separated tags for the page/post.
- -1 Create post with embedded metadata (single file format)
- -2 Create post with separate metadata (two file format)
- -f ARG, --format=ARG Markup format for post, one of rest, markdown, wiki, bbcode, html, textile, txt2tags
+ -p, --page Create a page instead of a blog post. (see also: `nikola new_page`)
+ -t ARG, --title=ARG Title for the post.
+ -a ARG, --author=ARG Author of the post.
+ --tags=ARG Comma-separated tags for the post.
+ -1 Create the post with embedded metadata (single file format)
+ -2 Create the post with separate metadata (two file format)
+ -e Open the post (and meta file, if any) in $EDITOR after creation.
+ -f ARG, --format=ARG Markup format for the post (use --available-formats for list)
+ -F, --available-formats List all available input formats
+ -s Schedule the post based on recurrence rule
+ -i ARG, --import=ARG Import an existing file instead of creating a placeholder
The optional ``path`` parameter tells nikola exactly where to put it instead of guessing from your config.
So, if you do ``nikola new_post posts/random/foo.txt`` you will have a post in that path, with
@@ -694,11 +477,15 @@ index page or in RSS feeds, but to display instead only the beginning of them.
If it's the case, you only need to add a "magical comment" in your post.
-In reStructuredText::
+In reStructuredText:
+
+.. code:: restructuredtext
.. TEASER_END
-In Markdown (or basically, the resulting HTML of any format)::
+In Markdown (or basically, the resulting HTML of any format):
+
+.. code:: html
<!-- TEASER_END -->
@@ -709,11 +496,24 @@ page should display the whole contents or only teasers. ``RSS_TEASERS``
works the same way for your RSS feeds.
By default, teasers will include a "read more" link at the end. If you want to
-change that text, you can use a custom teaser::
+change that text, you can use a custom teaser:
+
+.. code:: restructuredtext
.. TEASER_END: click to read the rest of the article
-Or you can completely customize the link using the ``READ_MORE_LINK`` option::
+You can override the default value for ``TEASER_END`` in ``conf.py`` — for
+example, the following example will work for ``.. more``, and will be
+compatible with both WordPress and Nikola posts:
+
+..code:: python
+
+ import re
+ TEASER_REGEXP = re.compile('<!--\s*(more|TEASER_END)(:(.+))?\s*-->', re.IGNORECASE)
+
+Or you can completely customize the link using the ``READ_MORE_LINK`` option.
+
+.. code:: python
# A HTML fragment with the Read more... link.
# The following tags exist and are replaced for you:
@@ -741,8 +541,8 @@ published immediately. Posts dated in the future are *not* deployed by default
deployed site, you can set ``DEPLOY_FUTURE = True`` in your configuration.
Generally, you want FUTURE_IS_NOW and DEPLOY_FUTURE to be the same value.
-Private (formerly retired) Posts
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Private Posts
+~~~~~~~~~~~~~
If you add a "private" tag to a post, then it will not be shown in indexes and feeds.
It *will* be compiled, and if you deploy it it *will* be made available, so it will
@@ -763,7 +563,9 @@ requires that the ``FUTURE_IS_NOW`` setting is set to ``False``)
For example, if you would like to schedule your posts to be on every
Monday, Wednesday and Friday at 7am, add the following
-``SCHEDULE_RULE`` to your configuration ::
+``SCHEDULE_RULE`` to your configuration:
+
+.. code:: python
SCHEDULE_RULE = 'RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR;BYHOUR=7;BYMINUTE=0;BYSECOND=0'
@@ -773,7 +575,9 @@ For more details on how to specify a recurrence rule, look at the
Say, you get a free Sunday, and want to write a flurry of new posts,
or at least posts for the rest of the week, you would run the
``new_post`` command with the ``--schedule`` flag, as many times as
-you want::
+you want:
+
+.. code:: console
$ nikola new_post --schedule
# Creates a new post to be posted on Monday, 7am.
@@ -797,6 +601,8 @@ types affect the look of your posts, by adding a ``post-YOURINPUTHERE``
CSS class to the post. Each post can have one and exactly one type. Nikola
styles the following types in the default themes:
+.. class:: table table-bordered
+
+-----------------+----------------------------+------------------+
| Name(s) | Description | Styling |
+=================+============================+==================+
@@ -805,6 +611,95 @@ styles the following types in the default themes:
| micro | “small” (short) posts | big serif font |
+-----------------+----------------------------+------------------+
+Indexes
+~~~~~~~
+
+All your posts that are not drafts, private or dated in the future, will be
+shown in indexes.
+
+Settings
+````````
+
+Indexes are put in the ``INDEX_PATH`` directory, which defaults to an empty
+string (site root). The “main” index is ``index.html``, and all the further
+indexes are ``index-*.html``, respectively.
+
+By default, 10 posts are displayed on an index page. This can be changed with
+``INDEX_DISPLAY_POST_COUNT``. Indexes can show full posts or just the teasers,
+as controlled by the ``INDEX_TEASERS`` setting (defaults to ``False``).
+
+Titles of the pages can be controlled by using ``INDEXES_TITLES``,
+``INDEXES_PAGES`` and ``INDEXES_PAGES_MAIN`` settings.
+
+Categories and tags use simple lists by default that show only titles and
+dates; however, you can switch them to full indexes by using
+``CATEGORY_PAGES_ARE_INDEXES`` and ``TAG_PAGES_ARE_INDEXES``, respectively.
+
+Static indexes
+``````````````
+
+Nikola uses *static indexes* by default. This means that ``index-1.html`` has
+the oldest posts, and the newest posts past the first 10 are in
+``index-N.html``, where ``N`` is the highest number. Only the page with the
+highest number and the main page (``index-N.html`` and ``index.html``) are
+rebuilt (the others remain unchanged). The page that appears when you click
+*Older posts* on the index page, ``index-N.html``, might contain **less than 10
+posts** if there are not enough posts to fill up all pages.
+
+This can be disabled by setting ``INDEXES_STATIC`` to ``False``. In that mode,
+``index-1.html`` contains all the newest posts past the first 10 and will
+always contain 10 posts (unless you have less than 20). The last page,
+``index-N.html``, contains the oldest posts, and might contain less than 10
+posts. This is how many blog engines and CMSes behave. Note that this will
+lead to rebuilding all index pages, which might be a problem for larger blogs
+(with a lot of index pages).
+
+Creating a Page
+---------------
+
+Pages are the same as posts, except that:
+
+* They are not added to the front page
+* They don't appear on the RSS feed
+* They use the ``story.tmpl`` template instead of ``post.tmpl`` by default
+
+The default configuration expects the page's metadata and text files to be on the
+``stories`` folder, but that can be changed (see ``PAGES`` option above).
+
+You can create the page's files manually or use the ``new_post`` command
+with the ``-p`` option, which will place the files in the folder that
+has ``use_in_feed`` set to False.
+
+Supported input formats
+-----------------------
+
+Nikola supports multiple input formats. Out of the box, we have compilers available for:
+
+* reStructuredText (default and pre-configured)
+* `Markdown`_
+* `IPython Notebook/Jupyter`_
+* `HTML`_
+* `PHP`_
+* anything `Pandoc`_ supports (including Textile, DocBook, LaTeX, MediaWiki,
+ TWiki, OPML, Emacs Org-Mode, txt2tags, Microsoft Word .docx, EPUB, Haddock markup)
+
+Plus, we have specialized compilers in the Plugins Index for:
+
+* `AsciiDoc <https://plugins.getnikola.com/#asciidoc>`_
+* `BBCode <https://plugins.getnikola.com/#bbcode>`_
+* `CommonMark <https://plugins.getnikola.com/#commonmark>`_
+* `IRC logs <https://plugins.getnikola.com/#irclogs>`_
+* `Markmin <https://plugins.getnikola.com/#markmin>`_
+* `MediaWiki (smc.mw) <https://plugins.getnikola.com/#mediawiki>`_
+* `Misaka <https://plugins.getnikola.com/#misaka>`_
+* `ODT <https://plugins.getnikola.com/#odt>`_
+* `Emacs Org-Mode <https://plugins.getnikola.com/#orgmode>`_
+* `reST with HTML 5 output <https://plugins.getnikola.com/#rest_html5>`_
+* `Textile <https://plugins.getnikola.com/#textile>`_
+* `txt2tags <https://plugins.getnikola.com/#txt2tags>`_
+* `CreoleWiki <https://plugins.getnikola.com/#wiki>`_
+* `WordPress posts <https://plugins.getnikola.com/#wordpress_compiler>`_
+
Configuring other input formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -876,70 +771,13 @@ Using Pandoc for reStructuredText, Markdown and other input formats that have a
standalone Nikola plugin is **not recommended** as it disables plugins and
extensions that are usually provided by Nikola.
-Indexes
-~~~~~~~
-
-All your posts that are not drafts, private or dated in the future, will be
-shown in indexes.
-
-Settings
-````````
-
-Indexes are put in the ``INDEX_PATH`` directory, which defaults to an empty
-string (site root). The “main” index is ``index.html``, and all the further
-indexes are ``index-*.html``, respectively.
-
-By default, 10 posts are displayed on an index page. This can be changed with
-``INDEX_DISPLAY_POST_COUNT``. Indexes can show full posts or just the teasers,
-as controlled by the ``INDEX_TEASERS`` setting (defaults to ``False``).
-
-Titles of the pages can be controlled by using ``INDEXES_TITLES``,
-``INDEXES_PAGES`` and ``INDEXES_PAGES_MAIN`` settings.
-
-Categories and tags use simple lists by default that show only titles and
-dates; however, you can switch them to full indexes by using
-``CATEGORY_PAGES_ARE_INDEXES`` and ``TAG_PAGES_ARE_INDEXES``, respectively.
-
-Static indexes
-``````````````
-
-Nikola uses *static indexes* by default. This means that ``index-1.html`` has
-the oldest posts, and the newest posts past the first 10 are in
-``index-N.html``, where ``N`` is the highest number. Only the page with the
-highest number and the main page (``index-N.html`` and ``index.html``) are
-rebuilt (the others remain unchanged). The page that appears when you click
-*Older posts* on the index page, ``index-N.html``, might contain **less than 10
-posts** if there are not enough posts to fill up all pages.
-
-This can be disabled by setting ``INDEXES_STATIC`` to ``False``. In that mode,
-``index-1.html`` contains all the newest posts past the first 10 and will
-always contain 10 posts (unless you have less than 20). The last page,
-``index-N.html``, contains the oldest posts, and might contain less than 10
-posts. This is how many blog engines and CMSes behave. Note that this will
-lead to rebuilding all index pages, which might be a problem for larger blogs
-(with a lot of index pages).
-
-Creating a Page
----------------
-
-Pages are the same as posts, except that:
-
-* They are not added to the front page
-* They don't appear on the RSS feed
-* They use the ``story.tmpl`` template instead of ``post.tmpl`` by default
-
-The default configuration expects the page's metadata and text files to be on the
-``stories`` folder, but that can be changed (see ``PAGES`` option above).
-
-You can create the page's files manually or use the ``new_post`` command
-with the ``-p`` option, which will place the files in the folder that
-has ``use_in_feed`` set to False.
-
Redirections
------------
If you need a page to be available in more than one place, you can define redirections
-in your ``conf.py``::
+in your ``conf.py``:
+
+.. code:: python
# A list of redirection tuples, [("foo/from.html", "/bar/to.html")].
#
@@ -964,7 +802,9 @@ still should not be terribly hard to grasp.
The default ``conf.py`` you get with Nikola should be fairly complete, and is quite
commented.
-You surely want to edit these options::
+You surely want to edit these options:
+
+.. code:: python
# Data about this site
BLOG_AUTHOR = "Your Name" # (translatable)
@@ -976,13 +816,13 @@ You surely want to edit these options::
Some options are demarked with a (translatable) comment above or right next to
them. For those options, two types of values can be provided:
- * a string, which will be used for all languages
- * a dict of language-value pairs, to have different values in each language
+* a string, which will be used for all languages
+* a dict of language-value pairs, to have different values in each language
.. note:: It is possible to load the configuration from another file by specifying
``--conf=path/to/other.file`` on Nikola's command line. For example, to
- build your blog using the configuration file ``configurations/test.config``,
- you have to execute ``nikola build --conf=configurations/test.config``.
+ build your blog using the configuration file ``configurations/test.conf.py``,
+ you have to execute ``nikola build --conf=configurations/test.conf.py``.
Customizing Your Site
---------------------
@@ -1024,7 +864,9 @@ Navigation Links
1. A (url, text) tuple, describing a link
2. A (((url, text), (url, text), (url, text)), title) tuple, describing a submenu / sublist.
- Example::
+ Example:
+
+ .. code:: python
NAVIGATION_LINKS = {
DEFAULT_LANG: (
@@ -1038,20 +880,16 @@ Navigation Links
.. note::
- Support for submenus is theme-dependent. Only one level of
- submenus is supported.
-
- .. note::
+ 1. Support for submenus is theme-dependent. Only one level of
+ submenus is supported.
- Some themes, including the default Bootstrap 3 theme, may
- present issues if the menu is too large. (in ``bootstrap3``, the
- navbar can grow too large and cover contents.)
-
- .. note::
+ 2. Some themes, including the default Bootstrap 3 theme, may
+ present issues if the menu is too large. (in ``bootstrap3``, the
+ navbar can grow too large and cover contents.)
- If you link to directories, make sure to follow ``STRIP_INDEXES``. If
- it’s set to ``True``, end your links with a ``/``, otherwise end them
- with ``/index.html`` — or else they won’t be hilighted when active.
+ 3. If you link to directories, make sure to follow ``STRIP_INDEXES``. If
+ it’s set to ``True``, end your links with a ``/``, otherwise end them
+ with ``/index.html`` — or else they won’t be hilighted when active.
The ``SEARCH_FORM`` option contains the HTML code for a search form based on
duckduckgo.com which should always work, but feel free to change it to
@@ -1138,11 +976,13 @@ with files Nikola generates (it will give an error).
.. admonition:: Important
- Don't put any files manually in ``output/``. Ever. Really. Maybe someday Nikola
- will just wipe ``output/`` and then you will be sorry. So, please don't do that.
+ Don't put any files manually in ``output/``. Ever. Really.
+ Maybe someday Nikola will just wipe ``output/`` (when you run ``nikola check -f --clean-files``) and then you will be sorry. So, please don't do that.
If you want to copy more than one folder of static files into ``output`` you can
-change the FILES_FOLDERS option::
+change the FILES_FOLDERS option:
+
+.. code:: python
# One or more folders containing files to be copied as-is into the output.
# The format is a dictionary of "source" "relative destination".
@@ -1155,7 +995,10 @@ Getting More Themes
There are a few themes for Nikola. They are available at
the `Themes Index <https://themes.getnikola.com/>`_.
-Nikola has a built-in theme download/install mechanism to install those themes — the ``install_theme`` command::
+Nikola has a built-in theme download/install mechanism to install those themes — the ``install_theme`` command:
+
+
+.. code:: console
$ nikola install_theme -l
Themes:
@@ -1178,7 +1021,10 @@ request in the `GitHub repository <https://github.com/getnikola/nikola-themes>`
One other option is to tweak an existing theme using a different color scheme,
typography and CSS in general. Nikola provides a ``bootswatch_theme`` option
-to create a custom theme by downloading free CSS files from http://bootswatch.com::
+to create a custom theme by downloading free CSS files from http://bootswatch.com:
+
+
+.. code:: console
$ nikola bootswatch_theme -n custom_theme -s spruce -p bootstrap3
[2013-10-12T16:46:58Z] NOTICE: bootswatch_theme: Creating 'custom_theme' theme
@@ -1208,7 +1054,9 @@ you want to run (eg. ``nikola deploy default``, multiple presets are allowed).
One caveat is that if any command has a % in it, you should double them.
-Here is an example, from my own site's deployment script::
+Here is an example, from my own site's deployment script:
+
+.. code:: python
DEPLOY_COMMANDS = {'default': [
'rsync -rav --delete output/ ralsina@lateral.netmanagers.com.ar:/srv/www/lateral',
@@ -1294,7 +1142,9 @@ I recommend 3rd party comments, and specially DISQUS because:
3) It's free.
4) It's damn nice.
-You can disable comments for a post by adding a "nocomments" metadata field to it::
+You can disable comments for a post by adding a "nocomments" metadata field to it:
+
+.. code:: restructuredtext
.. nocomments: True
@@ -1358,7 +1208,9 @@ then be copied directly to the corresponding path in the ``output`` directory, s
can reference it from whatever page you like, most easily using the ``thumbnail``
reST extension. If you don't want thumbnails, just use the ``files`` folder instead.
-The ``conf.py`` options affecting images and gallery pages are these::
+The ``conf.py`` options affecting images and gallery pages are these:
+
+.. code:: python
# One or more folders containing galleries. The format is a dictionary of
# {"source": "relative_destination"}, where galleries are looked for in
@@ -1405,7 +1257,9 @@ You can apply post processing to the files in your site, in order to optimize th
or change them in arbitrary ways. For example, you may want to compress all CSS
and JS files using yui-compressor.
-To do that, you can use the provided helper adding this in your ``conf.py``::
+To do that, you can use the provided helper adding this in your ``conf.py``:
+
+.. code:: python
from nikola import filters
@@ -1493,9 +1347,11 @@ jpegoptim
Compress JPEG files using `jpegoptim <http://www.kokkonen.net/tjko/projects.html>`_
-You can apply filters to specific posts or pages by using the ``filters`` metadata field::
+You can apply filters to specific posts or pages by using the ``filters`` metadata field:
+
+.. code:: restructuredtext
- .. filters:: filters.html_tidy_nowrap, "sed s/foo/bar"
+ .. filters: filters.html_tidy_nowrap, "sed s/foo/bar"
@@ -1509,11 +1365,15 @@ different ones, or about other web servers, please share!
#. Use a speed testing tool. I used Yahoo's YSlow but you can use any of them, and
it's probably a good idea to use more than one.
-#. Enable compression in Apache::
+#. Enable compression in Apache:
+
+ .. code:: apache
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
-#. If even after you did the previous step the CSS files are not sent compressed::
+#. If even after you did the previous step the CSS files are not sent compressed:
+
+ .. code:: apache
AddType text/css .css
@@ -1541,7 +1401,6 @@ like this:
.. code:: python
- """
MATHJAX_CONFIG = """
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
@@ -1568,7 +1427,9 @@ In reST:
Euler’s formula: :math:`e^{ix} = \cos x + i\sin x`
-In other input formats::
+In other input formats:
+
+.. code:: text
Euler’s formula: \(e^{ix} = \cos x + i\sin x\)
@@ -1581,7 +1442,7 @@ Display mathematics are produced using the reST `math` **directive** or the ``\[
In reST:
-::
+.. code:: restructuredtext
.. math::
@@ -1589,7 +1450,7 @@ In reST:
In other input formats:
-::
+.. code:: text
\[\int \frac{dx}{1+ax}=\frac{1}{a}\ln(1+ax)+C\]
@@ -1610,7 +1471,9 @@ Media
~~~~~
This directive lets you embed media from a variety of sites automatically by just passing the
-URL of the page. For example here are two random videos::
+URL of the page. For example here are two random videos:
+
+.. code:: restructuredtext
.. media:: http://vimeo.com/72425090
@@ -1625,7 +1488,9 @@ To link to a YouTube video, you need the id of the video. For example, if the
URL of the video is http://www.youtube.com/watch?v=8N_tupPBtWQ what you need is
**8N_tupPBtWQ**
-Once you have that, all you need to do is::
+Once you have that, all you need to do is:
+
+.. code:: restructuredtext
.. youtube:: 8N_tupPBtWQ
@@ -1635,13 +1500,17 @@ Vimeo
To link to a Vimeo video, you need the id of the video. For example, if the
URL of the video is http://www.vimeo.com/20241459 then the id is **20241459**
-Once you have that, all you need to do is::
+Once you have that, all you need to do is:
+
+.. code:: restructuredtext
.. vimeo:: 20241459
If you have internet connectivity when generating your site, the height and width of
the embedded player will be set to the native height and width of the video.
-You can override this if you wish::
+You can override this if you wish:
+
+.. code:: restructuredtext
.. vimeo:: 20241459
:height: 240
@@ -1652,11 +1521,15 @@ Soundcloud
This directive lets you share music from http://soundcloud.com You first need to get the
ID for the piece, which you can find in the "share" link. For example, if the
-WordPress code starts like this::
+WordPress code starts like this:
+
+.. code:: text
[soundcloud url="http://api.soundcloud.com/tracks/78131362"
-The ID is 78131362 and you can embed the audio with this::
+The ID is 78131362 and you can embed the audio with this:
+
+.. code:: restructuredtext
.. soundcloud:: 78131362
@@ -1669,7 +1542,9 @@ Code
The ``code`` directive has been included in docutils since version 0.9 and now
replaces Nikola's ``code-block`` directive. To ease the transition, two aliases
-for ``code`` directive are provided: ``code-block`` and ``sourcecode``::
+for ``code`` directive are provided: ``code-block`` and ``sourcecode``:
+
+.. code:: restructuredtext
.. code-block:: python
:number-lines:
@@ -1681,7 +1556,9 @@ Listing
To use this, you have to put your source code files inside ``listings`` or whatever folders
your ``LISTINGS_FOLDERS`` variable is set to fetch files from. Assuming you have a ``foo.py``
-inside one of these folders::
+inside one of these folders:
+
+.. code:: restructuredtext
.. listing:: foo.py python
@@ -1713,7 +1590,9 @@ __ http://docutils.sourceforge.net/docs/ref/rst/directives.html#including-an-ext
Gist
~~~~
-You can easily embed GitHub gists with this directive, like this::
+You can easily embed GitHub gists with this directive, like this:
+
+.. code:: restructuredtext
.. gist:: 2395294
@@ -1727,7 +1606,9 @@ Thumbnails
~~~~~~~~~~
To include an image placed in the ``images`` folder (or other folders defined in ``IMAGE_FOLDERS``), use the
-``thumbnail`` directive, like this::
+``thumbnail`` directive, like this:
+
+.. code:: restructuredtext
.. thumbnail:: ../tesla.jpg
@@ -1740,7 +1621,9 @@ the reST `image <http://docutils.sourceforge.net/docs/ref/rst/directives.html#im
directive are supported (except ``target``). If a body element is provided, the
thumbnail will mimic the behavior of the
`figure <http://docutils.sourceforge.net/docs/ref/rst/directives.html#figure>`_
-directive instead::
+directive instead:
+
+.. code:: restructuredtext
.. thumbnail:: ../tesla.jpg
@@ -1749,7 +1632,9 @@ directive instead::
Slideshows
~~~~~~~~~~
-To create an image slideshow, you can use the ``slides`` directive. For example::
+To create an image slideshow, you can use the ``slides`` directive. For example:
+
+.. code:: restructuredtext
.. slides::
@@ -1765,7 +1650,9 @@ Chart
This directive is a thin wrapper around `Pygal <http://pygal.org/>`_ and will produce charts
as SVG files embedded directly in your pages.
-Here's an example of how it works::
+Here's an example of how it works:
+
+.. code:: restructuredtext
.. chart:: Bar
:title: 'Browser usage evolution (in %)'
@@ -1791,7 +1678,9 @@ Doc
This role is useful to make links to other post or page inside the same site.
-Here's an example::
+Here's an example:
+
+.. code:: restructuredtext
Take a look at :doc:`my other post <creating-a-theme>` about theme creating.
@@ -1799,7 +1688,9 @@ In this case we are giving the portion of text we want to link. So, the result w
Take a look at :doc:`my other post <creating-a-theme>` about theme creating.
-If we want to use the post's title as the link's text, just do::
+If we want to use the post's title as the link's text, just do:
+
+.. code:: restructuredtext
Take a look at :doc:`creating-a-theme` to know how to do it.
@@ -1822,7 +1713,9 @@ Post List
This directive can be used to generate a list of posts. You could use it, for
example, to make a list of the latest 5 blog posts, or a list of all blog posts
-with the tag ``nikola``::
+with the tag ``nikola``:
+
+.. code:: restructuredtext
Here are my 5 latest and greatest blog posts:
@@ -1858,7 +1751,10 @@ The following options are recognized:
* ``tags`` : string [, string...]
Filter posts to show only posts having at least one of the ``tags``.
+ Defaults to None.
+* ``categories`` : string [, string...]
+ Filter posts to show only posts having one of the ``categories``.
Defaults to None.
* ``slugs`` : string [, string...]
@@ -1892,36 +1788,69 @@ the appropriate path if this happens.
We recommend using stories with dates in the past (1970-01-01) to avoid
dependency issues.
-Importing Your WordPress Site Into Nikola
+Importing your WordPress site into Nikola
-----------------------------------------
If you like Nikola, and want to start using it, but you have a WordPress blog, Nikola
-supports importing it. Here's the steps to do it:
+supports importing it. Here are the steps to do it:
-1) Get a XML dump of your site [#]_
-2) nikola import_wordpress mysite.wordpress.2012-12-20.xml
+1. Get an XML dump of your site [#]_
+2. ``nikola import_wordpress mysite.wordpress.2012-12-20.xml``
After some time, this will create a ``new_site`` folder with all your data. It currently supports
the following:
* All your posts and pages
-* Keeps "draft" status
+* Keeps “draft” status
* Your tags and categories
* Imports your attachments and fixes links to point to the right places
* Will try to add redirects that send the old post URLs to the new ones
-* Will give you a url_map so you know where each old post was
+* Will give you a URL map so you know where each old post was
+
+ This is also useful for DISQUS thread migration, or server-based 301
+ redirects!
+
+* Allows you to export your comments with each post
+* Exports information on attachments per post
+* There are different methods to transfer the content of your posts:
+
+ - You can convert them to HTML with the WordPress page compiler plugin
+ for Nikola. This will format the posts including supported shortcodes
+ the same way as WordPress does. Use the ``--transform-to-html`` option
+ to convert your posts to HTML.
+
+ If you use this option, you do not need to install the plugin
+ permanently. You can ask Nikola to install the plugin into the subdirectory
+ ``plugins`` of the current working directory by specifying
+ the ``--install-wordpress-compiler`` option.
+
+ - You can leave the posts the way they are and use the WordPress page
+ compiler plugin to render them when building your new blog. This also
+ allows you to create new posts using the WordPress syntax, or to manually
+ add more shortcode plugins later. Use the ``--use-wordpress-compiler``
+ option to not touch your posts.
- This is also useful for DISQUS thread migration!
+ If you want to use this option, you have to install the plugin permanently.
+ You can ask Nikola to install the plugin into your new site by specifying
+ the ``--install-wordpress-compiler`` option.
-* Will try to convert the content of your posts. This is *not* error free, because
- WordPress uses some unholy mix of HTML and strange things. Currently we are treating it
- as markdown, which does a reasonable job of it.
+ - You can let Nikola convert your posts to Markdown. This is *not* error
+ free, because WordPress uses some unholy mix of HTML and strange things.
+ This is the default option and requires no plugins.
- You will find your old posts in ``new_site/posts/post-title.wp`` in case you need to fix
- any of them.
+ You will find your old posts in ``new_site/posts/post-title.html`` in the first case,
+ ``new_site/posts/post-title.wp`` in the second case or ``new_site/posts/post-title.md``
+ in the last case if you need to edit or fix any of them.
+
+ Please note that the page compiler currently only supports the ``[code]`` shortcode,
+ but other shortcodes can be supported via plugins.
+
+ Also note that the WordPress page compiler is licensed under GPL v2 since
+ it uses code from WordPress itself, while Nikola is licensed under the more
+ liberal MIT license.
This feature is a work in progress, and the only way to improve it is to have it used for
-as many sites as possible and make it work better each time, so I am happy to get requests
+as many sites as possible and make it work better each time, so we are happy to get requests
about it.
.. [#] The dump needs to be in 1.2 format. You can check by reading it, it should say
@@ -1931,13 +1860,15 @@ about it.
Other versions may or may not work.
-Importing To A Custom Location Or Into An Existing Site
+Importing to a custom location or into an existing site
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is possible to either import into a location you desire or into an already existing Nikola site.
-To do so you can specify a location after the dump.::
+To do so you can specify a location after the dump:
- $ nikola import_wordpress mysite.wordpress.2012-12-20.xml -o import_location
+.. code:: console
+
+ $ nikola import_wordpress mysite.wordpress.2012-12-20.xml -o import_location
With this command Nikola will import into the folder ``import_location``.
@@ -1990,7 +1921,9 @@ Getting Extra Plugins
If you want extra plugins, there is also the `Plugins Index <https://plugins.getnikola.com/>`_.
Similarly to themes, there is a nice, built-in command to manage them —
-``plugin``::
+``plugin``:
+
+.. code:: console
$ nikola plugin -l
Plugins:
@@ -2015,7 +1948,9 @@ Similarly to themes, there is a nice, built-in command to manage them —
# Should the Hello World plugin say “BYE” instead?
BYE_WORLD = False
-Then you also can uninstall your plugins::
+Then you also can uninstall your plugins:
+
+.. code:: console
$ nikola plugin --uninstall tags
[2014-04-15T08:59:24Z] WARNING: plugin: About to uninstall plugin: tags
@@ -2023,7 +1958,9 @@ Then you also can uninstall your plugins::
Are you sure? [y/n] y
[2014-04-15T08:59:26Z] WARNING: plugin: Removing /home/ralsina/foo/plugins/tags
-And upgrade them::
+And upgrade them:
+
+.. code:: console
$ nikola plugin --upgrade
[2014-04-15T09:00:18Z] WARNING: plugin: This is not very smart, it just reinstalls some plugins and hopes for the best
@@ -2063,19 +2000,24 @@ Shell Tab Completion
Since Nikola is a command line tool, and this is the 21st century, it's handy to have smart tab-completion
so that you don't have to type the full commands.
-To enable this, you can use the ``nikola tabcompletion`` command like this, depending on your shell::
+To enable this, you can use the ``nikola tabcompletion`` command like this,
+depending on your shell:
+
+.. code:: console
$ nikola tabcompletion --shell bash --hardcode-tasks > _nikola_bash
$ nikola tabcompletion --shell zsh --hardcode-tasks > _nikola_zsh
The ``--hardcode-tasks`` adds tasks to the completion and may need updating periodically.
+Please refer to your shell’s documentation for help on how to use those files.
+
License
-------
-Nikola is released under a `MIT license <https://github.com/getnikola/nikola/blob/master/LICENSE.txt>`_ which
-is a free software license. Some components shipped along with Nikola, or required by it are
-released under other licenses.
+Nikola is released under the `MIT license <https://getnikola.com/license.html>`_, which is a free software license. Some
+components shipped along with Nikola, or required by it are released under
+other licenses.
If you are not familiar with free software licensing: In general, you should be able to
do pretty much anything you want, unless you modify Nikola. If you modify it, and share
diff --git a/docs/social_buttons.txt b/docs/social_buttons.txt
index 9436ee7..151c906 100644
--- a/docs/social_buttons.txt
+++ b/docs/social_buttons.txt
@@ -8,7 +8,7 @@
Using Alternative Social Buttons with Nikola
============================================
-:Version: 7.6.0
+:Version: 7.6.4
.. class:: alert alert-info pull-right
diff --git a/docs/sphinx/conf.py b/docs/sphinx/conf.py
index 36cf31b..3cd48af 100644
--- a/docs/sphinx/conf.py
+++ b/docs/sphinx/conf.py
@@ -54,9 +54,9 @@ copyright = '2012-2015, The Nikola Contributors'
# built documents.
#
# The short X.Y version.
-version = '7.6.0'
+version = '7.6.4'
# The full version, including alpha/beta/rc tags.
-release = '7.6.0'
+release = '7.6.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/support.rst b/docs/support.rst
index 0d4fc3a..bfcc24d 100644
--- a/docs/support.rst
+++ b/docs/support.rst
@@ -13,12 +13,13 @@ Help and Support
================
1. A `mailing list`_, nikola-discuss on Google Groups exists.
-2. There is an IRC channel, #nikola on Freenode. You can find many
+2. There is an IRC channel: #nikola on Freenode. You can find many
developers and volunteers (users) there which are there to provide
- help, if they are around and read your message.
+ help, if they are around and read your message. The channel is
+ `publicly logged <https://irclogs.getnikola.com/>`_.
3. You can also contact `@GetNikola <http://twitter.com/GetNikola>`_ on
Twitter.
-4. If you are experiencing a bug, [1]_ you should report it on GitHub (see
+4. If you are experiencing a bug, you should report it on GitHub (see
below).
Plugins and Themes
@@ -46,7 +47,7 @@ the `mailing list`_, especially if they require further discussion.
Administrativia
===============
-If you are in need of getting administrativia [2]_ resolved, you may want
+If you are in need of getting administrativia resolved, you may want
to e-mail info@getnikola.com and therefore contact the people behind the
project. Note that this email **may not** be used for support matters.
Messages are forwarded to all three administrators, the names and
@@ -56,6 +57,8 @@ find below.
Administrators
--------------
+.. class:: table table-bordered
+
+----------------+-----------------+-----------+-----------------------+
| Name | GitHub Nickname | Location | E-mail |
+================+=================+===========+=======================+
@@ -66,9 +69,6 @@ Administrators
| Chris Warrick | Kwpolska | Poland | chris@getnikola.com |
+----------------+-----------------+-----------+-----------------------+
-.. [1] `As defined on Wikipedia. <http://en.wikipedia.org/wiki/Software_bug>`_
-.. [2] `administrative matters <http://en.wiktionary.org/wiki/administrativia>`_
-
.. _mailing list: http://groups.google.com/group/nikola-discuss
.. _Issue tracker: https://github.com/getnikola/nikola/issues
.. _plugins issue tracker: https://github.com/getnikola/plugins/issues
diff --git a/docs/theming.txt b/docs/theming.txt
index f9667ed..4b6b4a7 100644
--- a/docs/theming.txt
+++ b/docs/theming.txt
@@ -8,7 +8,7 @@
Theming Nikola
==============
-:Version: 7.6.0
+:Version: 7.6.4
:Author: Roberto Alsina <ralsina@netmanagers.com.ar>
.. class:: alert alert-info pull-right
@@ -206,7 +206,7 @@ then your theme will need a custom ``messages`` folder.
-------------------------------------------------------------------
.. note::
- The LESS and Sass compilers will be moved to the Plugins Index in
+ The LESS and Sass compilers were moved to the Plugins Index in
Nikola v7.0.0.
If you want to use those CSS extensions, you can — just store your files
diff --git a/dodo.py b/dodo.py
index 3d5d070..82cd365 100644
--- a/dodo.py
+++ b/dodo.py
@@ -21,7 +21,14 @@ def task_flake8():
"""flake8 - static check for python files"""
yield {
'name': os.path.join(os.getcwd(), 'nikola'),
- 'actions': ['flake8 --ignore=E501 nikola/'],
+ 'actions': ['flake8 nikola/'],
+ }
+
+def task_pep257():
+ """pep257 -- static check for docstring style"""
+ yield {
+ 'name': os.path.join(os.getcwd(), 'nikola'),
+ 'actions': ["pep257 --count --match-dir='(?!^\.)(?!data).*' nikola/"],
}
diff --git a/nikola/__init__.py b/nikola/__init__.py
index 263874f..4ab6e34 100644
--- a/nikola/__init__.py
+++ b/nikola/__init__.py
@@ -24,10 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Nikola -- a modular, fast, simple, static website generator."""
+
from __future__ import absolute_import
import os
-__version__ = "7.6.0"
+__version__ = "7.6.4"
DEBUG = bool(os.getenv('NIKOLA_DEBUG'))
from .nikola import Nikola # NOQA
diff --git a/nikola/__main__.py b/nikola/__main__.py
index 6aa0977..2aa63f4 100644
--- a/nikola/__main__.py
+++ b/nikola/__main__.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""The main function of Nikola."""
+
from __future__ import print_function, unicode_literals
from collections import defaultdict
import os
@@ -49,7 +51,7 @@ from blinker import signal
from . import __version__
from .plugin_categories import Command
from .nikola import Nikola
-from .utils import sys_decode, sys_encode, get_root_dir, req_missing, LOGGER, STRICT_HANDLER, ColorfulStderrHandler
+from .utils import sys_decode, sys_encode, get_root_dir, req_missing, LOGGER, STRICT_HANDLER, STDERR_HANDLER, ColorfulStderrHandler
if sys.version_info[0] == 3:
import importlib.machinery
@@ -63,6 +65,7 @@ _RETURN_DOITNIKOLA = False
def main(args=None):
+ """Run Nikola."""
colorful = False
if sys.stderr.isatty() and os.name != 'nt':
colorful = True
@@ -88,13 +91,18 @@ def main(args=None):
break
quiet = False
+ strict = False
if len(args) > 0 and args[0] == 'build' and '--strict' in args:
LOGGER.notice('Running in strict mode')
STRICT_HANDLER.push_application()
+ strict = True
if len(args) > 0 and args[0] == 'build' and '-q' in args or '--quiet' in args:
- nullhandler = NullHandler()
- nullhandler.push_application()
+ NullHandler().push_application()
quiet = True
+ if not quiet and not strict:
+ NullHandler().push_application()
+ STDERR_HANDLER[0].push_application()
+
global config
original_cwd = os.getcwd()
@@ -167,11 +175,12 @@ def main(args=None):
class Help(DoitHelp):
- """show Nikola usage."""
+
+ """Show Nikola usage."""
@staticmethod
def print_usage(cmds):
- """print nikola "usage" (basic help) instructions"""
+ """Print nikola "usage" (basic help) instructions."""
# Remove 'run'. Nikola uses 'build', though we support 'run' for
# people used to it (eg. doit users).
# WARNING: 'run' is the vanilla doit command, without support for
@@ -190,8 +199,11 @@ class Help(DoitHelp):
class Build(DoitRun):
- """expose "run" command as "build" for backward compatibility"""
+
+ """Expose "run" command as "build" for backwards compatibility."""
+
def __init__(self, *args, **kw):
+ """Initialize Build."""
opts = list(self.cmd_options)
opts.append(
{
@@ -226,9 +238,11 @@ class Build(DoitRun):
class Clean(DoitClean):
- """A clean that removes cache/"""
+
+ """Clean site, including the cache directory."""
def clean_tasks(self, tasks, dryrun):
+ """Clean tasks."""
if not dryrun and config:
cache_folder = config.get('CACHE_FOLDER', 'cache')
if os.path.exists(cache_folder):
@@ -241,12 +255,16 @@ DoitAuto.name = 'doit_auto'
class NikolaTaskLoader(TaskLoader):
- """custom task loader to get tasks from Nikola instead of dodo.py file"""
+
+ """Nikola-specific task loader."""
+
def __init__(self, nikola, quiet=False):
+ """Initialize the loader."""
self.nikola = nikola
self.quiet = quiet
def load_tasks(self, cmd, opt_values, pos_args):
+ """Load Nikola tasks."""
if self.quiet:
DOIT_CONFIG = {
'verbosity': 0,
@@ -270,17 +288,22 @@ class NikolaTaskLoader(TaskLoader):
class DoitNikola(DoitMain):
+
+ """Nikola-specific implementation of DoitMain."""
+
# overwite help command
DOIT_CMDS = list(DoitMain.DOIT_CMDS) + [Help, Build, Clean, DoitAuto]
TASK_LOADER = NikolaTaskLoader
def __init__(self, nikola, quiet=False):
+ """Initialzie DoitNikola."""
super(DoitNikola, self).__init__()
self.nikola = nikola
nikola.doit = self
self.task_loader = self.TASK_LOADER(nikola, quiet)
def get_cmds(self):
+ """Get commands."""
# core doit commands
cmds = DoitMain.get_cmds(self)
# load nikola commands
@@ -289,7 +312,7 @@ class DoitNikola(DoitMain):
return cmds
def run(self, cmd_args):
- sub_cmds = self.get_cmds()
+ """Run Nikola."""
args = self.process_args(cmd_args)
args = [sys_decode(arg) for arg in args]
@@ -311,17 +334,31 @@ class DoitNikola(DoitMain):
if arg not in ('--help', '-h'):
args.append(arg)
+ if args[0] == 'help':
+ self.nikola.init_plugins(commands_only=True)
+ else:
+ self.nikola.init_plugins()
+
+ sub_cmds = self.get_cmds()
+
if any(arg in ("--version", '-V') for arg in args):
cmd_args = ['version']
args = ['version']
if args[0] not in sub_cmds.keys():
LOGGER.error("Unknown command {0}".format(args[0]))
sugg = defaultdict(list)
- for c in sub_cmds.keys():
- d = lev(c, args[0])
+ sub_filtered = (i for i in sub_cmds.keys() if i != 'run')
+ for c in sub_filtered:
+ d = levenshtein(c, args[0])
sugg[d].append(c)
- LOGGER.info('Did you mean "{}"?', '" or "'.join(sugg[min(sugg.keys())]))
+ if sugg.keys():
+ best_sugg = sugg[min(sugg.keys())]
+ if len(best_sugg) == 1:
+ LOGGER.info('Did you mean "{}"?'.format(best_sugg[0]))
+ else:
+ LOGGER.info('Did you mean "{}" or "{}"?'.format('", "'.join(best_sugg[:-1]), best_sugg[-1]))
return 3
+
if sub_cmds[args[0]] is not Help and not isinstance(sub_cmds[args[0]], Command): # Is a doit command
if not self.nikola.configured:
LOGGER.error("This command needs to run inside an "
@@ -331,15 +368,36 @@ class DoitNikola(DoitMain):
@staticmethod
def print_version():
+ """Print Nikola version."""
print("Nikola v" + __version__)
-# Stolen from http://stackoverflow.com/questions/4173579/implementing-levenshtein-distance-in-python
-def lev(a, b):
- if not a or not b:
- return max(len(a), len(b))
- return min(lev(a[1:], b[1:]) + (a[0] != b[0]), lev(a[1:], b) + 1, lev(a, b[1:]) + 1)
-
+def levenshtein(s1, s2):
+ u"""Calculate the Levenshtein distance of two strings.
+
+ Implementation from Wikibooks:
+ https://en.wikibooks.org/w/index.php?title=Algorithm_Implementation/Strings/Levenshtein_distance&oldid=2974448#Python
+ Copyright © The Wikibooks contributors (CC BY-SA/fair use citation); edited to match coding style and add an exception.
+ """
+ if len(s1) < len(s2):
+ return levenshtein(s2, s1)
+
+ # len(s1) >= len(s2)
+ if len(s2) == 0:
+ return len(s1)
+
+ previous_row = range(len(s2) + 1)
+ for i, c1 in enumerate(s1):
+ current_row = [i + 1]
+ for j, c2 in enumerate(s2):
+ # j+1 instead of j since previous_row and current_row are one character longer than s2
+ insertions = previous_row[j + 1] + 1
+ deletions = current_row[j] + 1
+ substitutions = previous_row[j] + (c1 != c2)
+ current_row.append(min(insertions, deletions, substitutions))
+ previous_row = current_row
+
+ return previous_row[-1]
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
diff --git a/nikola/conf.py.in b/nikola/conf.py.in
index ab00673..b7a88f7 100644
--- a/nikola/conf.py.in
+++ b/nikola/conf.py.in
@@ -21,7 +21,7 @@ import time
BLOG_AUTHOR = ${BLOG_AUTHOR} # (translatable)
BLOG_TITLE = ${BLOG_TITLE} # (translatable)
# This is the main URL for your site. It will be used
-# in a prominent link
+# in a prominent link. Don't forget the protocol (http/https)!
SITE_URL = ${SITE_URL}
# This is the URL where Nikola's output will be deployed.
# If not set, defaults to SITE_URL
@@ -229,7 +229,7 @@ WRITE_TAG_CLOUD = True
# "blogging": "Meta-blog posts about blogging about blogging.",
# "open source": "My contributions to my many, varied, ever-changing, and eternal libre software projects."
# },
-#}
+# }
# If you do not want to display a tag publicly, you can mark it as hidden.
@@ -255,10 +255,10 @@ HIDDEN_TAGS = ['mathjax']
# using a forward slash ('/') to separate paths. Use a backslash ('\') to escape
# a forward slash or a backslash (i.e. '\//\\' is a path specifying the
# subcategory called '\' of the top-level category called '/').
-# CATEGORY_ALLOW_HIERARCHIES = False
+CATEGORY_ALLOW_HIERARCHIES = ${CATEGORY_ALLOW_HIERARCHIES}
# If CATEGORY_OUTPUT_FLAT_HIERARCHY is set to True, the output written to output
# contains only the name of the leaf category and not the whole path.
-# CATEGORY_OUTPUT_FLAT_HIERARCHY = False
+CATEGORY_OUTPUT_FLAT_HIERARCHY = ${CATEGORY_OUTPUT_FLAT_HIERARCHY}
# If CATEGORY_PAGES_ARE_INDEXES is set to True, each category's page will contain
# the posts themselves. If set to False, it will be just a list of links.
@@ -272,7 +272,7 @@ HIDDEN_TAGS = ['mathjax']
# "blogging": "Meta-blog posts about blogging about blogging.",
# "open source": "My contributions to my many, varied, ever-changing, and eternal libre software projects."
# },
-#}
+# }
# If you do not want to display a category publicly, you can mark it as hidden.
# The category will not be displayed on the category list page.
@@ -546,7 +546,7 @@ IMAGE_FOLDERS = {'images': 'images'}
# ("icon", "/icon_128x128.png", "128x128"),
# )
-# Show only teasers in the index pages? Defaults to False.
+# Show teasers (instead of full posts) in indexes? Defaults to False.
# INDEX_TEASERS = False
# HTML fragments with the Read more... links.
@@ -582,10 +582,10 @@ LICENSE = ""
# I recommend using the Creative Commons' wizard:
# http://creativecommons.org/choose/
# LICENSE = """
-# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.5/ar/">
+# <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
# <img alt="Creative Commons License BY-NC-SA"
# style="border-width:0; margin-bottom:12px;"
-# src="http://i.creativecommons.org/l/by-nc-sa/2.5/ar/88x31.png"></a>"""
+# src="http://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"></a>"""
# A small copyright notice for the page footer (in HTML).
# (translatable)
@@ -655,8 +655,7 @@ COMMENT_SYSTEM_ID = ${COMMENT_SYSTEM_ID}
# (Uses the INDEX_FILE setting, so if that is, say, default.html,
# it will instead /foo/default.html => /foo)
# (Note: This was briefly STRIP_INDEX_HTML in v 5.4.3 and 5.4.4)
-# Default = False
-# STRIP_INDEXES = False
+STRIP_INDEXES = ${STRIP_INDEXES}
# Should the sitemap list directories which only include other directories
# and no files.
@@ -782,7 +781,7 @@ MARKDOWN_EXTENSIONS = ['fenced_code', 'codehilite', 'extra']
# change it for a FeedBurner feed or something else.
# RSS_LINK = None
-# Show only teasers in the RSS and Atom feeds? Default to True
+# Show teasers (instead of full posts) in feeds? Defaults to True.
# RSS_TEASERS = True
# Strip HTML in the RSS feed? Default to False
@@ -799,29 +798,34 @@ MARKDOWN_EXTENSIONS = ['fenced_code', 'codehilite', 'extra']
# it appears on the navigation bar:
#
# SEARCH_FORM = """
-# <!-- Custom search -->
+# <!-- DuckDuckGo custom search -->
# <form method="get" id="search" action="//duckduckgo.com/"
# class="navbar-form pull-left">
-# <input type="hidden" name="sites" value="%s"/>
-# <input type="hidden" name="k8" value="#444444"/>
-# <input type="hidden" name="k9" value="#D51920"/>
-# <input type="hidden" name="kt" value="h"/>
+# <input type="hidden" name="sites" value="%s">
+# <input type="hidden" name="k8" value="#444444">
+# <input type="hidden" name="k9" value="#D51920">
+# <input type="hidden" name="kt" value="h">
# <input type="text" name="q" maxlength="255"
-# placeholder="Search&hellip;" class="span2" style="margin-top: 4px;"/>
-# <input type="submit" value="DuckDuckGo Search" style="visibility: hidden;" />
+# placeholder="Search&hellip;" class="span2" style="margin-top: 4px;">
+# <input type="submit" value="DuckDuckGo Search" style="visibility: hidden;">
# </form>
# <!-- End of custom search -->
# """ % SITE_URL
#
# If you prefer a Google search form, here's an example that should just work:
# SEARCH_FORM = """
-# <!-- Custom search with Google-->
-# <form id="search" action="//www.google.com/search" method="get" class="navbar-form pull-left">
-# <input type="hidden" name="q" value="site:%s" />
-# <input type="text" name="q" maxlength="255" results="0" placeholder="Search"/>
+# <!-- Google custom search -->
+# <form method="get" action="http://www.google.com/search" class="navbar-form navbar-right" role="search">
+# <div class="form-group">
+# <input type="text" name="q" class="form-control" placeholder="Search">
+# </div>
+# <button type="submit" class="btn btn-primary">
+# <span class="glyphicon glyphicon-search"></span>
+# </button>
+# <input type="hidden" name="sitesearch" value="%s">
# </form>
# <!-- End of custom search -->
-#""" % SITE_URL
+# """ % SITE_URL
# Use content distribution networks for jQuery, twitter-bootstrap css and js,
# and html5shiv (for older versions of Internet Explorer)
@@ -926,26 +930,6 @@ UNSLUGIFY_TITLES = True
# sometimes crash Nikola, your web server, or eat your cat.
# USE_SLUGIFY = True
-# You can configure the logging handlers installed as plugins or change the
-# log level of the default stderr handler.
-# WARNING: The stderr handler allows only the loglevels of 'INFO' and 'DEBUG'.
-# This is done for safety reasons, as blocking out anything other
-# than 'DEBUG' may hide important information and break the user
-# experience!
-
-LOGGING_HANDLERS = {
- 'stderr': {'loglevel': 'INFO', 'bubble': True},
- # 'smtp': {
- # 'from_addr': 'test-errors@example.com',
- # 'recipients': ('test@example.com'),
- # 'credentials':('testusername', 'password'),
- # 'server_addr': ('127.0.0.1', 25),
- # 'secure': (),
- # 'level': 'DEBUG',
- # 'bubble': True
- # }
-}
-
# Templates will use those filters, along with the defaults.
# Consult your engine's documentation on filters if you need help defining
# those.
diff --git a/nikola/data/samplesite/README.txt b/nikola/data/samplesite/README.txt
index da0d685..011a882 100644
--- a/nikola/data/samplesite/README.txt
+++ b/nikola/data/samplesite/README.txt
@@ -2,7 +2,7 @@ This folder contains the source used to generate a static site using Nikola.
Installation and documentation at https://getnikola.com/
-Configuration file for the site is `conf.py`.
+Configuration file for the site is ``conf.py``.
To build the site::
@@ -10,10 +10,7 @@ To build the site::
To see it::
- nikola serve
-
-And point your browser to http://localhost:8000/
-
+ nikola serve -b
To check all available commands::
diff --git a/nikola/data/samplesite/posts/1.rst b/nikola/data/samplesite/posts/1.rst
index 9a55859..88263a7 100644
--- a/nikola/data/samplesite/posts/1.rst
+++ b/nikola/data/samplesite/posts/1.rst
@@ -17,11 +17,11 @@ and build a site using it. Congratulations!
Next steps:
-* `Read the manual </stories/handbook.html>`__
+* :doc:`Read the manual <handbook>`
* `Visit the Nikola website to learn more <https://getnikola.com>`__
-* `See a demo photo gallery </galleries/demo/index.html>`__
-* `See a demo listing </stories/listings-demo.html>`__
-* `See a demo slideshow </stories/slides-demo.html>`__
-* `See a demo of the Bootstrap theme </stories/bootstrap-demo.html>`__
+* `See a demo photo gallery <link://gallery/demo>`__
+* :doc:`See a demo listing <listings-demo>`
+* :doc:`See a demo slideshow <slides-demo>`
+* :doc:`See a demo of the Bootstrap theme <bootstrap-demo>`
Send feedback to info@getnikola.com!
diff --git a/nikola/data/symlinked.txt b/nikola/data/symlinked.txt
index aae8ea1..ce34ddf 100644
--- a/nikola/data/symlinked.txt
+++ b/nikola/data/symlinked.txt
@@ -14,105 +14,15 @@ nikola/data/samplesite/stories/theming.rst
nikola/data/symlink-test-link.txt
nikola/data/themes/base/assets/js/moment-with-locales.min.js
nikola/data/themes/base/messages/messages_cz.py
-nikola/data/themes/bootstrap-jinja/assets/css/colorbox.css
-nikola/data/themes/bootstrap-jinja/assets/css/images/controls.png
-nikola/data/themes/bootstrap-jinja/assets/css/images/loading.gif
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
-nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
-nikola/data/themes/bootstrap-jinja/assets/js/jquery.colorbox-min.js
-nikola/data/themes/bootstrap-jinja/assets/js/jquery.colorbox.js
-nikola/data/themes/bootstrap-jinja/assets/js/jquery.js
-nikola/data/themes/bootstrap-jinja/assets/js/jquery.min.js
-nikola/data/themes/bootstrap-jinja/assets/js/jquery.min.map
-nikola/data/themes/bootstrap-jinja/bundles
-nikola/data/themes/bootstrap/assets/css/colorbox.css
-nikola/data/themes/bootstrap/assets/css/images/controls.png
-nikola/data/themes/bootstrap/assets/css/images/loading.gif
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ar.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bg.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bn.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ca.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-cs.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-da.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-de.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-es.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-et.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fa.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fi.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gl.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-he.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hu.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-id.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-it.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ja.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-kr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lt.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lv.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-my.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-nl.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-no.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pl.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ro.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ru.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-si.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sk.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sv.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-tr.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-uk.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
-nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
-nikola/data/themes/bootstrap/assets/js/jquery.colorbox-min.js
-nikola/data/themes/bootstrap/assets/js/jquery.colorbox.js
-nikola/data/themes/bootstrap/assets/js/jquery.js
-nikola/data/themes/bootstrap/assets/js/jquery.min.js
-nikola/data/themes/bootstrap/assets/js/jquery.min.map
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap-theme.css
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap-theme.css.map
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap-theme.min.css
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap.css
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap.css.map
nikola/data/themes/bootstrap3-jinja/assets/css/bootstrap.min.css
+nikola/data/themes/bootstrap3-jinja/assets/css/colorbox.css
+nikola/data/themes/bootstrap3-jinja/assets/css/images/controls.png
+nikola/data/themes/bootstrap3-jinja/assets/css/images/loading.gif
nikola/data/themes/bootstrap3-jinja/assets/fonts/glyphicons-halflings-regular.eot
nikola/data/themes/bootstrap3-jinja/assets/fonts/glyphicons-halflings-regular.svg
nikola/data/themes/bootstrap3-jinja/assets/fonts/glyphicons-halflings-regular.ttf
@@ -120,6 +30,49 @@ nikola/data/themes/bootstrap3-jinja/assets/fonts/glyphicons-halflings-regular.wo
nikola/data/themes/bootstrap3-jinja/assets/fonts/glyphicons-halflings-regular.woff2
nikola/data/themes/bootstrap3-jinja/assets/js/bootstrap.js
nikola/data/themes/bootstrap3-jinja/assets/js/bootstrap.min.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
+nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
+nikola/data/themes/bootstrap3-jinja/assets/js/jquery.colorbox-min.js
+nikola/data/themes/bootstrap3-jinja/assets/js/jquery.colorbox.js
+nikola/data/themes/bootstrap3-jinja/assets/js/jquery.js
+nikola/data/themes/bootstrap3-jinja/assets/js/jquery.min.js
+nikola/data/themes/bootstrap3-jinja/assets/js/jquery.min.map
nikola/data/themes/bootstrap3-jinja/bundles
nikola/data/themes/bootstrap3/assets/css/bootstrap-theme.css
nikola/data/themes/bootstrap3/assets/css/bootstrap-theme.css.map
@@ -127,6 +80,9 @@ nikola/data/themes/bootstrap3/assets/css/bootstrap-theme.min.css
nikola/data/themes/bootstrap3/assets/css/bootstrap.css
nikola/data/themes/bootstrap3/assets/css/bootstrap.css.map
nikola/data/themes/bootstrap3/assets/css/bootstrap.min.css
+nikola/data/themes/bootstrap3/assets/css/colorbox.css
+nikola/data/themes/bootstrap3/assets/css/images/controls.png
+nikola/data/themes/bootstrap3/assets/css/images/loading.gif
nikola/data/themes/bootstrap3/assets/fonts/glyphicons-halflings-regular.eot
nikola/data/themes/bootstrap3/assets/fonts/glyphicons-halflings-regular.svg
nikola/data/themes/bootstrap3/assets/fonts/glyphicons-halflings-regular.ttf
@@ -134,4 +90,47 @@ nikola/data/themes/bootstrap3/assets/fonts/glyphicons-halflings-regular.woff
nikola/data/themes/bootstrap3/assets/fonts/glyphicons-halflings-regular.woff2
nikola/data/themes/bootstrap3/assets/js/bootstrap.js
nikola/data/themes/bootstrap3/assets/js/bootstrap.min.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ar.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bg.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bn.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ca.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-cs.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-da.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-de.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-es.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-et.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fa.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fi.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gl.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-he.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hu.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-id.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-it.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ja.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-kr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lt.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lv.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-my.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-nl.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-no.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pl.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ro.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ru.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-si.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sk.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sv.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-tr.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-uk.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
+nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
+nikola/data/themes/bootstrap3/assets/js/jquery.colorbox-min.js
+nikola/data/themes/bootstrap3/assets/js/jquery.colorbox.js
+nikola/data/themes/bootstrap3/assets/js/jquery.js
+nikola/data/themes/bootstrap3/assets/js/jquery.min.js
+nikola/data/themes/bootstrap3/assets/js/jquery.min.map
nikola/plugins/command/auto/livereload.js
diff --git a/nikola/data/themes/base-jinja/templates/archiveindex.tmpl b/nikola/data/themes/base-jinja/templates/archiveindex.tmpl
index 565732c..8b9286e 100644
--- a/nikola/data/themes/base-jinja/templates/archiveindex.tmpl
+++ b/nikola/data/themes/base-jinja/templates/archiveindex.tmpl
@@ -4,7 +4,7 @@
{% block extra_head %}
{{ super() }}
{% if translations|length > 1 and generate_atom %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/atom+xml" title="Atom for the {{ archive_name }} section ({{ language }})" href="{{ _link("archive_atom", archive_name, language) }}">
{% endfor %}
{% elif generate_atom %}
diff --git a/nikola/data/themes/base-jinja/templates/base.tmpl b/nikola/data/themes/base-jinja/templates/base.tmpl
index 00ba9d7..5412326 100644
--- a/nikola/data/themes/base-jinja/templates/base.tmpl
+++ b/nikola/data/themes/base-jinja/templates/base.tmpl
@@ -14,13 +14,14 @@
<a href="#content" class="sr-only sr-only-focusable">{{ messages("Skip to main content") }}</a>
<div id="container">
{{ header.html_header() }}
- <main id="content" role="main">
+ <main id="content">
{% block content %}{% endblock %}
</main>
{{ footer.html_footer() }}
</div>
+ {{ base.late_load_js() }}
+ {% block extra_js %}{% endblock %}
{{ body_end }}
{{ template_hooks['body_end']() }}
- {{ base.late_load_js() }}
</body>
</html>
diff --git a/nikola/data/themes/base-jinja/templates/base_footer.tmpl b/nikola/data/themes/base-jinja/templates/base_footer.tmpl
index 7fcf616..2e541a6 100644
--- a/nikola/data/themes/base-jinja/templates/base_footer.tmpl
+++ b/nikola/data/themes/base-jinja/templates/base_footer.tmpl
@@ -3,7 +3,7 @@
{% macro html_footer() %}
{% if content_footer %}
- <footer id="footer" role="contentinfo">
+ <footer id="footer">
<p>{{ content_footer }}</p>
{{ template_hooks['page_footer']() }}
</footer>
diff --git a/nikola/data/themes/base-jinja/templates/base_header.tmpl b/nikola/data/themes/base-jinja/templates/base_header.tmpl
index 9f79e72..092abd8 100644
--- a/nikola/data/themes/base-jinja/templates/base_header.tmpl
+++ b/nikola/data/themes/base-jinja/templates/base_header.tmpl
@@ -2,7 +2,7 @@
{% import 'base_helper.tmpl' as base with context %}
{% macro html_header() %}
- <header id="header" role="banner">
+ <header id="header">
{{ html_site_title() }}
{{ html_translation_header() }}
{{ html_navigation_links() }}
@@ -28,7 +28,7 @@
{% endmacro %}
{% macro html_navigation_links() %}
- <nav id="menu" role="navigation">
+ <nav id="menu">
<ul>
{% for url, text in navigation_links[lang] %}
{% if isinstance(url, tuple) %}
diff --git a/nikola/data/themes/base-jinja/templates/base_helper.tmpl b/nikola/data/themes/base-jinja/templates/base_helper.tmpl
index baa6810..8b4ed97 100644
--- a/nikola/data/themes/base-jinja/templates/base_helper.tmpl
+++ b/nikola/data/themes/base-jinja/templates/base_helper.tmpl
@@ -21,17 +21,20 @@ dir="rtl"
lang="{{ lang }}">
<head>
<meta charset="utf-8">
+ <base href="{{ abs_link(permalink) }}">
{% if description %}
<meta name="description" content="{{ description }}">
{% endif %}
<meta name="viewport" content="width=device-width">
- <title>{{ title|e }} | {{ blog_title|e }}</title>
+ {% if title == blog_title %}
+ <title>{{ blog_title|e }}</title>
+ {% else %}
+ <title>{{ title|e }} | {{ blog_title|e }}</title>
+ {% endif %}
{{ html_stylesheets() }}
{{ html_feedlinks() }}
- {% if permalink %}
- <link rel="canonical" href="{{ abs_link(permalink) }}">
- {% endif %}
+ <link rel="canonical" href="{{ abs_link(permalink) }}">
{% if favicons %}
{% for name, file, size in favicons %}
@@ -90,7 +93,7 @@ lang="{{ lang }}">
{{ rss_link }}
{% elif generate_rss %}
{% if translations|length > 1 %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/rss+xml" title="RSS ({{ language }})" href="{{ _link('rss', None, language) }}">
{% endfor %}
{% else %}
@@ -99,7 +102,7 @@ lang="{{ lang }}">
{% endif %}
{% if generate_atom %}
{% if translations|length > 1 %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/atom+xml" title="Atom ({{ language }})" href="{{ _link('index_atom', None, language) }}">
{% endfor %}
{% else %}
@@ -110,7 +113,7 @@ lang="{{ lang }}">
{% macro html_translations() %}
<ul class="translations">
- {% for langname in translations.keys() %}
+ {% for langname in translations|sort %}
{% if langname != lang %}
<li><a href="{{ abs_link(_link("root", None, langname)) }}" rel="alternate" hreflang="{{ langname }}">{{ messages("LANGUAGE", langname) }}</a></li>
{% endif %}
diff --git a/nikola/data/themes/base-jinja/templates/index.tmpl b/nikola/data/themes/base-jinja/templates/index.tmpl
index fd9fcf4..222da43 100644
--- a/nikola/data/themes/base-jinja/templates/index.tmpl
+++ b/nikola/data/themes/base-jinja/templates/index.tmpl
@@ -19,7 +19,7 @@
<h1 class="p-name entry-title"><a href="{{ post.permalink() }}" class="u-url">{{ post.title()|e }}</a></h1>
<div class="metadata">
<p class="byline author vcard"><span class="byline-name fn">{{ post.author() }}</span></p>
- <p class="dateline"><a href="{{ post.permalink() }}" rel="bookmark"><time class="published dt-published" datetime="{{ post.date.isoformat() }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></a></p>
+ <p class="dateline"><a href="{{ post.permalink() }}" rel="bookmark"><time class="published dt-published" datetime="{{ post.formatted_date('webiso') }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></a></p>
{% if not post.meta('nocomments') and site_has_comments %}
<p class="commentline">{{ comments.comment_link(post.permalink(), post._base_path) }}
{% endif %}
diff --git a/nikola/data/themes/base-jinja/templates/list_post.tmpl b/nikola/data/themes/base-jinja/templates/list_post.tmpl
index 166d8c4..919d6f0 100644
--- a/nikola/data/themes/base-jinja/templates/list_post.tmpl
+++ b/nikola/data/themes/base-jinja/templates/list_post.tmpl
@@ -9,7 +9,7 @@
{% if posts %}
<ul class="postlist">
{% for post in posts %}
- <li><a href="{{ post.permalink() }}" class="listtitle">{{ post.title()|e }}</a> <time class="listdate" datetime="{{ post.date.isoformat() }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></li>
+ <li><a href="{{ post.permalink() }}" class="listtitle">{{ post.title()|e }}</a> <time class="listdate" datetime="{{ post.formatted_date('webiso') }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></li>
{% endfor %}
</ul>
{% else %}
diff --git a/nikola/data/themes/base-jinja/templates/post_header.tmpl b/nikola/data/themes/base-jinja/templates/post_header.tmpl
index 00b6210..dc844e3 100644
--- a/nikola/data/themes/base-jinja/templates/post_header.tmpl
+++ b/nikola/data/themes/base-jinja/templates/post_header.tmpl
@@ -12,7 +12,7 @@
{% if post.translated_to|length > 1 %}
<div class="metadata posttranslations translations">
<h3 class="posttranslations-intro">{{ messages("Also available in:") }}</h3>
- {% for langname in translations.keys() %}
+ {% for langname in translations|sort %}
{% if langname != lang and post.is_translation_available(langname) %}
<p><a href="{{ post.permalink(langname) }}" rel="alternate" hreflang="{{ langname }}">{{ messages("LANGUAGE", langname) }}</a></p>
{% endif %}
@@ -32,7 +32,7 @@
{{ html_title() }}
<div class="metadata">
<p class="byline author vcard"><span class="byline-name fn">{{ post.author() }}</span></p>
- <p class="dateline"><a href="{{ post.permalink() }}" rel="bookmark"><time class="published dt-published" datetime="{{ post.date.isoformat() }}" itemprop="datePublished" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></a></p>
+ <p class="dateline"><a href="{{ post.permalink() }}" rel="bookmark"><time class="published dt-published" datetime="{{ post.formatted_date('webiso') }}" itemprop="datePublished" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></a></p>
{% if not post.meta('nocomments') and site_has_comments %}
<p class="commentline">{{ comments.comment_link(post.permalink(), post._base_path) }}
{% endif %}
diff --git a/nikola/data/themes/base-jinja/templates/post_helper.tmpl b/nikola/data/themes/base-jinja/templates/post_helper.tmpl
index ae0206b..b4826eb 100644
--- a/nikola/data/themes/base-jinja/templates/post_helper.tmpl
+++ b/nikola/data/themes/base-jinja/templates/post_helper.tmpl
@@ -2,7 +2,7 @@
{% macro meta_translations(post) %}
{% if translations|length > 1 %}
- {% for langname in translations.keys() %}
+ {% for langname in translations|sort %}
{% if langname != lang and post.is_translation_available(langname) %}
<link rel="alternate" hreflang="{{ langname }}" href="{{ post.permalink(langname) }}">
{% endif %}
@@ -58,7 +58,7 @@
{# <meta property="article:author" content="{{ post.author() }}"> #}
{# %endif #}
{% if post.date.isoformat() %}
- <meta property="article:published_time" content="{{ post.date.isoformat() }}">
+ <meta property="article:published_time" content="{{ post.formatted_date('webiso') }}">
{% endif %}
{% if post.tags %}
{% for tag in post.tags %}
diff --git a/nikola/data/themes/base-jinja/templates/tag.tmpl b/nikola/data/themes/base-jinja/templates/tag.tmpl
index 765c122..0928a5f 100644
--- a/nikola/data/themes/base-jinja/templates/tag.tmpl
+++ b/nikola/data/themes/base-jinja/templates/tag.tmpl
@@ -4,7 +4,7 @@
{% block extra_head %}
{{ super() }}
{% if translations|length > 1 and generate_rss %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/rss+xml" type="application/rss+xml" title="RSS for {{ kind }} {{ tag }} ({{ language }})" href="{{ _link(kind + "_rss", tag, language) }}">
{% endfor %}
{% elif generate_rss %}
@@ -30,7 +30,7 @@
{% endif %}
<div class="metadata">
{% if translations|length > 1 and generate_rss %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<p class="feedlink">
<a href="{{ _link(kind + "_rss", tag, language) }}" hreflang="{{ language }}" type="application/rss+xml">{{ messages('RSS feed', language) }} ({{ language }})</a>&nbsp;
</p>
@@ -43,7 +43,7 @@
{% if posts %}
<ul class="postlist">
{% for post in posts %}
- <li><a href="{{ post.permalink() }}" class="listtitle">{{ post.title()|e }}</a> <time class="listdate" datetime="{{ post.date.isoformat() }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></li>
+ <li><a href="{{ post.permalink() }}" class="listtitle">{{ post.title()|e }}</a> <time class="listdate" datetime="{{ post.formatted_date('webiso') }}" title="{{ post.formatted_date(date_format) }}">{{ post.formatted_date(date_format) }}</time></li>
{% endfor %}
</ul>
{% endif %}
diff --git a/nikola/data/themes/base-jinja/templates/tagindex.tmpl b/nikola/data/themes/base-jinja/templates/tagindex.tmpl
index ee7d8b0..f2d2d7a 100644
--- a/nikola/data/themes/base-jinja/templates/tagindex.tmpl
+++ b/nikola/data/themes/base-jinja/templates/tagindex.tmpl
@@ -15,7 +15,7 @@
{% block extra_head %}
{{ super() }}
{% if translations|length > 1 and generate_atom %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/atom+xml" title="Atom for the {{ tag }} section ({{ language }})" href="{{ _link(kind + "_atom", tag, language) }}">
{% endfor %}
{% elif generate_atom %}
diff --git a/nikola/data/themes/base/assets/css/rst.css b/nikola/data/themes/base/assets/css/rst.css
index 6e6de97..0fbab76 100644
--- a/nikola/data/themes/base/assets/css/rst.css
+++ b/nikola/data/themes/base/assets/css/rst.css
@@ -1,6 +1,6 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 7514 2012-09-14 14:27:12Z milde $
+:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
@@ -35,18 +35,10 @@ a.toc-backref {
blockquote.epigraph {
margin: 2em 5em ; }
-dl.docutils dd {
- margin-bottom: 0.5em }
-
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
- font-weight: bold }
-*/
-
div.abstract {
margin: 2em 5em }
@@ -55,23 +47,51 @@ div.abstract p.topic-title {
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
- margin: 2em ;
- border: medium outset ;
- padding: 1em }
+div.hint, div.important, div.note, div.tip, div.warning, div.sidebar {
+/* stolen from Boostrap 3 (.panel .panel-default) */
+ margin-bottom: 20px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
+ padding: 0 15px 15px 15px;
+}
+
+div.attention, div.caution, div.danger, div.error, div.warning {
+ /* stolen from Boostrap 3 (.panel .panel-danger) */
+ border-color: #EBCCD1;
+}
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
- font-weight: bold ;
- font-family: sans-serif }
+div.tip p.admonition-title, div.sidebar p.sidebar-title,
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+/* stolen from Boostrap 3 (.panel .panel-default .panel-heading) */
+ font-size: 16px;
+ color: #333;
+ background-color: #F5F5F5;
+ padding: 10px 15px;
+ margin-left: -15px;
+ margin-right: -15px;
+ border-bottom: 1px solid rgba(0, 0, 0, 0);
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ color: #333;
+ background-color: #F5F5F5;
+ border-color: #DDD;
+}
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title, .code .error {
- color: red ;
- font-weight: bold ;
- font-family: sans-serif }
+div.warning p.admonition-title {
+ /* stolen from Boostrap 3 (.panel .panel-danger) */
+ color: #A94442;
+ background-color: #F2DEDE;
+ border-color: #EBCCD1;
+}
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
@@ -118,48 +138,32 @@ html[dir="rtl"] div.line-block div.line-block {
}
div.sidebar {
- margin: 0 0 0.5em 1em ;
- border: medium outset ;
- padding: 1em ;
- background-color: #ffffee ;
+ margin-left: 2em;
+ min-height: 20px;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
- font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
- color: red }
+ color: #a94442 }
div.system-message {
- border: medium outset ;
+ border: 1px solid #ebccd1;
padding: 1em }
div.system-message p.system-message-title {
- color: red ;
+ color: #a94442 ;
font-weight: bold }
div.topic {
margin: 2em }
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
- margin-top: 0.4em }
-
-h1.title {
- text-align: center }
-
-h2.subtitle {
- text-align: center }
-
-hr.docutils {
- width: 75% }
-
img.align-left, .figure.align-left, object.align-left {
clear: left ;
float: left ;
@@ -231,13 +235,7 @@ p.rubric {
color: maroon ;
text-align: center }
-p.sidebar-title {
- font-family: sans-serif ;
- font-weight: bold ;
- font-size: larger }
-
p.sidebar-subtitle {
- font-family: sans-serif ;
font-weight: bold }
p.topic-title {
@@ -248,30 +246,23 @@ pre.address {
margin-top: 0 ;
font: inherit }
-pre.literal-block, pre.doctest-block, pre.math, pre.code {
- margin-left: 2em ;
- margin-right: 2em }
-
pre.code .ln { color: grey; } /* line numbers */
-pre.code, code { background-color: #eeeeee; }
+/*
+pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
+*/
span.classifier {
- font-family: sans-serif ;
- font-style: oblique }
+ font-style: italic }
span.classifier-delimiter {
- font-family: sans-serif ;
font-weight: bold }
-span.interpreted {
- font-family: sans-serif }
-
span.option {
white-space: nowrap }
@@ -312,6 +303,21 @@ table.docutils th.field-name, table.docinfo th.docinfo-name {
white-space: nowrap ;
padding-left: 0 }
+/* "booktabs" style (no vertical lines) */
+table.docutils.booktabs {
+ border: 0px;
+ border-top: 2px solid;
+ border-bottom: 2px solid;
+ border-collapse: collapse;
+}
+table.docutils.booktabs * {
+ border: 0px;
+}
+table.docutils.booktabs th {
+ border-bottom: thin solid;
+ text-align: left;
+}
+
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
diff --git a/nikola/data/themes/base/assets/css/theme.css b/nikola/data/themes/base/assets/css/theme.css
index 3cb8628..5c7c86d 100644
--- a/nikola/data/themes/base/assets/css/theme.css
+++ b/nikola/data/themes/base/assets/css/theme.css
@@ -320,6 +320,7 @@ pre.code, code {
*/
a[href^="#"]:after,
+ a[href^="data:"]:after,
a[href^="javascript:"]:after {
content: "";
}
diff --git a/nikola/data/themes/base/messages/messages_bs.py b/nikola/data/themes/base/messages/messages_bs.py
new file mode 100644
index 0000000..23a1f64
--- /dev/null
+++ b/nikola/data/themes/base/messages/messages_bs.py
@@ -0,0 +1,39 @@
+# -*- encoding:utf-8 -*-
+from __future__ import unicode_literals
+
+MESSAGES = {
+ "%d min remaining to read": "%d minuta preostalo za čitanje",
+ "(active)": "(aktivno)",
+ "Also available in:": "Takođe dostupan u:",
+ "Archive": "Arhiva",
+ "Categories": "Kategorije",
+ "Comments": "Komentari",
+ "LANGUAGE": "Bosanski",
+ "Languages:": "Jezici:",
+ "More posts about %s": "Više objava o %s",
+ "Newer posts": "Novije objave",
+ "Next post": "Naredna objava",
+ "No posts found.": "Nema objava.",
+ "Nothing found.": "Ništa nije pronađeno.",
+ "Older posts": "Starije objave",
+ "Original site": "Izvorni sajt",
+ "Posted:": "Objavljeno:",
+ "Posts about %s": "Objave o %s",
+ "Posts for year %s": "Objave u godini %s",
+ "Posts for {month} {day}, {year}": "Objave za {month} {day}, {year}",
+ "Posts for {month} {year}": "Objave za {month} {year}",
+ "Previous post": "Prethodne objave",
+ "Publication date": "Datum objavljivanja",
+ "RSS feed": "RSS feed",
+ "Read in English": "Pročitaj na bosanskom",
+ "Read more": "Pročitaj više",
+ "Skip to main content": "Preskoči na glavni sadržaj",
+ "Source": "Izvor",
+ "Subcategories:": "Podkategorije:",
+ "Tags and Categories": "Oznake i kategorije",
+ "Tags": "Oznake",
+ "Write your page here.": "Vašu stranicu napišite ovdje.",
+ "Write your post here.": "Vašu objavu napišite ovdje.",
+ "old posts, page %d": "stare objave, strana %d",
+ "page %d": "strana %d",
+}
diff --git a/nikola/data/themes/base/messages/messages_fi.py b/nikola/data/themes/base/messages/messages_fi.py
index bcc2680..1bcd6ad 100644
--- a/nikola/data/themes/base/messages/messages_fi.py
+++ b/nikola/data/themes/base/messages/messages_fi.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
MESSAGES = {
"%d min remaining to read": "%d minuuttia lukuaikaa",
- "(active)": "",
+ "(active)": "(aktiivinen)",
"Also available in:": "Saatavilla myös:",
"Archive": "Arkisto",
"Categories": "Kategoriat",
@@ -22,14 +22,14 @@ MESSAGES = {
"Posts for year %s": "Postauksia vuodelta %s",
"Posts for {month} {day}, {year}": "",
"Posts for {month} {year}": "Postauksia ajalle {month} {year}",
- "Previous post": "Vanhempia postauksia",
+ "Previous post": "Edellinen postaus",
"Publication date": "Julkaisupäivämäärä",
- "RSS feed": "RSS syöte",
+ "RSS feed": "RSS-syöte",
"Read in English": "Lue suomeksi",
"Read more": "Lue lisää",
"Skip to main content": "Hyppää sisältöön",
"Source": "Lähde",
- "Subcategories:": "",
+ "Subcategories:": "Alakategoriat:",
"Tags and Categories": "Tagit ja kategoriat",
"Tags": "Tagit",
"Write your page here.": "",
diff --git a/nikola/data/themes/base/messages/messages_hr.py b/nikola/data/themes/base/messages/messages_hr.py
index d26fc85..11e07d8 100644
--- a/nikola/data/themes/base/messages/messages_hr.py
+++ b/nikola/data/themes/base/messages/messages_hr.py
@@ -2,8 +2,8 @@
from __future__ import unicode_literals
MESSAGES = {
- "%d min remaining to read": "",
- "(active)": "",
+ "%d min remaining to read": "%d minuta preostalo za čitanje",
+ "(active)": "(aktivno)",
"Also available in:": "Također dostupno i u:",
"Archive": "Arhiva",
"Categories": "Kategorije",
@@ -27,9 +27,9 @@ MESSAGES = {
"RSS feed": "RSS kanal",
"Read in English": "Čitaj na hrvatskom",
"Read more": "Čitaj dalje",
- "Skip to main content": "",
+ "Skip to main content": "Preskoči na glavni sadržaj",
"Source": "Izvor",
- "Subcategories:": "",
+ "Subcategories:": "Podkategorije:",
"Tags and Categories": "Tagovi i kategorije",
"Tags": "Tagovi",
"Write your page here.": "",
diff --git a/nikola/data/themes/base/messages/messages_it.py b/nikola/data/themes/base/messages/messages_it.py
index 91f8374..9f6d8be 100644
--- a/nikola/data/themes/base/messages/messages_it.py
+++ b/nikola/data/themes/base/messages/messages_it.py
@@ -8,7 +8,7 @@ MESSAGES = {
"Archive": "Archivio",
"Categories": "Categorie",
"Comments": "Commenti",
- "LANGUAGE": "Inglese",
+ "LANGUAGE": "Italiano",
"Languages:": "Lingue:",
"More posts about %s": "Altri articoli collegati %s",
"Newer posts": "Articoli più recenti",
@@ -30,7 +30,7 @@ MESSAGES = {
"Skip to main content": "Vai al testo principale",
"Source": "Sorgente",
"Subcategories:": "Sottocategorie:",
- "Tags and Categories": "Tag e Categorie",
+ "Tags and Categories": "Tag e categorie",
"Tags": "Tag",
"Write your page here.": "Scrivi qui la tua pagina.",
"Write your post here.": "Scrivi qui il tuo post.",
diff --git a/nikola/data/themes/base/messages/messages_nb.py b/nikola/data/themes/base/messages/messages_nb.py
index 2533247..30b798e 100644
--- a/nikola/data/themes/base/messages/messages_nb.py
+++ b/nikola/data/themes/base/messages/messages_nb.py
@@ -2,38 +2,38 @@
from __future__ import unicode_literals
MESSAGES = {
- "%d min remaining to read": "",
- "(active)": "",
+ "%d min remaining to read": "%d min gjenstår å lese",
+ "(active)": "(aktiv)",
"Also available in:": "Også tilgjengelig på:",
"Archive": "Arkiv",
"Categories": "Kategorier",
- "Comments": "",
+ "Comments": "Kommentarer",
"LANGUAGE": "norsk",
- "Languages:": "",
+ "Languages:": "Språk:",
"More posts about %s": "Flere innlegg om %s",
"Newer posts": "Nyere innlegg",
"Next post": "Neste innlegg",
- "No posts found.": "",
- "Nothing found.": "",
+ "No posts found.": "Fant ingen innlegg.",
+ "Nothing found.": "Fant ingenting.",
"Older posts": "Eldre innlegg",
"Original site": "Opprinnelig side",
"Posted:": "Publisert:",
"Posts about %s": "Innlegg om %s",
"Posts for year %s": "Innlegg fra %s",
- "Posts for {month} {day}, {year}": "",
+ "Posts for {month} {day}, {year}": "Innlegg fra {day}. {month} {year}",
"Posts for {month} {year}": "Innlegg fra {month} {year}",
"Previous post": "Forrige innlegg",
- "Publication date": "",
- "RSS feed": "",
+ "Publication date": "Publiseringsdato",
+ "RSS feed": "RSS-nyhetskanal",
"Read in English": "Les på norsk",
"Read more": "Les mer",
- "Skip to main content": "",
+ "Skip to main content": "Hopp til hovedinnholdet",
"Source": "Kilde",
- "Subcategories:": "",
+ "Subcategories:": "Underkategorier:",
"Tags and Categories": "Merker og kategorier",
"Tags": "Merker",
- "Write your page here.": "",
- "Write your post here.": "",
+ "Write your page here.": "Skriv siden din her.",
+ "Write your post here.": "Skriv innlegget din her.",
"old posts, page %d": "eldre innlegg, side %d",
"page %d": "side %d",
}
diff --git a/nikola/data/themes/base/messages/messages_pa.py b/nikola/data/themes/base/messages/messages_pa.py
new file mode 100644
index 0000000..392a38b
--- /dev/null
+++ b/nikola/data/themes/base/messages/messages_pa.py
@@ -0,0 +1,39 @@
+# -*- encoding:utf-8 -*-
+from __future__ import unicode_literals
+
+MESSAGES = {
+ "%d min remaining to read": "ਪੜਣ ਲਈ %d ਮਿੰਟ ਬਾਕੀ",
+ "(active)": "(ਚਲੰਤ)",
+ "Also available in:": "ਹੋਰ ਉਪਲਬਧ ਬੋਲੀਆਂ:",
+ "Archive": "ਆਰਕਾਈਵ",
+ "Categories": "ਸ਼੍ਰੇਣੀ",
+ "Comments": "ਟਿੱਪਣੀਆਂ",
+ "LANGUAGE": "ਅੰਗਰੇਜ਼ੀ",
+ "Languages:": "ਬੋਲੀਆਂ:",
+ "More posts about %s": "%s ਬਾਰੇ ਹੋਰ ਲਿਖਤਾਂ",
+ "Newer posts": "ਨਵੀਆਂ ਲਿਖਤਾਂ",
+ "Next post": "ਅਗਲੀ ਲਿਖਤ",
+ "No posts found.": "ਕੋਈ ਲਿਖਤ ਨਹੀਂ ਲੱਭੀ |",
+ "Nothing found.": "ਕੁਝ ਨਹੀਂ ਲੱਭਿਆ |",
+ "Older posts": "ਪੁਰਾਣੀਆਂ ਲਿਖਤਾਂ",
+ "Original site": "ਅਸਲ ਸਾਈਟ",
+ "Posted:": "ਲਿਖਤ ਛਪੀ:",
+ "Posts about %s": "%s ਬਾਰੇ ਲਿਖਤਾਂ",
+ "Posts for year %s": "ਸਾਲ %s ਦੀਆਂ ਲਿਖਤਾਂ",
+ "Posts for {month} {day}, {year}": "{day} {month} {year} ਦੀਆਂ ਲਿਖਤਾਂ",
+ "Posts for {month} {year}": "{month} {year} ਦੀਆਂ ਲਿਖਤਾਂ",
+ "Previous post": "ਪਿਛਲੀ ਲਿਖਤ",
+ "Publication date": "ਛਪਾਈ ਦੀ ਤਰੀਕ",
+ "RSS feed": "ਆਰ ਐੱਸ ਐੱਸ ਫੀਡ",
+ "Read in English": "ਅੰਗਰੇਜ਼ੀ ਵਿੱਚ ਪੜ੍ਹੋ",
+ "Read more": "ਹੋਰ ਪੜ੍ਹੋ",
+ "Skip to main content": "ਮੁੱਖ ਸਮੱਗਰੀ ਵੱਲ ਜਾਓ",
+ "Source": "ਮੂਲ",
+ "Subcategories:": "ਉਪਸ਼੍ਰੇਣੀਆਂ:",
+ "Tags and Categories": "ਟੈਗ ਅਤੇ ਸ਼੍ਰੇਣੀਆਂ",
+ "Tags": "ਟੈਗ",
+ "Write your page here.": "ਆਪਣਾ ਸਫ਼ਾ ਏਥੇ ਲਿਖੋ |",
+ "Write your post here.": "ਆਪਣੀ ਲਿਖਤ ਏਥੇ ਲਿਖੋ |",
+ "old posts, page %d": "ਪੁਰਾਣੀਆਂ ਲਿਖਤਾਂ , ਸਫ਼ਾ %d",
+ "page %d": "ਸਫ਼ਾ %d",
+}
diff --git a/nikola/data/themes/base/messages/messages_pt.py b/nikola/data/themes/base/messages/messages_pt.py
index fd26d77..91ea52e 100644
--- a/nikola/data/themes/base/messages/messages_pt.py
+++ b/nikola/data/themes/base/messages/messages_pt.py
@@ -2,38 +2,38 @@
from __future__ import unicode_literals
MESSAGES = {
- "%d min remaining to read": "",
- "(active)": "",
- "Also available in:": "",
- "Archive": "",
- "Categories": "",
- "Comments": "",
- "LANGUAGE": "",
- "Languages:": "",
- "More posts about %s": "",
- "Newer posts": "",
- "Next post": "",
- "No posts found.": "",
- "Nothing found.": "",
- "Older posts": "",
- "Original site": "",
- "Posted:": "",
- "Posts about %s": "",
- "Posts for year %s": "",
- "Posts for {month} {day}, {year}": "",
- "Posts for {month} {year}": "",
- "Previous post": "",
- "Publication date": "",
- "RSS feed": "",
- "Read in English": "",
- "Read more": "",
- "Skip to main content": "",
- "Source": "",
- "Subcategories:": "",
- "Tags and Categories": "",
- "Tags": "",
- "Write your page here.": "",
- "Write your post here.": "",
- "old posts, page %d": "",
- "page %d": "",
+ "%d min remaining to read": "%d minutos restante para leitura",
+ "(active)": "(ativo)",
+ "Also available in:": "Também disponível em:",
+ "Archive": "Arquivo",
+ "Categories": "Categorias",
+ "Comments": "Comentários",
+ "LANGUAGE": "Português",
+ "Languages:": "Idiomas:",
+ "More posts about %s": "Mais textos publicados sobre %s",
+ "Newer posts": "Textos publicados mais recentes",
+ "Next post": "Próximo texto publicado",
+ "No posts found.": "Nenhum texto publicado foi encontrado",
+ "Nothing found.": "Nada encontrado.",
+ "Older posts": "Textos publicados mais antigos",
+ "Original site": "Sítio original",
+ "Posted:": "Publicado:",
+ "Posts about %s": "Textos publicados sobre %s",
+ "Posts for year %s": "Textos publicados do ano %s",
+ "Posts for {month} {day}, {year}": "Textos publicados de {day} {month} {year}",
+ "Posts for {month} {year}": "Textos publicados de {month} {year}",
+ "Previous post": "Texto publicado anterior",
+ "Publication date": "Data de publicação",
+ "RSS feed": "Feed RSS",
+ "Read in English": "Ler em português",
+ "Read more": "Ler mais",
+ "Skip to main content": "Saltar para o conteúdo principal",
+ "Source": "Código",
+ "Subcategories:": "Sub-Categorias:",
+ "Tags and Categories": "Etiquetas e Categorias",
+ "Tags": "Etiqueta",
+ "Write your page here.": "Escreva a sua página aqui.",
+ "Write your post here.": "Escreva o seu texto para publicar aqui.",
+ "old posts, page %d": "Textos publicados antigos, página %d",
+ "page %d": "página %d",
}
diff --git a/nikola/data/themes/base/messages/messages_sk.py b/nikola/data/themes/base/messages/messages_sk.py
index a793ba6..acd7364 100644
--- a/nikola/data/themes/base/messages/messages_sk.py
+++ b/nikola/data/themes/base/messages/messages_sk.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
MESSAGES = {
"%d min remaining to read": "zostáva %d minút na čítanie",
- "(active)": "",
+ "(active)": "(aktívne)",
"Also available in:": "Tiež dostupné v:",
"Archive": "Archív",
"Categories": "Kategórie",
@@ -20,7 +20,7 @@ MESSAGES = {
"Posted:": "Zverejnené:",
"Posts about %s": "Príspevky o %s",
"Posts for year %s": "Príspevky z roku %s",
- "Posts for {month} {day}, {year}": "Príspevky z dňa {day}. {month} {year}",
+ "Posts for {month} {day}, {year}": "Príspevky zo dňa {day}. {month} {year}",
"Posts for {month} {year}": "Príspevky za mesiac {month} z roku {year}",
"Previous post": "Predchádzajúci príspevok",
"Publication date": "Dátum zverejnenia",
@@ -29,11 +29,11 @@ MESSAGES = {
"Read more": "Čítať ďalej",
"Skip to main content": "Skočiť na hlavný obsah",
"Source": "Zdroj",
- "Subcategories:": "",
+ "Subcategories:": "Podkategórie:",
"Tags and Categories": "Štítky a kategórie",
"Tags": "Štítky",
- "Write your page here.": "",
- "Write your post here.": "",
+ "Write your page here.": "Tu napíšte svoju stránku.",
+ "Write your post here.": "Tu napíšte svoj príspevok.",
"old posts, page %d": "staré príspevky, strana %d",
"page %d": "stránka %d",
}
diff --git a/nikola/data/themes/base/messages/messages_sr.py b/nikola/data/themes/base/messages/messages_sr.py
index 6087027..2b0aaf5 100644
--- a/nikola/data/themes/base/messages/messages_sr.py
+++ b/nikola/data/themes/base/messages/messages_sr.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
MESSAGES = {
"%d min remaining to read": "%d минута је преостало за читање",
- "(active)": "",
+ "(active)": "(активно)",
"Also available in:": "Такође доступан у:",
"Archive": "Архива",
"Categories": "Категорије",
@@ -20,7 +20,7 @@ MESSAGES = {
"Posted:": "Објављено:",
"Posts about %s": "Постови о %s",
"Posts for year %s": "Постови за годину %s",
- "Posts for {month} {day}, {year}": "",
+ "Posts for {month} {day}, {year}": "Објаве за {month} {day}, {year}",
"Posts for {month} {year}": "Постови за {month} {year}",
"Previous post": "Претходни пост",
"Publication date": "Датум објаве",
@@ -29,11 +29,11 @@ MESSAGES = {
"Read more": "Прочитај више",
"Skip to main content": "Прескочи на главни садржај",
"Source": "Извор",
- "Subcategories:": "",
+ "Subcategories:": "Подкатегорије:",
"Tags and Categories": "Тагови и категорије",
"Tags": "Тагови",
- "Write your page here.": "",
- "Write your post here.": "",
+ "Write your page here.": "Вашу страницу напишите овдје.",
+ "Write your post here.": "Вашу објаву напишите овдје.",
"old posts, page %d": "стари постови, страна %d",
"page %d": "страна %d",
}
diff --git a/nikola/data/themes/base/messages/messages_sr@latin.py b/nikola/data/themes/base/messages/messages_sr@latin.py
new file mode 100644
index 0000000..23a1f64
--- /dev/null
+++ b/nikola/data/themes/base/messages/messages_sr@latin.py
@@ -0,0 +1,39 @@
+# -*- encoding:utf-8 -*-
+from __future__ import unicode_literals
+
+MESSAGES = {
+ "%d min remaining to read": "%d minuta preostalo za čitanje",
+ "(active)": "(aktivno)",
+ "Also available in:": "Takođe dostupan u:",
+ "Archive": "Arhiva",
+ "Categories": "Kategorije",
+ "Comments": "Komentari",
+ "LANGUAGE": "Bosanski",
+ "Languages:": "Jezici:",
+ "More posts about %s": "Više objava o %s",
+ "Newer posts": "Novije objave",
+ "Next post": "Naredna objava",
+ "No posts found.": "Nema objava.",
+ "Nothing found.": "Ništa nije pronađeno.",
+ "Older posts": "Starije objave",
+ "Original site": "Izvorni sajt",
+ "Posted:": "Objavljeno:",
+ "Posts about %s": "Objave o %s",
+ "Posts for year %s": "Objave u godini %s",
+ "Posts for {month} {day}, {year}": "Objave za {month} {day}, {year}",
+ "Posts for {month} {year}": "Objave za {month} {year}",
+ "Previous post": "Prethodne objave",
+ "Publication date": "Datum objavljivanja",
+ "RSS feed": "RSS feed",
+ "Read in English": "Pročitaj na bosanskom",
+ "Read more": "Pročitaj više",
+ "Skip to main content": "Preskoči na glavni sadržaj",
+ "Source": "Izvor",
+ "Subcategories:": "Podkategorije:",
+ "Tags and Categories": "Oznake i kategorije",
+ "Tags": "Oznake",
+ "Write your page here.": "Vašu stranicu napišite ovdje.",
+ "Write your post here.": "Vašu objavu napišite ovdje.",
+ "old posts, page %d": "stare objave, strana %d",
+ "page %d": "strana %d",
+}
diff --git a/nikola/data/themes/base/messages/messages_sv.py b/nikola/data/themes/base/messages/messages_sv.py
index deda21a..52df00d 100644
--- a/nikola/data/themes/base/messages/messages_sv.py
+++ b/nikola/data/themes/base/messages/messages_sv.py
@@ -3,37 +3,37 @@ from __future__ import unicode_literals
MESSAGES = {
"%d min remaining to read": "%d minuter kvar att läsa",
- "(active)": "",
+ "(active)": "(aktiv)",
"Also available in:": "Även tillgänglig på:",
"Archive": "Arkiv",
"Categories": "Kategorier",
"Comments": "Kommentarer",
"LANGUAGE": "Svenska",
"Languages:": "Språk:",
- "More posts about %s": "Mer inlägg om %s",
+ "More posts about %s": "Fler inlägg om %s",
"Newer posts": "Nya inlägg",
"Next post": "Nästa inlägg",
- "No posts found.": "Inga inlägg hittade",
- "Nothing found.": "Inget hittat",
+ "No posts found.": "Inga inlägg hittade.",
+ "Nothing found.": "Inget hittat.",
"Older posts": "Äldre inlägg",
- "Original site": "Orgnialsida",
- "Posted:": "Publicerad",
+ "Original site": "Originalsida",
+ "Posted:": "Publicerad:",
"Posts about %s": "Inlägg om %s",
"Posts for year %s": "Inlägg för år %s",
"Posts for {month} {day}, {year}": "Inlägg för {month} {day}, {year}",
"Posts for {month} {year}": "Inlägg för {month} {year}",
"Previous post": "Föregående inlägg",
"Publication date": "Publiceringsdatum",
- "RSS feed": "RSS flöde",
- "Read in English": "Läs på Svenska",
+ "RSS feed": "RSS-flöde",
+ "Read in English": "Läs på svenska",
"Read more": "Läs mer",
- "Skip to main content": "hoppa till huvudinehåll",
+ "Skip to main content": "Hoppa till huvudinnehåll",
"Source": "Källa",
"Subcategories:": "Underkategorier:",
"Tags and Categories": "Taggar och Kategorier",
"Tags": "Taggar",
- "Write your page here.": "",
- "Write your post here.": "",
+ "Write your page here.": "Skriv din sida här.",
+ "Write your post here.": "Skriv ditt inlägg här.",
"old posts, page %d": "gamla inlägg, sida %d",
"page %d": "sida %d",
}
diff --git a/nikola/data/themes/base/messages/messages_ur.py b/nikola/data/themes/base/messages/messages_ur.py
index 075606c..074cb06 100644
--- a/nikola/data/themes/base/messages/messages_ur.py
+++ b/nikola/data/themes/base/messages/messages_ur.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
MESSAGES = {
"%d min remaining to read": "%d منٹ کا مطالعہ باقی",
- "(active)": "",
+ "(active)": "(فعال)",
"Also available in:": "ان زبانوں میں بھی دستیاب:",
"Archive": "آرکائیو",
"Categories": "زمرے",
@@ -32,8 +32,8 @@ MESSAGES = {
"Subcategories:": "ذیلی زمرے",
"Tags and Categories": "ٹیگز اور زمرے",
"Tags": "ٹیگز",
- "Write your page here.": "",
- "Write your post here.": "",
+ "Write your page here.": "اپنے صفحے کا متن یہاں لکھیں۔",
+ "Write your post here.": "اپنی تحریر یہاں لکھیں۔",
"old posts, page %d": "پرانی تحاریر صفحہ %d",
"page %d": "صفحہ %d",
}
diff --git a/nikola/data/themes/base/templates/archiveindex.tmpl b/nikola/data/themes/base/templates/archiveindex.tmpl
index 129b7c4..8c58f13 100644
--- a/nikola/data/themes/base/templates/archiveindex.tmpl
+++ b/nikola/data/themes/base/templates/archiveindex.tmpl
@@ -4,7 +4,7 @@
<%block name="extra_head">
${parent.extra_head()}
%if len(translations) > 1 and generate_atom:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/atom+xml" title="Atom for the ${archive_name} section (${language})" href="${_link("archive_atom", archive_name, language)}">
%endfor
%elif generate_atom:
diff --git a/nikola/data/themes/base/templates/base.tmpl b/nikola/data/themes/base/templates/base.tmpl
index 6da6416..2b0cbfd 100644
--- a/nikola/data/themes/base/templates/base.tmpl
+++ b/nikola/data/themes/base/templates/base.tmpl
@@ -14,13 +14,14 @@ ${template_hooks['extra_head']()}
<a href="#content" class="sr-only sr-only-focusable">${messages("Skip to main content")}</a>
<div id="container">
${header.html_header()}
- <main id="content" role="main">
+ <main id="content">
<%block name="content"></%block>
</main>
${footer.html_footer()}
</div>
+ ${base.late_load_js()}
+ <%block name="extra_js"></%block>
${body_end}
${template_hooks['body_end']()}
- ${base.late_load_js()}
</body>
</html>
diff --git a/nikola/data/themes/base/templates/base_footer.tmpl b/nikola/data/themes/base/templates/base_footer.tmpl
index 9a1c00f..cd41d37 100644
--- a/nikola/data/themes/base/templates/base_footer.tmpl
+++ b/nikola/data/themes/base/templates/base_footer.tmpl
@@ -3,7 +3,7 @@
<%def name="html_footer()">
%if content_footer:
- <footer id="footer" role="contentinfo">
+ <footer id="footer">
<p>${content_footer}</p>
${template_hooks['page_footer']()}
</footer>
diff --git a/nikola/data/themes/base/templates/base_header.tmpl b/nikola/data/themes/base/templates/base_header.tmpl
index 0c19af6..e29e2b3 100644
--- a/nikola/data/themes/base/templates/base_header.tmpl
+++ b/nikola/data/themes/base/templates/base_header.tmpl
@@ -2,7 +2,7 @@
<%namespace name="base" file="base_helper.tmpl" import="*"/>
<%def name="html_header()">
- <header id="header" role="banner">
+ <header id="header">
${html_site_title()}
${html_translation_header()}
${html_navigation_links()}
@@ -28,7 +28,7 @@
</%def>
<%def name="html_navigation_links()">
- <nav id="menu" role="navigation">
+ <nav id="menu">
<ul>
%for url, text in navigation_links[lang]:
% if isinstance(url, tuple):
diff --git a/nikola/data/themes/base/templates/base_helper.tmpl b/nikola/data/themes/base/templates/base_helper.tmpl
index 28b3f8a..948cfba 100644
--- a/nikola/data/themes/base/templates/base_helper.tmpl
+++ b/nikola/data/themes/base/templates/base_helper.tmpl
@@ -21,17 +21,20 @@ dir="rtl" \
lang="${lang}">
<head>
<meta charset="utf-8">
+ <base href="${abs_link(permalink)}">
%if description:
<meta name="description" content="${description}">
%endif
<meta name="viewport" content="width=device-width">
- <title>${title|striphtml} | ${blog_title|striphtml}</title>
+ %if title == blog_title:
+ <title>${blog_title|h}</title>
+ %else:
+ <title>${title|h} | ${blog_title|h}</title>
+ %endif
${html_stylesheets()}
${html_feedlinks()}
- %if permalink:
- <link rel="canonical" href="${abs_link(permalink)}">
- %endif
+ <link rel="canonical" href="${abs_link(permalink)}">
%if favicons:
%for name, file, size in favicons:
@@ -90,7 +93,7 @@ lang="${lang}">
${rss_link}
%elif generate_rss:
%if len(translations) > 1:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/rss+xml" title="RSS (${language})" href="${_link('rss', None, language)}">
%endfor
%else:
@@ -99,7 +102,7 @@ lang="${lang}">
%endif
%if generate_atom:
%if len(translations) > 1:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/atom+xml" title="Atom (${language})" href="${_link('index_atom', None, language)}">
%endfor
%else:
@@ -110,7 +113,7 @@ lang="${lang}">
<%def name="html_translations()">
<ul class="translations">
- %for langname in translations.keys():
+ %for langname in sorted(translations):
%if langname != lang:
<li><a href="${abs_link(_link("root", None, langname))}" rel="alternate" hreflang="${langname}">${messages("LANGUAGE", langname)}</a></li>
%endif
diff --git a/nikola/data/themes/base/templates/index.tmpl b/nikola/data/themes/base/templates/index.tmpl
index 69630e5..88bb25c 100644
--- a/nikola/data/themes/base/templates/index.tmpl
+++ b/nikola/data/themes/base/templates/index.tmpl
@@ -19,7 +19,7 @@
<h1 class="p-name entry-title"><a href="${post.permalink()}" class="u-url">${post.title()|h}</a></h1>
<div class="metadata">
<p class="byline author vcard"><span class="byline-name fn">${post.author()}</span></p>
- <p class="dateline"><a href="${post.permalink()}" rel="bookmark"><time class="published dt-published" datetime="${post.date.isoformat()}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></a></p>
+ <p class="dateline"><a href="${post.permalink()}" rel="bookmark"><time class="published dt-published" datetime="${post.formatted_date('webiso')}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></a></p>
% if not post.meta('nocomments') and site_has_comments:
<p class="commentline">${comments.comment_link(post.permalink(), post._base_path)}
% endif
diff --git a/nikola/data/themes/base/templates/list_post.tmpl b/nikola/data/themes/base/templates/list_post.tmpl
index 4fb497c..3335fa6 100644
--- a/nikola/data/themes/base/templates/list_post.tmpl
+++ b/nikola/data/themes/base/templates/list_post.tmpl
@@ -9,7 +9,7 @@
%if posts:
<ul class="postlist">
% for post in posts:
- <li><a href="${post.permalink()}" class="listtitle">${post.title()|h}</a> <time class="listdate" datetime="${post.date.isoformat()}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></li>
+ <li><a href="${post.permalink()}" class="listtitle">${post.title()|h}</a> <time class="listdate" datetime="${post.formatted_date('webiso')}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></li>
% endfor
</ul>
%else:
diff --git a/nikola/data/themes/base/templates/post_header.tmpl b/nikola/data/themes/base/templates/post_header.tmpl
index 0efb2f8..75383cb 100644
--- a/nikola/data/themes/base/templates/post_header.tmpl
+++ b/nikola/data/themes/base/templates/post_header.tmpl
@@ -12,7 +12,7 @@
% if len(post.translated_to) > 1:
<div class="metadata posttranslations translations">
<h3 class="posttranslations-intro">${messages("Also available in:")}</h3>
- % for langname in translations.keys():
+ % for langname in sorted(translations):
% if langname != lang and post.is_translation_available(langname):
<p><a href="${post.permalink(langname)}" rel="alternate" hreflang="${langname}">${messages("LANGUAGE", langname)}</a></p>
% endif
@@ -32,7 +32,7 @@
${html_title()}
<div class="metadata">
<p class="byline author vcard"><span class="byline-name fn">${post.author()}</span></p>
- <p class="dateline"><a href="${post.permalink()}" rel="bookmark"><time class="published dt-published" datetime="${post.date.isoformat()}" itemprop="datePublished" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></a></p>
+ <p class="dateline"><a href="${post.permalink()}" rel="bookmark"><time class="published dt-published" datetime="${post.formatted_date('webiso')}" itemprop="datePublished" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></a></p>
% if not post.meta('nocomments') and site_has_comments:
<p class="commentline">${comments.comment_link(post.permalink(), post._base_path)}
% endif
diff --git a/nikola/data/themes/base/templates/post_helper.tmpl b/nikola/data/themes/base/templates/post_helper.tmpl
index e091447..424d134 100644
--- a/nikola/data/themes/base/templates/post_helper.tmpl
+++ b/nikola/data/themes/base/templates/post_helper.tmpl
@@ -2,7 +2,7 @@
<%def name="meta_translations(post)">
%if len(translations) > 1:
- %for langname in translations.keys():
+ %for langname in sorted(translations):
%if langname != lang and post.is_translation_available(langname):
<link rel="alternate" hreflang="${langname}" href="${post.permalink(langname)}">
%endif
@@ -58,7 +58,7 @@
### <meta property="article:author" content="${post.author()}">
### %endif
%if post.date.isoformat():
- <meta property="article:published_time" content="${post.date.isoformat()}">
+ <meta property="article:published_time" content="${post.formatted_date('webiso')}">
%endif
%if post.tags:
%for tag in post.tags:
diff --git a/nikola/data/themes/base/templates/tag.tmpl b/nikola/data/themes/base/templates/tag.tmpl
index ec5caca..7509f3e 100644
--- a/nikola/data/themes/base/templates/tag.tmpl
+++ b/nikola/data/themes/base/templates/tag.tmpl
@@ -4,7 +4,7 @@
<%block name="extra_head">
${parent.extra_head()}
%if len(translations) > 1 and generate_rss:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/rss+xml" type="application/rss+xml" title="RSS for ${kind} ${tag} (${language})" href="${_link(kind + "_rss", tag, language)}">
%endfor
%elif generate_rss:
@@ -30,7 +30,7 @@
%endif
<div class="metadata">
%if len(translations) > 1 and generate_rss:
- %for language in translations:
+ %for language in sorted(translations):
<p class="feedlink">
<a href="${_link(kind + "_rss", tag, language)}" hreflang="${language}" type="application/rss+xml">${messages('RSS feed', language)} (${language})</a>&nbsp;
</p>
@@ -43,7 +43,7 @@
%if posts:
<ul class="postlist">
% for post in posts:
- <li><a href="${post.permalink()}" class="listtitle">${post.title()|h}</a> <time class="listdate" datetime="${post.date.isoformat()}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></li>
+ <li><a href="${post.permalink()}" class="listtitle">${post.title()|h}</a> <time class="listdate" datetime="${post.formatted_date('webiso')}" title="${post.formatted_date(date_format)}">${post.formatted_date(date_format)}</time></li>
% endfor
</ul>
%endif
diff --git a/nikola/data/themes/base/templates/tagindex.tmpl b/nikola/data/themes/base/templates/tagindex.tmpl
index 7160fe9..0834411 100644
--- a/nikola/data/themes/base/templates/tagindex.tmpl
+++ b/nikola/data/themes/base/templates/tagindex.tmpl
@@ -15,7 +15,7 @@
<%block name="extra_head">
${parent.extra_head()}
%if len(translations) > 1 and generate_atom:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/atom+xml" title="Atom for the ${tag} section (${language})" href="${_link(kind + "_atom", tag, language)}">
%endfor
%elif generate_atom:
diff --git a/nikola/data/themes/bootstrap-jinja/AUTHORS.txt b/nikola/data/themes/bootstrap-jinja/AUTHORS.txt
deleted file mode 100644
index 043d497..0000000
--- a/nikola/data/themes/bootstrap-jinja/AUTHORS.txt
+++ /dev/null
@@ -1 +0,0 @@
-Roberto Alsina <https://github.com/ralsina>
diff --git a/nikola/data/themes/bootstrap-jinja/README.md b/nikola/data/themes/bootstrap-jinja/README.md
deleted file mode 100644
index 637caf5..0000000
--- a/nikola/data/themes/bootstrap-jinja/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-A "website-done-with-bootstrap" theme, so to speak.
-
-Has a fixed navigation bar at top that displays the NAVIGATION_LINKS
-setting and supports nested menus.
-
-This theme is used in Nikola's website: https://getnikola.com
-
-Important: To fit in the bootstrap navigation bar, the search form needs the
-navbar-form and pull-left CSS classes applied. Here is an example with Nikola's
-default duckduckgo search form:
-
- SEARCH_FORM = """
- <!-- Custom search -->
- <form method="get" id="search" action="http://duckduckgo.com/" class="navbar-form pull-left">
- <input type="hidden" name="sites" value="%s"/>
- <input type="hidden" name="k8" value="#444444"/>
- <input type="hidden" name="k9" value="#D51920"/>
- <input type="hidden" name="kt" value="h"/>
- <input type="text" name="q" maxlength="255" placeholder="Search&hellip;" class="span2" style="margin-top: 4px;"/>
- <input type="submit" value="DuckDuckGo Search" style="visibility: hidden;" />
- </form>
- <!-- End of custom search -->
- """ % SITE_URL
diff --git a/nikola/data/themes/bootstrap-jinja/assets/css/theme.css b/nikola/data/themes/bootstrap-jinja/assets/css/theme.css
deleted file mode 100644
index 4fc31a8..0000000
--- a/nikola/data/themes/bootstrap-jinja/assets/css/theme.css
+++ /dev/null
@@ -1,205 +0,0 @@
-#container {
- width: 960px;
- margin: 50 auto;
-}
-
-#contentcolumn {
- max-width: 760px;
-}
-#q {
- width: 150px;
-}
-
-img {
- max-width: 90%;
-}
-
-.postbox {
- border-bottom: 2px solid darkgrey;
- margin-bottom: 12px;
-}
-
-.footerbox {padding: 15px; text-align: center; margin-bottom: 15px;}
-
-td.label {
- /* Issue #290 */
- background-color: inherit;
-}
-
-.footnote-reference {
- /* Issue 290 */
- vertical-align: super;
- font-size: xx-small;
-}
-
-.caption {
- /* Issue 292 */
- text-align: center;
- padding-top: 1em;
-}
-
-div.figure > img,
-div.figure > a > img {
- /* Issue 292 */
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-div.sidebar, div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning {
- /* Issue 277 */
- border: 1px solid #aaa;
- border-radius: 5px;
-}
-
-blockquote p, blockquote {
- font-size: 17.5px;
- font-weight: 300;
- line-height: 1.25;
-}
-
-ul.bricks > li {
- display: inline;
- background-color: lightblue;
- padding: 8px;
- border-radius: 5px;
- line-height: 3;
- white-space:nowrap;
- margin: 3px;
-}
-
-ul.breadcrumb > li:before {
- content: " / ";
-}
-
-pre, pre code {
- white-space: pre;
- word-wrap: normal;
- overflow: auto;
-}
-
-article.post-micro {
- font-family: Georgia, 'Times New Roman', Times, serif;
- font-size: 1.5em;
-}
-
-.image-block {
- display: inline-block;
-}
-
-.flowr_row {
- width: 100%;
-}
-
-.tags {
- padding-left: 0;
- margin-left: -5px;
- list-style: none;
- text-align: center;
-
-}
-
-.tags > li {
- display: inline-block;
- min-width: 10px;
- padding: 3px 7px;
- font-size: 12px;
- font-weight: bold;
- line-height: 1;
- color: #fff;
- text-align: center;
- white-space: nowrap;
- vertical-align: baseline;
- background-color: #999;
- border-radius: 10px;
-}
-
-.tags > li a {
- color: #fff;
-}
-
-.metadata p:before,
-.postlist .listdate:before {
- content: " — ";
-}
-
-.metadata p:first-of-type:before {
- content: "";
-}
-
-.metadata p {
- display: inline;
-}
-
-.posttranslations h3 {
- display: inline;
- font-size: 1em;
- font-weight: bold;
-}
-
-.posttranslations h3:last-child {
- display: none;
-}
-
-.entry-content {
- margin-top: 1em;
-}
-
-.navbar .brand {
- padding: 0 20px;
-}
-
-.navbar .brand #blog-title {
- padding: 10px 0;
- display: inline-block;
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-
-.sr-only-focusable:active,
-.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto;
-}
-
-/* hat tip bootstrap/html5 boilerplate */
-@media print {
- *, *:before, *:after {
- font-family: Garamond, Junicode, serif;
- }
-
- body {
- font-size: 12pt;
- }
-
- article .entry-title a[href]:after,
- article .metadata a[href]:after,
- article .tags a[href]:after {
- content: "";
- }
-
- article .metadata .sourceline {
- display: none;
- }
-
- article .metadata .linkline a[href]:after {
- content: " (" attr(href) ")";
- }
-
- .navbar {
- display: none;
- }
-}
diff --git a/nikola/data/themes/bootstrap-jinja/bundles b/nikola/data/themes/bootstrap-jinja/bundles
deleted file mode 120000
index 3e517bb..0000000
--- a/nikola/data/themes/bootstrap-jinja/bundles
+++ /dev/null
@@ -1 +0,0 @@
-../bootstrap/bundles \ No newline at end of file
diff --git a/nikola/data/themes/bootstrap-jinja/engine b/nikola/data/themes/bootstrap-jinja/engine
deleted file mode 100644
index 6f04b30..0000000
--- a/nikola/data/themes/bootstrap-jinja/engine
+++ /dev/null
@@ -1 +0,0 @@
-jinja
diff --git a/nikola/data/themes/bootstrap-jinja/parent b/nikola/data/themes/bootstrap-jinja/parent
deleted file mode 100644
index e9ed660..0000000
--- a/nikola/data/themes/bootstrap-jinja/parent
+++ /dev/null
@@ -1 +0,0 @@
-base-jinja
diff --git a/nikola/data/themes/bootstrap-jinja/templates/base.tmpl b/nikola/data/themes/bootstrap-jinja/templates/base.tmpl
deleted file mode 100644
index 3177276..0000000
--- a/nikola/data/themes/bootstrap-jinja/templates/base.tmpl
+++ /dev/null
@@ -1,93 +0,0 @@
-{# -*- coding: utf-8 -*- #}
-{% import 'base_helper.tmpl' as base with context %}
-{% import 'annotation_helper.tmpl' as notes with context %}
-{{ set_locale(lang) }}
-{{ base.html_headstart() }}
-{% block extra_head %}
-{# Leave this block alone. #}
-{% endblock %}
-{{ template_hooks['extra_head']() }}
-</head>
-<body>
-<a href="#content" class="sr-only sr-only-focusable">{{ messages("Skip to main content") }}</a>
-
-<!-- Menubar -->
-
-<div class="navbar navbar-static-top" id="navbar">
- <div class="navbar-inner">
- <div class="container">
-
- <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
- <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </a>
-
- <a class="brand" href="{{ abs_link(_link("root", None, lang)) }}">
- {% if logo_url %}
- <img src="{{ logo_url }}" alt="{{ blog_title }}" id="logo">
- {% endif %}
-
- {% if show_blog_title %}
- <span id="blog-title">{{ blog_title }}</span>
- {% endif %}
- </a>
- <!-- Everything you want hidden at 940px or less, place within here -->
- <div class="nav-collapse collapse">
- <ul class="nav">
- {{ base.html_navigation_links() }}
- {{ template_hooks['menu']() }}
- </ul>
- {% if search_form %}
- {{ search_form }}
- {% endif %}
- <ul class="nav pull-right">
- {% block belowtitle %}
- {% if translations|length > 1 %}
- <li>{{ base.html_translations() }}</li>
- {% endif %}
- {% endblock %}
- {% if show_sourcelink %}
- <li>{% block sourcelink %}{% endblock %}</li>
- {% endif %}
- {{ template_hooks['menu_alt']() }}
- </ul>
- </div>
- </div>
- </div>
-</div>
-<!-- End of Menubar -->
-<div class="container-fluid" id="content" role="main">
- <!--Body content-->
- <div class="row-fluid">
- <div class="span2"></div>
- <div class="span8">
- {{ template_hooks['page_header']() }}
- {% block content %}{% endblock %}
- </div>
- </div>
- <!--End of body content-->
-</div>
-<div class="footerbox">
- {{ content_footer }}
- {{ template_hooks['page_footer']() }}
-</div>
-{{ base.late_load_js() }}
- <script>$('a.image-reference:not(.islink) img:not(.islink)').parent().colorbox({rel:"gal",maxWidth:"100%",maxHeight:"100%",scalePhotos:true});</script>
- <!-- fancy dates -->
- <script>
- moment.locale("{{ momentjs_locales[lang] }}");
- fancydates({{ date_fanciness }}, {{ js_date_format }});
- </script>
- <!-- end fancy dates -->
- {% block extra_js %}{% endblock %}
- {% if annotations and post and not post.meta('noannotations') %}
- {{ notes.code() }}
- {% elif not annotations and post and post.meta('annotations') %}
- {{ notes.code() }}
- {% endif %}
-{{ body_end }}
-{{ template_hooks['body_end']() }}
-</body>
-</html>
diff --git a/nikola/data/themes/bootstrap-jinja/templates/base_helper.tmpl b/nikola/data/themes/bootstrap-jinja/templates/base_helper.tmpl
deleted file mode 100644
index 4a29e69..0000000
--- a/nikola/data/themes/bootstrap-jinja/templates/base_helper.tmpl
+++ /dev/null
@@ -1,184 +0,0 @@
-{# -*- coding: utf-8 -*- #}
-
-{% import 'annotation_helper.tmpl' as notes with context %}
-{% macro html_headstart() %}
-<!DOCTYPE html>
-<html
-
-{% if use_open_graph or (twitter_card and twitter_card['use_twitter_cards']) or (comment_system == 'facebook') %}
-prefix='
-{% if use_open_graph or (twitter_card and twitter_card['use_twitter_cards']) %}
-og: http://ogp.me/ns#
-{% endif %}
-{% if use_open_graph %}
-article: http://ogp.me/ns/article#
-{% endif %}
-{% if comment_system == 'facebook' %}
-fb: http://ogp.me/ns/fb#
-{% endif %}
-'
-{% endif %}
-
-{% if is_rtl %}
-dir="rtl"
-{% endif %}
-
-lang="{{ lang }}">
- <head>
- <meta charset="utf-8">
- {% if description %}
- <meta name="description" content="{{ description }}">
- {% endif %}
- <meta name="viewport" content="width=device-width">
- <title>{{ title|e }} | {{ blog_title|e }}</title>
-
- {{ html_stylesheets() }}
- {{ html_feedlinks() }}
- {% if permalink %}
- <link rel="canonical" href="{{ abs_link(permalink) }}">
- {% endif %}
-
- {% if favicons %}
- {% for name, file, size in favicons %}
- <link rel="{{ name }}" href="{{ file }}" sizes="{{ size }}"/>
- {% endfor %}
- {% endif %}
-
- {% if comment_system == 'facebook' %}
- <meta property="fb:app_id" content="{{ comment_system_id }}">
- {% endif %}
-
- {% if prevlink %}
- <link rel="prev" href="{{ prevlink }}" type="text/html">
- {% endif %}
- {% if nextlink %}
- <link rel="next" href="{{ nextlink }}" type="text/html">
- {% endif %}
-
- {{ mathjax_config }}
- {% if use_cdn %}
- <!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
- {% else %}
- <!--[if lt IE 9]><script src="{{ url_replacer(permalink, '/assets/js/html5.js', lang) }}"></script><![endif]-->
- {% endif %}
-
- {{ extra_head_data }}
-{% endmacro %}
-
-
-{% macro late_load_js() %}
- {% if use_bundles %}
- {% if use_cdn %}
- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
- <script src="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
- <script src="/assets/js/all.js"></script>
- {% else %}
- <script src="/assets/js/all-nocdn.js"></script>
- {% endif %}
- {% else %}
- {% if use_cdn %}
- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
- <script src="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
- {% else %}
- <script src="/assets/js/jquery.min.js"></script>
- <script src="/assets/js/bootstrap.min.js"></script>
- <script src="/assets/js/moment-with-locales.min.js"></script>
- <script src="/assets/js/fancydates.js"></script>
- {% endif %}
- <script src="/assets/js/jquery.colorbox-min.js"></script>
- {% endif %}
- {% if colorbox_locales[lang] %}
- <script src="/assets/js/colorbox-i18n/jquery.colorbox-{{ colorbox_locales[lang] }}.js"></script>
- {% endif %}
- {{ social_buttons_code }}
-{% endmacro %}
-
-
-{% macro html_stylesheets() %}
- {% if use_bundles %}
- {% if use_cdn %}
- <link href="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
- <link href="/assets/css/all.css" rel="stylesheet" type="text/css">
- {% else %}
- <link href="/assets/css/all-nocdn.css" rel="stylesheet" type="text/css">
- {% endif %}
- {% else %}
- {% if use_cdn %}
- <link href="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
- {% else %}
- <link href="/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/bootstrap-responsive.min.css" rel="stylesheet" type="text/css">
- {% endif %}
- <link href="/assets/css/rst.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/code.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/colorbox.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/theme.css" rel="stylesheet" type="text/css">
- {% if has_custom_css %}
- <link href="/assets/css/custom.css" rel="stylesheet" type="text/css">
- {% endif %}
- {% endif %}
- {% if needs_ipython_css %}
- <link href="/assets/css/ipython.min.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/nikola_ipython.css" rel="stylesheet" type="text/css">
- {% endif %}
- {% if annotations and post and not post.meta('noannotations') %}
- {{ notes.css() }}
- {% elif not annotations and post and post.meta('annotations') %}
- {{ notes.css() }}
- {% endif %}
-{% endmacro %}
-
-
-{% macro html_navigation_links() %}
- {% for url, text in navigation_links[lang] %}
- {% if isinstance(url, tuple) %}
- <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ text }}<b class="caret"></b></a>
- <ul class="dropdown-menu">
- {% for suburl, text in url %}
- {% if rel_link(permalink, suburl) == "#" %}
- <li class="active"><a href="{{ permalink }}">{{ text }} <span class="sr-only">{{ messages("(active)", lang) }}</span></a>
- {% else %}
- <li><a href="{{ suburl }}">{{ text }}</a>
- {% endif %}
- {% endfor %}
- </ul>
- {% else %}
- {% if rel_link(permalink, url) == "#" %}
- <li class="active"><a href="{{ permalink }}">{{ text }} <span class="sr-only">{{ messages("(active)", lang) }}</span></a>
- {% else %}
- <li><a href="{{ url }}">{{ text }}</a>
- {% endif %}
- {% endif %}
- {% endfor %}
-{% endmacro %}
-
-{% macro html_feedlinks() %}
- {% if rss_link %}
- {{ rss_link }}
- {% elif generate_rss %}
- {% if translations|length > 1 %}
- {% for language in translations %}
- <link rel="alternate" type="application/rss+xml" title="RSS ({{ language }})" href="{{ _link('rss', None, language) }}">
- {% endfor %}
- {% else %}
- <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ _link('rss', None) }}">
- {% endif %}
- {% endif %}
- {% if generate_atom %}
- {% if translations|length > 1 %}
- {% for language in translations %}
- <link rel="alternate" type="application/atom+xml" title="Atom ({{ language }})" href="{{ _link('index_atom', None, language) }}">
- {% endfor %}
- {% else %}
- <link rel="alternate" type="application/atom+xml" title="Atom" href="{{ _link('index_atom', None) }}">
- {% endif %}
- {% endif %}
-{% endmacro %}
-
-{% macro html_translations() %}
- {% for langname in translations.keys() %}
- {% if langname != lang %}
- <li><a href="{{ abs_link(_link("root", None, langname)) }}" rel="alternate" hreflang="{{ langname }}">{{ messages("LANGUAGE", langname) }}</a></li>
- {% endif %}
- {% endfor %}
-{% endmacro %}
diff --git a/nikola/data/themes/bootstrap-jinja/templates/gallery.tmpl b/nikola/data/themes/bootstrap-jinja/templates/gallery.tmpl
deleted file mode 100644
index 07112da..0000000
--- a/nikola/data/themes/bootstrap-jinja/templates/gallery.tmpl
+++ /dev/null
@@ -1,94 +0,0 @@
-{# -*- coding: utf-8 -*- #}
-{% extends 'base.tmpl' %}
-{% import 'comments_helper.tmpl' as comments with context %}
-{% import 'crumbs.tmpl' as ui with context %}
-{% block sourcelink %}{% endblock %}
-
-{% block content %}
- {{ ui.bar(crumbs) }}
- {% if title %}
- <h1>{{ title|e }}</h1>
- {% endif %}
- {% if post %}
- <p>
- {{ post.text() }}
- </p>
- {% endif %}
- {% if folders %}
- <ul>
- {% for folder, ftitle in folders %}
- <li><a href="{{ folder }}"><i class="icon-folder-open"></i>&nbsp;{{ ftitle }}</a></li>
- {% endfor %}
- </ul>
- {% endif %}
-
-<div id="gallery_container"></div>
-{% if photo_array %}
-<noscript>
-<ul class="thumbnails">
- {% for image in photo_array %}
- <li><a href="{{ image['url'] }}" class="thumbnail image-reference" title="{{ image['title'] }}">
- <img src="{{ image['url_thumb'] }}" alt="{{ image['title'] }}" /></a>
- {% endfor %}
-</ul>
-</noscript>
-{% endif %}
-{% if site_has_comments and enable_comments %}
-{{ comments.comment_form(None, permalink, title) }}
-{% endif %}
-{% endblock %}
-
-{% block extra_head %}
-{{ super() }}
-<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
-<style type="text/css">
- .image-block {
- display: inline-block;
- }
- .flowr_row {
- width: 100%;
- }
- </style>
-{% endblock %}
-
-
-{% block extra_js %}
-<script src="/assets/js/flowr.plugin.js"></script>
-<script>
-jsonContent = {{ photo_array_json }};
-$("#gallery_container").flowr({
- data : jsonContent,
- height : {{ thumbnail_size }}*.6,
- padding: 5,
- rows: -1,
- render : function(params) {
- // Just return a div, string or a dom object, anything works fine
- img = $("<img />").attr({
- 'src': params.itemData.url_thumb,
- 'width' : params.width,
- 'height' : params.height
- }).css('max-width', '100%');
- link = $( "<a></a>").attr({
- 'href': params.itemData.url,
- 'class': 'image-reference'
- });
- div = $("<div />").addClass('image-block').attr({
- 'title': params.itemData.title,
- 'data-toggle': "tooltip",
- });
- link.append(img);
- div.append(link);
- div.hover(div.tooltip());
- return div;
- },
- itemWidth : function(data) { return data.size.w; },
- itemHeight : function(data) { return data.size.h; },
- complete : function(params) {
- if( jsonContent.length > params.renderedItems ) {
- nextRenderList = jsonContent.slice( params.renderedItems );
- }
- }
- });
-$("a.image-reference").colorbox({rel:"gal", maxWidth:"100%",maxHeight:"100%",scalePhotos:true});
-</script>
-{% endblock %}
diff --git a/nikola/data/themes/bootstrap-jinja/templates/listing.tmpl b/nikola/data/themes/bootstrap-jinja/templates/listing.tmpl
deleted file mode 100644
index 4b99f86..0000000
--- a/nikola/data/themes/bootstrap-jinja/templates/listing.tmpl
+++ /dev/null
@@ -1,28 +0,0 @@
-{# -*- coding: utf-8 -*- #}
-{% extends 'base.tmpl' %}
-{% import 'crumbs.tmpl' as ui with context %}
-
-{% block content %}
-{{ ui.bar(crumbs) }}
-{% if folders or files %}
-<ul class="list-unstyled">
-{% for name in folders %}
- <li><a href="{{ name }}"><i class="icon-folder-open"></i> {{ name }}</a>
-{% endfor %}
-{% for name in files %}
- <li><a href="{{ name }}.html"><i class="icon-file"></i> {{ name }}</a>
-{% endfor %}
-</ul>
-{% endif %}
-{% if code %}
- {{ code }}
-{% endif %}
-{% endblock %}
-
-{% block sourcelink %}
-{% if source_link %}
- <li>
- <a href="{{ source_link }}" id="sourcelink">{{ messages("Source") }}</a>
- </li>
-{% endif %}
-{% endblock %}
diff --git a/nikola/data/themes/bootstrap-jinja/templates/slides.tmpl b/nikola/data/themes/bootstrap-jinja/templates/slides.tmpl
deleted file mode 100644
index 0ae8fe8..0000000
--- a/nikola/data/themes/bootstrap-jinja/templates/slides.tmpl
+++ /dev/null
@@ -1,24 +0,0 @@
-{% block content %}
-<div id="{{ carousel_id }}" class="carousel slide">
- <ol class="carousel-indicators">
- {% for i in range(slides_content|length) %}
- {% if i == 0 %}
- <li data-target="#{{ carousel_id }}" data-slide-to="{{ i }}" class="active"></li>
- {% else %}
- <li data-target="#{{ carousel_id }}" data-slide-to="{{ i }}"></li>
- {% endif %}
- {% endfor %}
- </ol>
- <div class="carousel-inner">
- {% for i, image in enumerate(slides_content) %}
- {% if i == 0 %}
- <div class="item active"><img src="{{ image }}" alt="" style="margin: 0 auto 0 auto;"></div>
- {% else %}
- <div class="item"><img src="{{ image }}" alt="" style="margin: 0 auto 0 auto;"></div>
- {% endif %}
- {% endfor %}
- </div>
- <a class="left carousel-control" href="#{{ carousel_id }}" data-slide="prev">&lsaquo;</a>
- <a class="right carousel-control" href="#{{ carousel_id }}" data-slide="next">&rsaquo;</a>
-</div>
-{% endblock %}
diff --git a/nikola/data/themes/bootstrap/README.md b/nikola/data/themes/bootstrap/README.md
deleted file mode 100644
index 637caf5..0000000
--- a/nikola/data/themes/bootstrap/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-A "website-done-with-bootstrap" theme, so to speak.
-
-Has a fixed navigation bar at top that displays the NAVIGATION_LINKS
-setting and supports nested menus.
-
-This theme is used in Nikola's website: https://getnikola.com
-
-Important: To fit in the bootstrap navigation bar, the search form needs the
-navbar-form and pull-left CSS classes applied. Here is an example with Nikola's
-default duckduckgo search form:
-
- SEARCH_FORM = """
- <!-- Custom search -->
- <form method="get" id="search" action="http://duckduckgo.com/" class="navbar-form pull-left">
- <input type="hidden" name="sites" value="%s"/>
- <input type="hidden" name="k8" value="#444444"/>
- <input type="hidden" name="k9" value="#D51920"/>
- <input type="hidden" name="kt" value="h"/>
- <input type="text" name="q" maxlength="255" placeholder="Search&hellip;" class="span2" style="margin-top: 4px;"/>
- <input type="submit" value="DuckDuckGo Search" style="visibility: hidden;" />
- </form>
- <!-- End of custom search -->
- """ % SITE_URL
diff --git a/nikola/data/themes/bootstrap/assets/css/theme.css b/nikola/data/themes/bootstrap/assets/css/theme.css
deleted file mode 100644
index 4fc31a8..0000000
--- a/nikola/data/themes/bootstrap/assets/css/theme.css
+++ /dev/null
@@ -1,205 +0,0 @@
-#container {
- width: 960px;
- margin: 50 auto;
-}
-
-#contentcolumn {
- max-width: 760px;
-}
-#q {
- width: 150px;
-}
-
-img {
- max-width: 90%;
-}
-
-.postbox {
- border-bottom: 2px solid darkgrey;
- margin-bottom: 12px;
-}
-
-.footerbox {padding: 15px; text-align: center; margin-bottom: 15px;}
-
-td.label {
- /* Issue #290 */
- background-color: inherit;
-}
-
-.footnote-reference {
- /* Issue 290 */
- vertical-align: super;
- font-size: xx-small;
-}
-
-.caption {
- /* Issue 292 */
- text-align: center;
- padding-top: 1em;
-}
-
-div.figure > img,
-div.figure > a > img {
- /* Issue 292 */
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-div.sidebar, div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning {
- /* Issue 277 */
- border: 1px solid #aaa;
- border-radius: 5px;
-}
-
-blockquote p, blockquote {
- font-size: 17.5px;
- font-weight: 300;
- line-height: 1.25;
-}
-
-ul.bricks > li {
- display: inline;
- background-color: lightblue;
- padding: 8px;
- border-radius: 5px;
- line-height: 3;
- white-space:nowrap;
- margin: 3px;
-}
-
-ul.breadcrumb > li:before {
- content: " / ";
-}
-
-pre, pre code {
- white-space: pre;
- word-wrap: normal;
- overflow: auto;
-}
-
-article.post-micro {
- font-family: Georgia, 'Times New Roman', Times, serif;
- font-size: 1.5em;
-}
-
-.image-block {
- display: inline-block;
-}
-
-.flowr_row {
- width: 100%;
-}
-
-.tags {
- padding-left: 0;
- margin-left: -5px;
- list-style: none;
- text-align: center;
-
-}
-
-.tags > li {
- display: inline-block;
- min-width: 10px;
- padding: 3px 7px;
- font-size: 12px;
- font-weight: bold;
- line-height: 1;
- color: #fff;
- text-align: center;
- white-space: nowrap;
- vertical-align: baseline;
- background-color: #999;
- border-radius: 10px;
-}
-
-.tags > li a {
- color: #fff;
-}
-
-.metadata p:before,
-.postlist .listdate:before {
- content: " — ";
-}
-
-.metadata p:first-of-type:before {
- content: "";
-}
-
-.metadata p {
- display: inline;
-}
-
-.posttranslations h3 {
- display: inline;
- font-size: 1em;
- font-weight: bold;
-}
-
-.posttranslations h3:last-child {
- display: none;
-}
-
-.entry-content {
- margin-top: 1em;
-}
-
-.navbar .brand {
- padding: 0 20px;
-}
-
-.navbar .brand #blog-title {
- padding: 10px 0;
- display: inline-block;
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
-
-.sr-only-focusable:active,
-.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto;
-}
-
-/* hat tip bootstrap/html5 boilerplate */
-@media print {
- *, *:before, *:after {
- font-family: Garamond, Junicode, serif;
- }
-
- body {
- font-size: 12pt;
- }
-
- article .entry-title a[href]:after,
- article .metadata a[href]:after,
- article .tags a[href]:after {
- content: "";
- }
-
- article .metadata .sourceline {
- display: none;
- }
-
- article .metadata .linkline a[href]:after {
- content: " (" attr(href) ")";
- }
-
- .navbar {
- display: none;
- }
-}
diff --git a/nikola/data/themes/bootstrap/bundles b/nikola/data/themes/bootstrap/bundles
deleted file mode 100644
index 38257d2..0000000
--- a/nikola/data/themes/bootstrap/bundles
+++ /dev/null
@@ -1,4 +0,0 @@
-assets/css/all-nocdn.css=bootstrap.css,bootstrap-responsive.css,rst.css,code.css,colorbox.css,theme.css,custom.css
-assets/css/all.css=rst.css,code.css,colorbox.css,theme.css,custom.css
-assets/js/all-nocdn.js=jquery.min.js,bootstrap.min.js,jquery.colorbox-min.js,moment-with-locales.min.js,fancydates.js
-assets/js/all.js=jquery.colorbox-min.js,moment-with-locales.min.js,fancydates.js
diff --git a/nikola/data/themes/bootstrap/engine b/nikola/data/themes/bootstrap/engine
deleted file mode 100644
index 2951cdd..0000000
--- a/nikola/data/themes/bootstrap/engine
+++ /dev/null
@@ -1 +0,0 @@
-mako
diff --git a/nikola/data/themes/bootstrap/parent b/nikola/data/themes/bootstrap/parent
deleted file mode 100644
index df967b9..0000000
--- a/nikola/data/themes/bootstrap/parent
+++ /dev/null
@@ -1 +0,0 @@
-base
diff --git a/nikola/data/themes/bootstrap/templates/base.tmpl b/nikola/data/themes/bootstrap/templates/base.tmpl
deleted file mode 100644
index e848673..0000000
--- a/nikola/data/themes/bootstrap/templates/base.tmpl
+++ /dev/null
@@ -1,93 +0,0 @@
-## -*- coding: utf-8 -*-
-<%namespace name="base" file="base_helper.tmpl" import="*" />
-<%namespace name="notes" file="annotation_helper.tmpl" import="*" />
-${set_locale(lang)}
-${base.html_headstart()}
-<%block name="extra_head">
-### Leave this block alone.
-</%block>
-${template_hooks['extra_head']()}
-</head>
-<body>
-<a href="#content" class="sr-only sr-only-focusable">${messages("Skip to main content")}</a>
-
-<!-- Menubar -->
-
-<div class="navbar navbar-static-top" id="navbar">
- <div class="navbar-inner">
- <div class="container">
-
- <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
- <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </a>
-
- <a class="brand" href="${abs_link(_link("root", None, lang))}">
- %if logo_url:
- <img src="${logo_url}" alt="${blog_title}" id="logo">
- %endif
-
- % if show_blog_title:
- <span id="blog-title">${blog_title}</span>
- % endif
- </a>
- <!-- Everything you want hidden at 940px or less, place within here -->
- <div class="nav-collapse collapse">
- <ul class="nav">
- ${base.html_navigation_links()}
- ${template_hooks['menu']()}
- </ul>
- %if search_form:
- ${search_form}
- %endif
- <ul class="nav pull-right">
- <%block name="belowtitle">
- %if len(translations) > 1:
- <li>${base.html_translations()}</li>
- %endif
- </%block>
- % if show_sourcelink:
- <li><%block name="sourcelink"></%block></li>
- %endif
- ${template_hooks['menu_alt']()}
- </ul>
- </div>
- </div>
- </div>
-</div>
-<!-- End of Menubar -->
-<div class="container-fluid" id="content" role="main">
- <!--Body content-->
- <div class="row-fluid">
- <div class="span2"></div>
- <div class="span8">
- ${template_hooks['page_header']()}
- <%block name="content"></%block>
- </div>
- </div>
- <!--End of body content-->
-</div>
-<div class="footerbox">
- ${content_footer}
- ${template_hooks['page_footer']()}
-</div>
-${base.late_load_js()}
- <script>$('a.image-reference:not(.islink) img:not(.islink)').parent().colorbox({rel:"gal",maxWidth:"100%",maxHeight:"100%",scalePhotos:true});</script>
- <!-- fancy dates -->
- <script>
- moment.locale("${momentjs_locales[lang]}");
- fancydates(${date_fanciness}, ${js_date_format});
- </script>
- <!-- end fancy dates -->
- <%block name="extra_js"></%block>
- % if annotations and post and not post.meta('noannotations'):
- ${notes.code()}
- % elif not annotations and post and post.meta('annotations'):
- ${notes.code()}
- % endif
-${body_end}
-${template_hooks['body_end']()}
-</body>
-</html>
diff --git a/nikola/data/themes/bootstrap/templates/base_helper.tmpl b/nikola/data/themes/bootstrap/templates/base_helper.tmpl
deleted file mode 100644
index 4c62f8d..0000000
--- a/nikola/data/themes/bootstrap/templates/base_helper.tmpl
+++ /dev/null
@@ -1,184 +0,0 @@
-## -*- coding: utf-8 -*-
-
-<%namespace name="notes" file="annotation_helper.tmpl" import="*" />
-<%def name="html_headstart()">
-<!DOCTYPE html>
-<html
-\
-% if use_open_graph or (twitter_card and twitter_card['use_twitter_cards']) or (comment_system == 'facebook'):
-prefix='\
-%if use_open_graph or (twitter_card and twitter_card['use_twitter_cards']):
-og: http://ogp.me/ns# \
-%endif
-%if use_open_graph:
-article: http://ogp.me/ns/article# \
-%endif
-%if comment_system == 'facebook':
-fb: http://ogp.me/ns/fb# \
-%endif
-'\
-%endif
-\
-% if is_rtl:
-dir="rtl" \
-% endif
-\
-lang="${lang}">
- <head>
- <meta charset="utf-8">
- %if description:
- <meta name="description" content="${description}">
- %endif
- <meta name="viewport" content="width=device-width">
- <title>${title|striphtml} | ${blog_title|striphtml}</title>
-
- ${html_stylesheets()}
- ${html_feedlinks()}
- %if permalink:
- <link rel="canonical" href="${abs_link(permalink)}">
- %endif
-
- %if favicons:
- %for name, file, size in favicons:
- <link rel="${name}" href="${file}" sizes="${size}"/>
- %endfor
- %endif
-
- % if comment_system == 'facebook':
- <meta property="fb:app_id" content="${comment_system_id}">
- % endif
-
- %if prevlink:
- <link rel="prev" href="${prevlink}" type="text/html">
- %endif
- %if nextlink:
- <link rel="next" href="${nextlink}" type="text/html">
- %endif
-
- ${mathjax_config}
- %if use_cdn:
- <!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
- %else:
- <!--[if lt IE 9]><script src="${url_replacer(permalink, '/assets/js/html5.js', lang)}"></script><![endif]-->
- %endif
-
- ${extra_head_data}
-</%def>
-
-
-<%def name="late_load_js()">
- %if use_bundles:
- %if use_cdn:
- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
- <script src="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
- <script src="/assets/js/all.js"></script>
- %else:
- <script src="/assets/js/all-nocdn.js"></script>
- %endif
- %else:
- %if use_cdn:
- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
- <script src="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
- %else:
- <script src="/assets/js/jquery.min.js"></script>
- <script src="/assets/js/bootstrap.min.js"></script>
- <script src="/assets/js/moment-with-locales.min.js"></script>
- <script src="/assets/js/fancydates.js"></script>
- %endif
- <script src="/assets/js/jquery.colorbox-min.js"></script>
- %endif
- %if colorbox_locales[lang]:
- <script src="/assets/js/colorbox-i18n/jquery.colorbox-${colorbox_locales[lang]}.js"></script>
- %endif
- ${social_buttons_code}
-</%def>
-
-
-<%def name="html_stylesheets()">
- %if use_bundles:
- %if use_cdn:
- <link href="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
- <link href="/assets/css/all.css" rel="stylesheet" type="text/css">
- %else:
- <link href="/assets/css/all-nocdn.css" rel="stylesheet" type="text/css">
- %endif
- %else:
- %if use_cdn:
- <link href="//maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
- %else:
- <link href="/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/bootstrap-responsive.min.css" rel="stylesheet" type="text/css">
- %endif
- <link href="/assets/css/rst.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/code.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/colorbox.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/theme.css" rel="stylesheet" type="text/css">
- %if has_custom_css:
- <link href="/assets/css/custom.css" rel="stylesheet" type="text/css">
- %endif
- %endif
- % if needs_ipython_css:
- <link href="/assets/css/ipython.min.css" rel="stylesheet" type="text/css">
- <link href="/assets/css/nikola_ipython.css" rel="stylesheet" type="text/css">
- % endif
- % if annotations and post and not post.meta('noannotations'):
- ${notes.css()}
- % elif not annotations and post and post.meta('annotations'):
- ${notes.css()}
- % endif
-</%def>
-
-
-<%def name="html_navigation_links()">
- %for url, text in navigation_links[lang]:
- % if isinstance(url, tuple):
- <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">${text}<b class="caret"></b></a>
- <ul class="dropdown-menu">
- %for suburl, text in url:
- % if rel_link(permalink, suburl) == "#":
- <li class="active"><a href="${permalink}">${text} <span class="sr-only">${messages("(active)", lang)}</span></a>
- %else:
- <li><a href="${suburl}">${text}</a>
- %endif
- %endfor
- </ul>
- % else:
- % if rel_link(permalink, url) == "#":
- <li class="active"><a href="${permalink}">${text} <span class="sr-only">${messages("(active)", lang)}</span></a>
- %else:
- <li><a href="${url}">${text}</a>
- %endif
- % endif
- %endfor
-</%def>
-
-<%def name="html_feedlinks()">
- %if rss_link:
- ${rss_link}
- %elif generate_rss:
- %if len(translations) > 1:
- %for language in translations:
- <link rel="alternate" type="application/rss+xml" title="RSS (${language})" href="${_link('rss', None, language)}">
- %endfor
- %else:
- <link rel="alternate" type="application/rss+xml" title="RSS" href="${_link('rss', None)}">
- %endif
- %endif
- %if generate_atom:
- %if len(translations) > 1:
- %for language in translations:
- <link rel="alternate" type="application/atom+xml" title="Atom (${language})" href="${_link('index_atom', None, language)}">
- %endfor
- %else:
- <link rel="alternate" type="application/atom+xml" title="Atom" href="${_link('index_atom', None)}">
- %endif
- %endif
-</%def>
-
-<%def name="html_translations()">
- %for langname in translations.keys():
- %if langname != lang:
- <li><a href="${abs_link(_link("root", None, langname))}" rel="alternate" hreflang="${langname}">${messages("LANGUAGE", langname)}</a></li>
- %endif
- %endfor
-</%def>
diff --git a/nikola/data/themes/bootstrap/templates/gallery.tmpl b/nikola/data/themes/bootstrap/templates/gallery.tmpl
deleted file mode 100644
index ab15587..0000000
--- a/nikola/data/themes/bootstrap/templates/gallery.tmpl
+++ /dev/null
@@ -1,94 +0,0 @@
-## -*- coding: utf-8 -*-
-<%inherit file="base.tmpl"/>
-<%namespace name="comments" file="comments_helper.tmpl"/>
-<%namespace name="ui" file="crumbs.tmpl" import="bar"/>
-<%block name="sourcelink"></%block>
-
-<%block name="content">
- ${ui.bar(crumbs)}
- %if title:
- <h1>${title|h}</h1>
- %endif
- %if post:
- <p>
- ${post.text()}
- </p>
- %endif
- %if folders:
- <ul>
- % for folder, ftitle in folders:
- <li><a href="${folder}"><i class="icon-folder-open"></i>&nbsp;${ftitle}</a></li>
- % endfor
- </ul>
- %endif
-
-<div id="gallery_container"></div>
-%if photo_array:
-<noscript>
-<ul class="thumbnails">
- %for image in photo_array:
- <li><a href="${image['url']}" class="thumbnail image-reference" title="${image['title']}">
- <img src="${image['url_thumb']}" alt="${image['title']}" /></a>
- %endfor
-</ul>
-</noscript>
-%endif
-%if site_has_comments and enable_comments:
-${comments.comment_form(None, permalink, title)}
-%endif
-</%block>
-
-<%block name="extra_head">
-${parent.extra_head()}
-<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
-<style type="text/css">
- .image-block {
- display: inline-block;
- }
- .flowr_row {
- width: 100%;
- }
- </style>
-</%block>
-
-
-<%block name="extra_js">
-<script src="/assets/js/flowr.plugin.js"></script>
-<script>
-jsonContent = ${photo_array_json};
-$("#gallery_container").flowr({
- data : jsonContent,
- height : ${thumbnail_size}*.6,
- padding: 5,
- rows: -1,
- render : function(params) {
- // Just return a div, string or a dom object, anything works fine
- img = $("<img />").attr({
- 'src': params.itemData.url_thumb,
- 'width' : params.width,
- 'height' : params.height
- }).css('max-width', '100%');
- link = $( "<a></a>").attr({
- 'href': params.itemData.url,
- 'class': 'image-reference'
- });
- div = $("<div />").addClass('image-block').attr({
- 'title': params.itemData.title,
- 'data-toggle': "tooltip",
- });
- link.append(img);
- div.append(link);
- div.hover(div.tooltip());
- return div;
- },
- itemWidth : function(data) { return data.size.w; },
- itemHeight : function(data) { return data.size.h; },
- complete : function(params) {
- if( jsonContent.length > params.renderedItems ) {
- nextRenderList = jsonContent.slice( params.renderedItems );
- }
- }
- });
-$("a.image-reference").colorbox({rel:"gal", maxWidth:"100%",maxHeight:"100%",scalePhotos:true});
-</script>
-</%block>
diff --git a/nikola/data/themes/bootstrap/templates/listing.tmpl b/nikola/data/themes/bootstrap/templates/listing.tmpl
deleted file mode 100644
index f03ea23..0000000
--- a/nikola/data/themes/bootstrap/templates/listing.tmpl
+++ /dev/null
@@ -1,28 +0,0 @@
-## -*- coding: utf-8 -*-
-<%inherit file="base.tmpl"/>
-<%namespace name="ui" file="crumbs.tmpl" import="bar"/>
-
-<%block name="content">
-${ui.bar(crumbs)}
-%if folders or files:
-<ul class="list-unstyled">
-% for name in folders:
- <li><a href="${name}"><i class="icon-folder-open"></i> ${name}</a>
-% endfor
-% for name in files:
- <li><a href="${name}.html"><i class="icon-file"></i> ${name}</a>
-% endfor
-</ul>
-%endif
-% if code:
- ${code}
-% endif
-</%block>
-
-<%block name="sourcelink">
-% if source_link:
- <li>
- <a href="${source_link}" id="sourcelink">${messages("Source")}</a>
- </li>
-% endif
-</%block>
diff --git a/nikola/data/themes/bootstrap/templates/slides.tmpl b/nikola/data/themes/bootstrap/templates/slides.tmpl
deleted file mode 100644
index 048fb7e..0000000
--- a/nikola/data/themes/bootstrap/templates/slides.tmpl
+++ /dev/null
@@ -1,24 +0,0 @@
-<%block name="content">
-<div id="${carousel_id}" class="carousel slide">
- <ol class="carousel-indicators">
- % for i in range(len(slides_content)):
- % if i == 0:
- <li data-target="#${carousel_id}" data-slide-to="${i}" class="active"></li>
- % else:
- <li data-target="#${carousel_id}" data-slide-to="${i}"></li>
- % endif
- % endfor
- </ol>
- <div class="carousel-inner">
- % for i, image in enumerate(slides_content):
- % if i == 0:
- <div class="item active"><img src="${image}" alt="" style="margin: 0 auto 0 auto;"></div>
- % else:
- <div class="item"><img src="${image}" alt="" style="margin: 0 auto 0 auto;"></div>
- % endif
- % endfor
- </div>
- <a class="left carousel-control" href="#${carousel_id}" data-slide="prev">&lsaquo;</a>
- <a class="right carousel-control" href="#${carousel_id}" data-slide="next">&rsaquo;</a>
-</div>
-</%block>
diff --git a/nikola/data/themes/bootstrap3-jinja/README.md b/nikola/data/themes/bootstrap3-jinja/README.md
index f008daf..10e673a 100644
--- a/nikola/data/themes/bootstrap3-jinja/README.md
+++ b/nikola/data/themes/bootstrap3-jinja/README.md
@@ -1,4 +1,4 @@
-A bootstrap3 version of the bootstrap theme.
+A theme based on Bootstrap 3.
There is a variant called bootstrap3-gradients which uses an extra CSS
file for a *visually enhanced experience* (according to Bootstrap
diff --git a/nikola/data/themes/bootstrap-jinja/assets/css/colorbox.css b/nikola/data/themes/bootstrap3-jinja/assets/css/colorbox.css
index 5f8b3b0..5f8b3b0 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/css/colorbox.css
+++ b/nikola/data/themes/bootstrap3-jinja/assets/css/colorbox.css
diff --git a/nikola/data/themes/bootstrap-jinja/assets/css/images/controls.png b/nikola/data/themes/bootstrap3-jinja/assets/css/images/controls.png
index 841a726..841a726 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/css/images/controls.png
+++ b/nikola/data/themes/bootstrap3-jinja/assets/css/images/controls.png
diff --git a/nikola/data/themes/bootstrap-jinja/assets/css/images/loading.gif b/nikola/data/themes/bootstrap3-jinja/assets/css/images/loading.gif
index b192a75..b192a75 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/css/images/loading.gif
+++ b/nikola/data/themes/bootstrap3-jinja/assets/css/images/loading.gif
diff --git a/nikola/data/themes/bootstrap3-jinja/assets/css/theme.css b/nikola/data/themes/bootstrap3-jinja/assets/css/theme.css
index 9ce6472..6964ec6 100644
--- a/nikola/data/themes/bootstrap3-jinja/assets/css/theme.css
+++ b/nikola/data/themes/bootstrap3-jinja/assets/css/theme.css
@@ -51,12 +51,6 @@ div.figure > a > img {
margin-right: auto;
}
-div.sidebar, div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning {
- /* Issue 277 */
- border: 1px solid #aaa;
- border-radius: 5px;
-}
-
blockquote p, blockquote {
font-size: 17.5px;
font-weight: 300;
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js
index f83073f..f83073f 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ar.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js
index bafc4e0..bafc4e0 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bg.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js
index 9b995d8..9b995d8 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-bn.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js
index a749232..a749232 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ca.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js
index e4a595c..e4a595c 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-cs.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js
index 1e9a1d6..1e9a1d6 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-da.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js
index 748f53b..748f53b 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-de.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js
index 1154fb5..1154fb5 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-es.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js
index 483e192..483e192 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-et.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js
index a30b13c..a30b13c 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fa.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js
index 2a7e8ad..2a7e8ad 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fi.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js
index e359290..e359290 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-fr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js
index 04fa276..04fa276 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gl.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js
index d8105ab..d8105ab 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-gr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js
index 72dddf5..72dddf5 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-he.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js
index 34aa3c0..34aa3c0 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js
index a87f03c..a87f03c 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-hu.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js
index 31053b8..31053b8 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-id.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js
index aad9d22..aad9d22 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-it.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js
index 3ea27c2..3ea27c2 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ja.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js
index 3e23b4a..3e23b4a 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-kr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js
index 374b9bb..374b9bb 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lt.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js
index 101b476..101b476 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-lv.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js
index 8e14f15..8e14f15 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-my.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js
index 2d03d48..2d03d48 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-nl.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js
index 9af0ba7..9af0ba7 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-no.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js
index 34f8ab1..34f8ab1 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pl.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
index e20bd38..e20bd38 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js
index 555f2e6..555f2e6 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ro.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js
index bac4855..bac4855 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-ru.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js
index 65b0492..65b0492 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-si.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js
index 99859fd..99859fd 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sk.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js
index c4fd9d5..c4fd9d5 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js
index d7f26e0..d7f26e0 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-sv.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js
index 86fd98f..86fd98f 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-tr.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js
index 7cd1336..7cd1336 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-uk.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
index e6c5965..e6c5965 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
index bd2254c..bd2254c 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/flowr.plugin.js b/nikola/data/themes/bootstrap3-jinja/assets/js/flowr.plugin.js
index c0d986b..c0d986b 100644
--- a/nikola/data/themes/bootstrap-jinja/assets/js/flowr.plugin.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/flowr.plugin.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/jquery.colorbox.js b/nikola/data/themes/bootstrap3-jinja/assets/js/jquery.colorbox.js
index 5ee7a90..5ee7a90 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/jquery.colorbox.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/jquery.colorbox.js
diff --git a/nikola/data/themes/bootstrap-jinja/assets/js/jquery.js b/nikola/data/themes/bootstrap3-jinja/assets/js/jquery.js
index 966173b..966173b 120000
--- a/nikola/data/themes/bootstrap-jinja/assets/js/jquery.js
+++ b/nikola/data/themes/bootstrap3-jinja/assets/js/jquery.js
diff --git a/nikola/data/themes/bootstrap3-jinja/parent b/nikola/data/themes/bootstrap3-jinja/parent
index e89c4ee..e9ed660 100644
--- a/nikola/data/themes/bootstrap3-jinja/parent
+++ b/nikola/data/themes/bootstrap3-jinja/parent
@@ -1 +1 @@
-bootstrap-jinja
+base-jinja
diff --git a/nikola/data/themes/bootstrap3-jinja/templates/base.tmpl b/nikola/data/themes/bootstrap3-jinja/templates/base.tmpl
index 058640a..46d145a 100644
--- a/nikola/data/themes/bootstrap3-jinja/templates/base.tmpl
+++ b/nikola/data/themes/bootstrap3-jinja/templates/base.tmpl
@@ -13,10 +13,10 @@
<!-- Menubar -->
-<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
+<nav class="navbar navbar-inverse navbar-static-top">
<div class="container"><!-- This keeps the margins nice -->
<div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-navbar" aria-controls="bs-navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
@@ -32,7 +32,7 @@
{% endif %}
</a>
</div><!-- /.navbar-header -->
- <div class="collapse navbar-collapse navbar-ex1-collapse">
+ <div class="collapse navbar-collapse" id="bs-navbar" aria-expanded="false">
<ul class="nav navbar-nav">
{{ base.html_navigation_links() }}
{{ template_hooks['menu']() }}
diff --git a/nikola/data/themes/bootstrap3-jinja/templates/base_helper.tmpl b/nikola/data/themes/bootstrap3-jinja/templates/base_helper.tmpl
index a481632..5ab4dcb 100644
--- a/nikola/data/themes/bootstrap3-jinja/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootstrap3-jinja/templates/base_helper.tmpl
@@ -26,17 +26,20 @@ dir="rtl"
lang="{{ lang }}">
<head>
<meta charset="utf-8">
+ <base href="{{ abs_link(permalink) }}">
{% if description %}
<meta name="description" content="{{ description }}">
{% endif %}
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>{{ title|e }} | {{ blog_title|e }}</title>
+ {% if title == blog_title %}
+ <title>{{ blog_title|e }}</title>
+ {% else %}
+ <title>{{ title|e }} | {{ blog_title|e }}</title>
+ {% endif %}
{{ html_stylesheets() }}
{{ html_feedlinks() }}
- {% if permalink %}
- <link rel="canonical" href="{{ abs_link(permalink) }}">
- {% endif %}
+ <link rel="canonical" href="{{ abs_link(permalink) }}">
{% if favicons %}
{% for name, file, size in favicons %}
@@ -129,7 +132,7 @@ lang="{{ lang }}">
{% macro html_navigation_links() %}
{% for url, text in navigation_links[lang] %}
{% if isinstance(url, tuple) %}
- <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ text }} <b class="caret"></b></a>
+ <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ text }} <b class="caret"></b></a>
<ul class="dropdown-menu">
{% for suburl, text in url %}
{% if rel_link(permalink, suburl) == "#" %}
@@ -154,7 +157,7 @@ lang="{{ lang }}">
{{ rss_link }}
{% elif generate_rss %}
{% if translations|length > 1 %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/rss+xml" title="RSS ({{ language }})" href="{{ _link('rss', None, language) }}">
{% endfor %}
{% else %}
@@ -163,7 +166,7 @@ lang="{{ lang }}">
{% endif %}
{% if generate_atom %}
{% if translations|length > 1 %}
- {% for language in translations %}
+ {% for language in translations|sort %}
<link rel="alternate" type="application/atom+xml" title="Atom ({{ language }})" href="{{ _link('index_atom', None, language) }}">
{% endfor %}
{% else %}
@@ -173,7 +176,7 @@ lang="{{ lang }}">
{% endmacro %}
{% macro html_translations() %}
- {% for langname in translations.keys() %}
+ {% for langname in translations|sort %}
{% if langname != lang %}
<li><a href="{{ abs_link(_link("root", None, langname)) }}" rel="alternate" hreflang="{{ langname }}">{{ messages("LANGUAGE", langname) }}</a></li>
{% endif %}
diff --git a/nikola/data/themes/bootstrap-jinja/templates/post.tmpl b/nikola/data/themes/bootstrap3-jinja/templates/post.tmpl
index df4109c..df4109c 100644
--- a/nikola/data/themes/bootstrap-jinja/templates/post.tmpl
+++ b/nikola/data/themes/bootstrap3-jinja/templates/post.tmpl
diff --git a/nikola/data/themes/bootstrap-jinja/templates/tags.tmpl b/nikola/data/themes/bootstrap3-jinja/templates/tags.tmpl
index c308f19..c308f19 100644
--- a/nikola/data/themes/bootstrap-jinja/templates/tags.tmpl
+++ b/nikola/data/themes/bootstrap3-jinja/templates/tags.tmpl
diff --git a/nikola/data/themes/bootstrap3/README.md b/nikola/data/themes/bootstrap3/README.md
index f008daf..10e673a 100644
--- a/nikola/data/themes/bootstrap3/README.md
+++ b/nikola/data/themes/bootstrap3/README.md
@@ -1,4 +1,4 @@
-A bootstrap3 version of the bootstrap theme.
+A theme based on Bootstrap 3.
There is a variant called bootstrap3-gradients which uses an extra CSS
file for a *visually enhanced experience* (according to Bootstrap
diff --git a/nikola/data/themes/bootstrap/assets/css/colorbox.css b/nikola/data/themes/bootstrap3/assets/css/colorbox.css
index 5f8b3b0..5f8b3b0 120000
--- a/nikola/data/themes/bootstrap/assets/css/colorbox.css
+++ b/nikola/data/themes/bootstrap3/assets/css/colorbox.css
diff --git a/nikola/data/themes/bootstrap/assets/css/images/controls.png b/nikola/data/themes/bootstrap3/assets/css/images/controls.png
index 841a726..841a726 120000
--- a/nikola/data/themes/bootstrap/assets/css/images/controls.png
+++ b/nikola/data/themes/bootstrap3/assets/css/images/controls.png
diff --git a/nikola/data/themes/bootstrap/assets/css/images/loading.gif b/nikola/data/themes/bootstrap3/assets/css/images/loading.gif
index b192a75..b192a75 120000
--- a/nikola/data/themes/bootstrap/assets/css/images/loading.gif
+++ b/nikola/data/themes/bootstrap3/assets/css/images/loading.gif
diff --git a/nikola/data/themes/bootstrap3/assets/css/theme.css b/nikola/data/themes/bootstrap3/assets/css/theme.css
index 9ce6472..6964ec6 100644
--- a/nikola/data/themes/bootstrap3/assets/css/theme.css
+++ b/nikola/data/themes/bootstrap3/assets/css/theme.css
@@ -51,12 +51,6 @@ div.figure > a > img {
margin-right: auto;
}
-div.sidebar, div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning {
- /* Issue 277 */
- border: 1px solid #aaa;
- border-radius: 5px;
-}
-
blockquote p, blockquote {
font-size: 17.5px;
font-weight: 300;
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ar.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ar.js
index f83073f..f83073f 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ar.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ar.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bg.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bg.js
index bafc4e0..bafc4e0 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bg.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bg.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bn.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bn.js
index 9b995d8..9b995d8 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-bn.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-bn.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ca.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ca.js
index a749232..a749232 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ca.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ca.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-cs.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-cs.js
index e4a595c..e4a595c 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-cs.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-cs.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-da.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-da.js
index 1e9a1d6..1e9a1d6 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-da.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-da.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-de.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-de.js
index 748f53b..748f53b 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-de.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-de.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-es.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-es.js
index 1154fb5..1154fb5 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-es.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-es.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-et.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-et.js
index 483e192..483e192 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-et.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-et.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fa.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fa.js
index a30b13c..a30b13c 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fa.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fa.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fi.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fi.js
index 2a7e8ad..2a7e8ad 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fi.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fi.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fr.js
index e359290..e359290 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-fr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-fr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gl.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gl.js
index 04fa276..04fa276 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gl.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gl.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gr.js
index d8105ab..d8105ab 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-gr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-gr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-he.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-he.js
index 72dddf5..72dddf5 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-he.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-he.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hr.js
index 34aa3c0..34aa3c0 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hu.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hu.js
index a87f03c..a87f03c 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-hu.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-hu.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-id.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-id.js
index 31053b8..31053b8 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-id.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-id.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-it.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-it.js
index aad9d22..aad9d22 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-it.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-it.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ja.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ja.js
index 3ea27c2..3ea27c2 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ja.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ja.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-kr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-kr.js
index 3e23b4a..3e23b4a 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-kr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-kr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lt.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lt.js
index 374b9bb..374b9bb 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lt.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lt.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lv.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lv.js
index 101b476..101b476 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-lv.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-lv.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-my.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-my.js
index 8e14f15..8e14f15 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-my.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-my.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-nl.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-nl.js
index 2d03d48..2d03d48 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-nl.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-nl.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-no.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-no.js
index 9af0ba7..9af0ba7 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-no.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-no.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pl.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pl.js
index 34f8ab1..34f8ab1 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pl.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pl.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
index e20bd38..e20bd38 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-pt-BR.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ro.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ro.js
index 555f2e6..555f2e6 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ro.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ro.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ru.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ru.js
index bac4855..bac4855 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-ru.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-ru.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-si.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-si.js
index 65b0492..65b0492 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-si.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-si.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sk.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sk.js
index 99859fd..99859fd 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sk.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sk.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sr.js
index c4fd9d5..c4fd9d5 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sv.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sv.js
index d7f26e0..d7f26e0 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-sv.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-sv.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-tr.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-tr.js
index 86fd98f..86fd98f 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-tr.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-tr.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-uk.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-uk.js
index 7cd1336..7cd1336 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-uk.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-uk.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
index e6c5965..e6c5965 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-CN.js
diff --git a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
index bd2254c..bd2254c 120000
--- a/nikola/data/themes/bootstrap/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
+++ b/nikola/data/themes/bootstrap3/assets/js/colorbox-i18n/jquery.colorbox-zh-TW.js
diff --git a/nikola/data/themes/bootstrap/assets/js/flowr.plugin.js b/nikola/data/themes/bootstrap3/assets/js/flowr.plugin.js
index c0d986b..c0d986b 100644
--- a/nikola/data/themes/bootstrap/assets/js/flowr.plugin.js
+++ b/nikola/data/themes/bootstrap3/assets/js/flowr.plugin.js
diff --git a/nikola/data/themes/bootstrap/assets/js/jquery.colorbox.js b/nikola/data/themes/bootstrap3/assets/js/jquery.colorbox.js
index 5ee7a90..5ee7a90 120000
--- a/nikola/data/themes/bootstrap/assets/js/jquery.colorbox.js
+++ b/nikola/data/themes/bootstrap3/assets/js/jquery.colorbox.js
diff --git a/nikola/data/themes/bootstrap/assets/js/jquery.js b/nikola/data/themes/bootstrap3/assets/js/jquery.js
index 966173b..966173b 120000
--- a/nikola/data/themes/bootstrap/assets/js/jquery.js
+++ b/nikola/data/themes/bootstrap3/assets/js/jquery.js
diff --git a/nikola/data/themes/bootstrap3/parent b/nikola/data/themes/bootstrap3/parent
index b7c200a..df967b9 100644
--- a/nikola/data/themes/bootstrap3/parent
+++ b/nikola/data/themes/bootstrap3/parent
@@ -1 +1 @@
-bootstrap
+base
diff --git a/nikola/data/themes/bootstrap3/templates/base.tmpl b/nikola/data/themes/bootstrap3/templates/base.tmpl
index 16aebce..5f90733 100644
--- a/nikola/data/themes/bootstrap3/templates/base.tmpl
+++ b/nikola/data/themes/bootstrap3/templates/base.tmpl
@@ -13,10 +13,10 @@ ${template_hooks['extra_head']()}
<!-- Menubar -->
-<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
+<nav class="navbar navbar-inverse navbar-static-top">
<div class="container"><!-- This keeps the margins nice -->
<div class="navbar-header">
- <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-navbar" aria-controls="bs-navbar" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
@@ -32,7 +32,7 @@ ${template_hooks['extra_head']()}
% endif
</a>
</div><!-- /.navbar-header -->
- <div class="collapse navbar-collapse navbar-ex1-collapse">
+ <div class="collapse navbar-collapse" id="bs-navbar" aria-expanded="false">
<ul class="nav navbar-nav">
${base.html_navigation_links()}
${template_hooks['menu']()}
diff --git a/nikola/data/themes/bootstrap3/templates/base_helper.tmpl b/nikola/data/themes/bootstrap3/templates/base_helper.tmpl
index 8ea843a..a1e7508 100644
--- a/nikola/data/themes/bootstrap3/templates/base_helper.tmpl
+++ b/nikola/data/themes/bootstrap3/templates/base_helper.tmpl
@@ -26,17 +26,20 @@ dir="rtl" \
lang="${lang}">
<head>
<meta charset="utf-8">
+ <base href="${abs_link(permalink)}">
%if description:
<meta name="description" content="${description}">
%endif
<meta name="viewport" content="width=device-width, initial-scale=1">
- <title>${title|striphtml} | ${blog_title|striphtml}</title>
+ %if title == blog_title:
+ <title>${blog_title|h}</title>
+ %else:
+ <title>${title|h} | ${blog_title|h}</title>
+ %endif
${html_stylesheets()}
${html_feedlinks()}
- %if permalink:
- <link rel="canonical" href="${abs_link(permalink)}">
- %endif
+ <link rel="canonical" href="${abs_link(permalink)}">
%if favicons:
%for name, file, size in favicons:
@@ -129,7 +132,7 @@ lang="${lang}">
<%def name="html_navigation_links()">
%for url, text in navigation_links[lang]:
% if isinstance(url, tuple):
- <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">${text} <b class="caret"></b></a>
+ <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">${text} <b class="caret"></b></a>
<ul class="dropdown-menu">
%for suburl, text in url:
% if rel_link(permalink, suburl) == "#":
@@ -154,7 +157,7 @@ lang="${lang}">
${rss_link}
%elif generate_rss:
%if len(translations) > 1:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/rss+xml" title="RSS (${language})" href="${_link('rss', None, language)}">
%endfor
%else:
@@ -163,7 +166,7 @@ lang="${lang}">
%endif
%if generate_atom:
%if len(translations) > 1:
- %for language in translations:
+ %for language in sorted(translations):
<link rel="alternate" type="application/atom+xml" title="Atom (${language})" href="${_link('index_atom', None, language)}">
%endfor
%else:
@@ -173,7 +176,7 @@ lang="${lang}">
</%def>
<%def name="html_translations()">
- %for langname in translations.keys():
+ %for langname in sorted(translations):
%if langname != lang:
<li><a href="${abs_link(_link("root", None, langname))}" rel="alternate" hreflang="${langname}">${messages("LANGUAGE", langname)}</a></li>
%endif
diff --git a/nikola/data/themes/bootstrap/templates/post.tmpl b/nikola/data/themes/bootstrap3/templates/post.tmpl
index 8d9f88a..8d9f88a 100644
--- a/nikola/data/themes/bootstrap/templates/post.tmpl
+++ b/nikola/data/themes/bootstrap3/templates/post.tmpl
diff --git a/nikola/data/themes/bootstrap/templates/tags.tmpl b/nikola/data/themes/bootstrap3/templates/tags.tmpl
index ead3b0a..ead3b0a 100644
--- a/nikola/data/themes/bootstrap/templates/tags.tmpl
+++ b/nikola/data/themes/bootstrap3/templates/tags.tmpl
diff --git a/nikola/filters.py b/nikola/filters.py
index 269aae9..4304860 100644
--- a/nikola/filters.py
+++ b/nikola/filters.py
@@ -24,7 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Utility functions to help you run filters on files."""
+"""Utility functions to help run filters on files."""
from .utils import req_missing
from functools import wraps
@@ -42,9 +42,12 @@ except ImportError:
def apply_to_binary_file(f):
- """Take a function f that transforms a data argument, and returns
+ """Apply a filter to a binary file.
+
+ Take a function f that transforms a data argument, and returns
a function that takes a filename and applies f to the contents,
- in place. Reads files in binary mode."""
+ in place. Reads files in binary mode.
+ """
@wraps(f)
def f_in_file(fname):
with open(fname, 'rb') as inf:
@@ -57,9 +60,12 @@ def apply_to_binary_file(f):
def apply_to_text_file(f):
- """Take a function f that transforms a data argument, and returns
+ """Apply a filter to a text file.
+
+ Take a function f that transforms a data argument, and returns
a function that takes a filename and applies f to the contents,
- in place. Reads files in UTF-8."""
+ in place. Reads files in UTF-8.
+ """
@wraps(f)
def f_in_file(fname):
with io.open(fname, 'r', encoding='utf-8') as inf:
@@ -72,7 +78,7 @@ def apply_to_text_file(f):
def list_replace(the_list, find, replacement):
- "Replace all occurrences of ``find`` with ``replacement`` in ``the_list``"
+ """Replace all occurrences of ``find`` with ``replacement`` in ``the_list``."""
for i, v in enumerate(the_list):
if v == find:
the_list[i] = replacement
@@ -93,7 +99,6 @@ def runinplace(command, infile):
You can also supply command as a list.
"""
-
if not isinstance(command, list):
command = shlex.split(command)
@@ -118,6 +123,7 @@ def runinplace(command, infile):
def yui_compressor(infile):
+ """Run YUI Compressor on a file."""
yuicompressor = False
try:
subprocess.call('yui-compressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
@@ -136,39 +142,48 @@ def yui_compressor(infile):
def closure_compiler(infile):
+ """Run closure-compiler on a file."""
return runinplace(r'closure-compiler --warning_level QUIET --js %1 --js_output_file %2', infile)
def optipng(infile):
+ """Run optipng on a file."""
return runinplace(r"optipng -preserve -o2 -quiet %1", infile)
def jpegoptim(infile):
+ """Run jpegoptim on a file."""
return runinplace(r"jpegoptim -p --strip-all -q %1", infile)
def html_tidy_withconfig(infile):
+ """Run HTML Tidy with tidy5.conf as config file."""
return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent -config tidy5.conf -modify %1")
def html_tidy_nowrap(infile):
+ """Run HTML Tidy without line wrapping."""
return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
def html_tidy_wrap(infile):
+ """Run HTML Tidy with line wrapping."""
return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
def html_tidy_wrap_attr(infile):
+ """Run HTML tidy with line wrapping and attribute indentation."""
return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes yes --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
def html_tidy_mini(infile):
+ """Run HTML tidy with minimal settings."""
return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --tidy-mark no --drop-empty-elements no -modify %1")
def _html_tidy_runner(infile, options):
- """ Warnings (returncode 1) are not critical, and *everything* is a warning """
+ """Run HTML Tidy."""
+ # Warnings (returncode 1) are not critical, and *everything* is a warning.
try:
status = runinplace(r"tidy5 " + options, infile)
except subprocess.CalledProcessError as err:
@@ -178,6 +193,7 @@ def _html_tidy_runner(infile, options):
@apply_to_text_file
def html5lib_minify(data):
+ """Minify with html5lib."""
import html5lib
import html5lib.serializer
data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),
@@ -193,6 +209,7 @@ def html5lib_minify(data):
@apply_to_text_file
def html5lib_xmllike(data):
+ """Transform document to an XML-like form with html5lib."""
import html5lib
import html5lib.serializer
data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),
@@ -207,11 +224,13 @@ def html5lib_xmllike(data):
@apply_to_text_file
def minify_lines(data):
+ """Do nothing -- deprecated filter."""
return data
@apply_to_text_file
def typogrify(data):
+ """Prettify text with typogrify."""
if typo is None:
req_missing(['typogrify'], 'use the typogrify filter')
@@ -226,6 +245,7 @@ def typogrify(data):
@apply_to_text_file
def typogrify_sans_widont(data):
+ """Prettify text with typogrify, skipping the widont filter."""
# typogrify with widont disabled because it caused broken headline
# wrapping, see issue #1465
if typo is None:
@@ -241,6 +261,7 @@ def typogrify_sans_widont(data):
@apply_to_text_file
def php_template_injection(data):
+ """Insert PHP code into Nikola templates."""
import re
template = re.search('<\!-- __NIKOLA_PHP_TEMPLATE_INJECTION source\:(.*) checksum\:(.*)__ -->', data)
if template:
diff --git a/nikola/image_processing.py b/nikola/image_processing.py
index 1e11a50..0ba139f 100644
--- a/nikola/image_processing.py
+++ b/nikola/image_processing.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Process images."""
+
from __future__ import unicode_literals
import datetime
import os
@@ -43,6 +45,7 @@ except ImportError:
class ImageProcessor(object):
+
"""Apply image operations."""
image_ext_list_builtin = ['.jpg', '.png', '.jpeg', '.gif', '.svg', '.bmp', '.tiff']
diff --git a/nikola/nikola.py b/nikola/nikola.py
index 2a15568..e0af7ad 100644
--- a/nikola/nikola.py
+++ b/nikola/nikola.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""The main Nikola site object."""
+
from __future__ import print_function, unicode_literals
import io
from collections import defaultdict
@@ -60,8 +62,9 @@ from .plugin_categories import (
Command,
LateTask,
PageCompiler,
- RestExtension,
+ CompilerExtension,
MarkdownExtension,
+ RestExtension,
Task,
TaskMultiplier,
TemplateSystem,
@@ -85,7 +88,7 @@ DEFAULT_TRANSLATIONS_PATTERN = '{path}.{lang}.{ext}'
config_changed = utils.config_changed
-__all__ = ['Nikola']
+__all__ = ('Nikola',)
# We store legal values for some setting here. For internal use.
LEGAL_VALUES = {
@@ -123,6 +126,7 @@ LEGAL_VALUES = {
'ko': 'Korean',
'nb': 'Norwegian Bokmål',
'nl': 'Dutch',
+ 'pa': 'Punjabi',
'pl': 'Polish',
'pt_br': 'Portuguese (Brasil)',
'ru': 'Russian',
@@ -135,6 +139,29 @@ LEGAL_VALUES = {
'uk': 'Ukrainian',
'zh_cn': 'Chinese (Simplified)',
},
+ '_WINDOWS_LOCALE_GUESSES': {
+ # TODO incomplete
+ # some languages may need that the appropiate Microsoft Language Pack be instaled.
+ "bg": "Bulgarian",
+ "ca": "Catalan",
+ "de": "German",
+ "el": "Greek",
+ "en": "English",
+ "eo": "Esperanto",
+ "es": "Spanish",
+ "fa": "Farsi", # Persian
+ "fr": "French",
+ "hr": "Croatian",
+ "it": "Italian",
+ "jp": "Japanese",
+ "nl": "Dutch",
+ "pl": "Polish",
+ "pt_br": "Portuguese_Brazil",
+ "ru": "Russian",
+ "sl_si": "Slovenian",
+ "tr_tr": "Turkish",
+ "zh_cn": "Chinese_China", # Chinese (Simplified)
+ },
'_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS': {
# This dict is used in `init` in case of locales that exist with a
# country specifier. If there is no other locale that has the same
@@ -238,7 +265,7 @@ LEGAL_VALUES = {
def _enclosure(post, lang):
- '''Default implementation of enclosures'''
+ """Add an enclosure to RSS."""
enclosure = post.meta('enclosure', lang)
if enclosure:
length = 0
@@ -256,7 +283,6 @@ class Nikola(object):
def __init__(self, **config):
"""Setup proper environment for running tasks."""
-
# Register our own path handlers
self.path_handlers = {
'slug': self.slug_path,
@@ -272,6 +298,7 @@ class Nikola(object):
self.posts_per_month = defaultdict(list)
self.posts_per_tag = defaultdict(list)
self.posts_per_category = defaultdict(list)
+ self.tags_per_language = defaultdict(list)
self.post_per_file = {}
self.timeline = []
self.pages = []
@@ -279,7 +306,7 @@ class Nikola(object):
self._template_system = None
self._THEMES = None
self.debug = DEBUG
- self.loghandlers = []
+ self.loghandlers = utils.STDERR_HANDLER # TODO remove on v8
self.colorful = config.pop('__colorful__', False)
self.invariant = config.pop('__invariant__', False)
self.quiet = config.pop('__quiet__', False)
@@ -422,7 +449,7 @@ class Nikola(object):
'TAG_PAGES_DESCRIPTIONS': {},
'TAGLIST_MINIMUM_POSTS': 1,
'TEMPLATE_FILTERS': {},
- 'THEME': 'bootstrap',
+ 'THEME': 'bootstrap3',
'THEME_REVEAL_CONFIG_SUBTHEME': 'sky',
'THEME_REVEAL_CONFIG_TRANSITION': 'cube',
'THUMBNAIL_SIZE': 180,
@@ -661,6 +688,37 @@ class Nikola(object):
self.tzinfo = dateutil.tz.gettz()
self.config['__tzinfo__'] = self.tzinfo
+ # Store raw compilers for internal use (need a copy for that)
+ self.config['_COMPILERS_RAW'] = {}
+ for k, v in self.config['COMPILERS'].items():
+ self.config['_COMPILERS_RAW'][k] = list(v)
+
+ compilers = defaultdict(set)
+ # Also add aliases for combinations with TRANSLATIONS_PATTERN
+ for compiler, exts in self.config['COMPILERS'].items():
+ for ext in exts:
+ compilers[compiler].add(ext)
+ for lang in self.config['TRANSLATIONS'].keys():
+ candidate = utils.get_translation_candidate(self.config, "f" + ext, lang)
+ compilers[compiler].add(candidate)
+
+ # Avoid redundant compilers
+ # Remove compilers that match nothing in POSTS/PAGES
+ # And put them in "bad compilers"
+ pp_exts = set([os.path.splitext(x[0])[1] for x in self.config['post_pages']])
+ self.config['COMPILERS'] = {}
+ self.disabled_compilers = {}
+ self.bad_compilers = set([])
+ for k, v in compilers.items():
+ if pp_exts.intersection(v):
+ self.config['COMPILERS'][k] = sorted(list(v))
+ else:
+ self.bad_compilers.add(k)
+
+ self._set_global_context()
+
+ def init_plugins(self, commands_only=False):
+ """Load plugins as needed."""
self.plugin_manager = PluginManager(categories_filter={
"Command": Command,
"Task": Task,
@@ -668,13 +726,14 @@ class Nikola(object):
"TemplateSystem": TemplateSystem,
"PageCompiler": PageCompiler,
"TaskMultiplier": TaskMultiplier,
- "RestExtension": RestExtension,
+ "CompilerExtension": CompilerExtension,
"MarkdownExtension": MarkdownExtension,
+ "RestExtension": RestExtension,
"SignalHandler": SignalHandler,
"ConfigPlugin": ConfigPlugin,
"PostScanner": PostScanner,
})
- self.plugin_manager.setPluginInfoExtension('plugin')
+ self.plugin_manager.getPluginLocator().setPluginInfoExtension('plugin')
extra_plugins_dirs = self.config['EXTRA_PLUGINS_DIRS']
if sys.version_info[0] == 3:
places = [
@@ -689,8 +748,36 @@ class Nikola(object):
os.path.expanduser('~/.nikola/plugins'),
] + [utils.sys_encode(path) for path in extra_plugins_dirs if path]
- self.plugin_manager.setPluginPlaces(places)
- self.plugin_manager.collectPlugins()
+ self.plugin_manager.getPluginLocator().setPluginPlaces(places)
+ self.plugin_manager.locatePlugins()
+ bad_candidates = set([])
+ for p in self.plugin_manager._candidates:
+ if commands_only:
+ if p[-1].details.has_option('Nikola', 'plugincategory'):
+ # FIXME TemplateSystem should not be needed
+ if p[-1].details.get('Nikola', 'PluginCategory') not in {'Command', 'Template'}:
+ bad_candidates.add(p)
+ else: # Not commands-only
+ # Remove compilers we don't use
+ if p[-1].name in self.bad_compilers:
+ bad_candidates.add(p)
+ self.disabled_compilers[p[-1].name] = p
+ utils.LOGGER.debug('Not loading unneeded compiler {}', p[-1].name)
+ if p[-1].name not in self.config['COMPILERS'] and \
+ p[-1].details.has_option('Nikola', 'plugincategory') and p[-1].details.get('Nikola', 'PluginCategory') == 'Compiler':
+ bad_candidates.add(p)
+ self.disabled_compilers[p[-1].name] = p
+ utils.LOGGER.debug('Not loading unneeded compiler {}', p[-1].name)
+ # Remove blacklisted plugins
+ if p[-1].name in self.config['DISABLED_PLUGINS']:
+ bad_candidates.add(p)
+ utils.LOGGER.debug('Not loading disabled plugin {}', p[-1].name)
+ # Remove compiler extensions we don't need
+ if p[-1].details.has_option('Nikola', 'compiler') and p[-1].details.get('Nikola', 'compiler') in self.disabled_compilers:
+ bad_candidates.add(p)
+ utils.LOGGER.debug('Not loading comopiler extension {}', p[-1].name)
+ self.plugin_manager._candidates = list(set(self.plugin_manager._candidates) - bad_candidates)
+ self.plugin_manager.loadPlugins()
self._activate_plugins_of_category("SignalHandler")
@@ -709,30 +796,28 @@ class Nikola(object):
self._activate_plugins_of_category("LateTask")
self._activate_plugins_of_category("TaskMultiplier")
- # Store raw compilers for internal use (need a copy for that)
- self.config['_COMPILERS_RAW'] = {}
- for k, v in self.config['COMPILERS'].items():
- self.config['_COMPILERS_RAW'][k] = list(v)
-
- compilers = defaultdict(set)
- # Also add aliases for combinations with TRANSLATIONS_PATTERN
- for compiler, exts in self.config['COMPILERS'].items():
- for ext in exts:
- compilers[compiler].add(ext)
- for lang in self.config['TRANSLATIONS'].keys():
- candidate = utils.get_translation_candidate(self.config, "f" + ext, lang)
- compilers[compiler].add(candidate)
-
- # Avoid redundant compilers
- for k, v in compilers.items():
- self.config['COMPILERS'][k] = sorted(list(v))
-
# Activate all required compiler plugins
+ self.compiler_extensions = self._activate_plugins_of_category("CompilerExtension")
for plugin_info in self.plugin_manager.getPluginsOfCategory("PageCompiler"):
if plugin_info.name in self.config["COMPILERS"].keys():
self.plugin_manager.activatePluginByName(plugin_info.name)
plugin_info.plugin_object.set_site(self)
+ # Load compiler plugins
+ self.compilers = {}
+ self.inverse_compilers = {}
+
+ for plugin_info in self.plugin_manager.getPluginsOfCategory(
+ "PageCompiler"):
+ self.compilers[plugin_info.name] = \
+ plugin_info.plugin_object
+
+ self._activate_plugins_of_category("ConfigPlugin")
+
+ signal('configured').send(self)
+
+ def _set_global_context(self):
+ """Create global context from configuration."""
self._GLOBAL_CONTEXT['url_type'] = self.config['URL_TYPE']
self._GLOBAL_CONTEXT['timezone'] = self.tzinfo
self._GLOBAL_CONTEXT['_link'] = self.link
@@ -801,41 +886,21 @@ class Nikola(object):
self._GLOBAL_CONTEXT['hidden_categories'] = self.config.get('HIDDEN_CATEGORIES')
self._GLOBAL_CONTEXT['url_replacer'] = self.url_replacer
- # IPython theme configuration. If a website can potentially have ipynb
- # posts (as determined by checking POSTS/PAGES against ipynb
- # extensions), we should enable the IPython CSS (leaving that up to the
- # theme itself).
+ # IPython theme configuration. If a website has ipynb enabled in post_pages
+ # we should enable the IPython CSS (leaving that up to the theme itself).
- self._GLOBAL_CONTEXT['needs_ipython_css'] = False
- for i in self.config['post_pages']:
- if os.path.splitext(i[0])[1] in self.config['COMPILERS'].get('ipynb', []):
- self._GLOBAL_CONTEXT['needs_ipython_css'] = True
+ self._GLOBAL_CONTEXT['needs_ipython_css'] = 'ipynb' in self.config['COMPILERS']
self._GLOBAL_CONTEXT.update(self.config.get('GLOBAL_CONTEXT', {}))
- # Load compiler plugins
- self.compilers = {}
- self.inverse_compilers = {}
-
- for plugin_info in self.plugin_manager.getPluginsOfCategory(
- "PageCompiler"):
- self.compilers[plugin_info.name] = \
- plugin_info.plugin_object
-
- self._activate_plugins_of_category("ConfigPlugin")
-
- signal('configured').send(self)
-
def _activate_plugins_of_category(self, category):
"""Activate all the plugins of a given category and return them."""
+ # this code duplicated in tests/base.py
plugins = []
for plugin_info in self.plugin_manager.getPluginsOfCategory(category):
- if plugin_info.name in self.config.get('DISABLED_PLUGINS'):
- self.plugin_manager.removePluginFromCategory(plugin_info, category)
- else:
- self.plugin_manager.activatePluginByName(plugin_info.name)
- plugin_info.plugin_object.set_site(self)
- plugins.append(plugin_info)
+ self.plugin_manager.activatePluginByName(plugin_info.name)
+ plugin_info.plugin_object.set_site(self)
+ plugins.append(plugin_info)
return plugins
def _get_themes(self):
@@ -843,8 +908,8 @@ class Nikola(object):
try:
self._THEMES = utils.get_theme_chain(self.config['THEME'])
except Exception:
- utils.LOGGER.warn('''Cannot load theme "{0}", using 'bootstrap' instead.'''.format(self.config['THEME']))
- self.config['THEME'] = 'bootstrap'
+ utils.LOGGER.warn('''Cannot load theme "{0}", using 'bootstrap3' instead.'''.format(self.config['THEME']))
+ self.config['THEME'] = 'bootstrap3'
return self._get_themes()
# Check consistency of USE_CDN and the current THEME (Issue #386)
if self.config['USE_CDN'] and self.config['USE_CDN_WARNING']:
@@ -909,11 +974,11 @@ class Nikola(object):
template_system = property(_get_template_system)
def get_compiler(self, source_name):
- """Get the correct compiler for a post from `conf.COMPILERS`
+ """Get the correct compiler for a post from `conf.COMPILERS`.
+
To make things easier for users, the mapping in conf.py is
- compiler->[extensions], although this is less convenient for us. The
- majority of this function is reversing that dictionary and error
- checking.
+ compiler->[extensions], although this is less convenient for us.
+ The majority of this function is reversing that dictionary and error checking.
"""
ext = os.path.splitext(source_name)[1]
try:
@@ -925,9 +990,9 @@ class Nikola(object):
len([ext_ for ext_ in exts if source_name.endswith(ext_)]) > 0]
if len(langs) != 1:
if len(set(langs)) > 1:
- exit("Your file extension->compiler definition is"
- "ambiguous.\nPlease remove one of the file extensions"
- "from 'COMPILERS' in conf.py\n(The error is in"
+ exit("Your file extension->compiler definition is "
+ "ambiguous.\nPlease remove one of the file extensions "
+ "from 'COMPILERS' in conf.py\n(The error is in "
"one of {0})".format(', '.join(langs)))
elif len(langs) > 1:
langs = langs[:1]
@@ -988,13 +1053,26 @@ class Nikola(object):
utils.makedirs(os.path.dirname(output_name))
parser = lxml.html.HTMLParser(remove_blank_text=True)
doc = lxml.html.document_fromstring(data, parser)
- doc.rewrite_links(lambda dst: self.url_replacer(src, dst, context['lang']))
+ self.rewrite_links(doc, src, context['lang'])
data = b'<!DOCTYPE html>\n' + lxml.html.tostring(doc, encoding='utf8', method='html', pretty_print=True)
with open(output_name, "wb+") as post_file:
post_file.write(data)
+ def rewrite_links(self, doc, src, lang):
+ """Replace links in document to point to the right places."""
+ # First let lxml replace most of them
+ doc.rewrite_links(lambda dst: self.url_replacer(src, dst, lang), resolve_base_href=False)
+
+ # lxml ignores srcset in img and source elements, so do that by hand
+ objs = list(doc.findall('*//img')) + list(doc.findall('*//source'))
+ for obj in objs:
+ if 'srcset' in obj.attrib:
+ urls = [u.strip() for u in obj.attrib['srcset'].split(',')]
+ urls = [self.url_replacer(src, dst, lang) for dst in urls]
+ obj.set('srcset', ', '.join(urls))
+
def url_replacer(self, src, dst, lang=None, url_type=None):
- """URL mangler.
+ """Mangle URLs.
* Replaces link:// URLs with real links
* Makes dst relative to src
@@ -1111,14 +1189,13 @@ class Nikola(object):
def generic_rss_renderer(self, lang, title, link, description, timeline, output_path,
rss_teasers, rss_plain, feed_length=10, feed_url=None,
enclosure=_enclosure, rss_links_append_query=None):
-
- """Takes all necessary data, and renders a RSS feed in output_path."""
+ """Take all necessary data, and render a RSS feed in output_path."""
rss_obj = utils.ExtendedRSS2(
title=title,
link=link,
description=description,
lastBuildDate=datetime.datetime.utcnow(),
- generator='http://getnikola.com/',
+ generator='https://getnikola.com/',
language=lang
)
@@ -1193,7 +1270,7 @@ class Nikola(object):
rss_file.write(data)
def path(self, kind, name, lang=None, is_link=False):
- """Build the path to a certain kind of page.
+ r"""Build the path to a certain kind of page.
These are mostly defined by plugins by registering via the
register_path_handler method, except for slug, post_path, root
@@ -1223,9 +1300,8 @@ class Nikola(object):
(ex: "/archive/index.html").
If is_link is False, the path is relative to output and uses the
platform's separator.
- (ex: "archive\\index.html")
+ (ex: "archive\index.html")
"""
-
if lang is None:
lang = utils.LocaleBorg().current_lang
@@ -1248,13 +1324,13 @@ class Nikola(object):
return ""
def post_path(self, name, lang):
- """post_path path handler"""
+ """Handle post_path paths."""
return [_f for _f in [self.config['TRANSLATIONS'][lang],
os.path.dirname(name),
self.config['INDEX_FILE']] if _f]
def root_path(self, name, lang):
- """root_path path handler"""
+ """Handle root_path paths."""
d = self.config['TRANSLATIONS'][lang]
if d:
return [d, '']
@@ -1262,7 +1338,7 @@ class Nikola(object):
return []
def slug_path(self, name, lang):
- """slug path handler"""
+ """Handle slug paths."""
results = [p for p in self.timeline if p.meta('slug') == name]
if not results:
utils.LOGGER.warning("Cannot resolve path request for slug: {0}".format(name))
@@ -1272,7 +1348,7 @@ class Nikola(object):
return [_f for _f in results[0].permalink(lang).split('/') if _f]
def filename_path(self, name, lang):
- """filename path handler"""
+ """Handle filename paths."""
results = [p for p in self.timeline if p.source_path == name]
if not results:
utils.LOGGER.warning("Cannot resolve path request for filename: {0}".format(name))
@@ -1282,15 +1358,18 @@ class Nikola(object):
return [_f for _f in results[0].permalink(lang).split('/') if _f]
def register_path_handler(self, kind, f):
+ """Register a path handler."""
if kind in self.path_handlers:
utils.LOGGER.warning('Conflicting path handlers for kind: {0}'.format(kind))
else:
self.path_handlers[kind] = f
def link(self, *args):
+ """Create a link."""
return self.path(*args, is_link=True)
def abs_link(self, dst, protocol_relative=False):
+ """Get an absolute link."""
# Normalize
if dst: # Mako templates and empty strings evaluate to False
dst = urljoin(self.config['BASE_URL'], dst.lstrip('/'))
@@ -1302,6 +1381,7 @@ class Nikola(object):
return url
def rel_link(self, src, dst):
+ """Get a relative link."""
# Normalize
src = urljoin(self.config['BASE_URL'], src)
dst = urljoin(src, dst)
@@ -1326,8 +1406,7 @@ class Nikola(object):
return '/'.join(['..'] * (len(src_elems) - i - 1) + dst_elems[i:])
def file_exists(self, path, not_empty=False):
- """Returns True if the file exists. If not_empty is True,
- it also has to be not empty."""
+ """Check if the file exists. If not_empty is True, it also must not be empty."""
exists = os.path.exists(path)
if exists and not_empty:
exists = os.stat(path).st_size > 0
@@ -1341,8 +1420,9 @@ class Nikola(object):
return task
def gen_tasks(self, name, plugin_category, doc=''):
-
+ """Generate tasks."""
def flatten(task):
+ """Flatten lists of tasks."""
if isinstance(task, dict):
yield task
else:
@@ -1377,6 +1457,7 @@ class Nikola(object):
}
def parse_category_name(self, category_name):
+ """Parse a category name into a hierarchy."""
if self.config['CATEGORY_ALLOW_HIERARCHIES']:
try:
return utils.parse_escaped_hierarchical_category_name(category_name)
@@ -1387,12 +1468,14 @@ class Nikola(object):
return [category_name] if len(category_name) > 0 else []
def category_path_to_category_name(self, category_path):
+ """Translate a category path to a category name."""
if self.config['CATEGORY_ALLOW_HIERARCHIES']:
return utils.join_hierarchical_category_path(category_path)
else:
return ''.join(category_path)
def _add_post_to_category(self, post, category_name):
+ """Add a post to a category."""
category_path = self.parse_category_name(category_name)
current_path = []
current_subtree = self.category_hierarchy
@@ -1404,10 +1487,12 @@ class Nikola(object):
self.posts_per_category[self.category_path_to_category_name(current_path)].append(post)
def _sort_category_hierarchy(self):
+ """Sort category hierarchy."""
# First create a hierarchy of TreeNodes
self.category_hierarchy_lookup = {}
def create_hierarchy(cat_hierarchy, parent=None):
+ """Create category hierarchy."""
result = []
for name, children in cat_hierarchy.items():
node = utils.TreeNode(name, parent)
@@ -1426,7 +1511,7 @@ class Nikola(object):
def scan_posts(self, really=False, ignore_quit=False, quiet=False):
"""Scan all the posts.
- Ignoring quiet.
+ The `quiet` option is ignored.
"""
if self._scanned and not really:
return
@@ -1438,6 +1523,7 @@ class Nikola(object):
self.posts_per_month = defaultdict(list)
self.posts_per_tag = defaultdict(list)
self.posts_per_category = defaultdict(list)
+ self.tags_per_language = defaultdict(list)
self.category_hierarchy = {}
self.post_per_file = {}
self.timeline = []
@@ -1470,6 +1556,8 @@ class Nikola(object):
else:
slugged_tags.add(utils.slugify(tag, force=True))
self.posts_per_tag[tag].append(post)
+ for lang in self.config['TRANSLATIONS'].keys():
+ self.tags_per_language[lang].extend(post.tags_for_language(lang))
self._add_post_to_category(post, post.meta('category'))
if post.is_post:
@@ -1495,6 +1583,8 @@ class Nikola(object):
quit = True
self.post_per_file[dest] = post
self.post_per_file[src_dest] = post
+ # deduplicate tags_per_language
+ self.tags_per_language[lang] = list(set(self.tags_per_language[lang]))
# Sort everything.
@@ -1514,9 +1604,9 @@ class Nikola(object):
sys.exit(1)
signal('scanned').send(self)
- def generic_page_renderer(self, lang, post, filters):
+ def generic_page_renderer(self, lang, post, filters, context=None):
"""Render post fragments to final HTML pages."""
- context = {}
+ context = context.copy() if context else {}
deps = post.deps(lang) + \
self.template_system.template_deps(post.template_name)
deps.extend(utils.get_asset_path(x, self.THEMES) for x in ('bundles', 'parent', 'engine'))
@@ -1526,6 +1616,8 @@ class Nikola(object):
context['title'] = post.title(lang)
context['description'] = post.description(lang)
context['permalink'] = post.permalink(lang)
+ if 'pagekind' not in context:
+ context['pagekind'] = ['generic_page']
if post.use_in_feeds:
context['enable_comments'] = True
else:
@@ -1557,7 +1649,7 @@ class Nikola(object):
task = {
'name': os.path.normpath(output_name),
- 'file_dep': deps,
+ 'file_dep': sorted(deps),
'targets': [output_name],
'actions': [(self.render_template, [post.template_name,
output_name, context])],
@@ -1569,9 +1661,9 @@ class Nikola(object):
def generic_post_list_renderer(self, lang, posts, output_name,
template_name, filters, extra_context):
- """Renders pages with lists of posts."""
-
- deps = self.template_system.template_deps(template_name)
+ """Render pages with lists of posts."""
+ deps = []
+ deps += self.template_system.template_deps(template_name)
uptodate_deps = []
for post in posts:
deps += post.deps(lang)
@@ -1600,7 +1692,7 @@ class Nikola(object):
task = {
'name': os.path.normpath(output_name),
'targets': [output_name],
- 'file_dep': deps,
+ 'file_dep': sorted(deps),
'actions': [(self.render_template, [template_name, output_name,
context])],
'clean': True,
@@ -1611,9 +1703,10 @@ class Nikola(object):
def atom_feed_renderer(self, lang, posts, output_path, filters,
extra_context):
- """Renders Atom feeds and archives with lists of posts. Feeds are
- considered archives when no future updates to them are expected"""
+ """Render Atom feeds and archives with lists of posts.
+ Feeds are considered archives when no future updates to them are expected.
+ """
def atom_link(link_rel, link_type, link_href):
link = lxml.etree.Element("link")
link.set("rel", link_rel)
@@ -1662,7 +1755,7 @@ class Nikola(object):
feed_id = lxml.etree.SubElement(feed_root, "id")
feed_id.text = self.abs_link(context["feedlink"])
feed_updated = lxml.etree.SubElement(feed_root, "updated")
- feed_updated.text = datetime.datetime.now(tz=dateutil.tz.tzutc()).replace(microsecond=0).isoformat()
+ feed_updated.text = post.formatted_date('webiso', datetime.datetime.now(tz=dateutil.tz.tzutc()))
feed_author = lxml.etree.SubElement(feed_root, "author")
feed_author_name = lxml.etree.SubElement(feed_author, "name")
feed_author_name.text = self.config["BLOG_AUTHOR"](lang)
@@ -1726,9 +1819,9 @@ class Nikola(object):
entry_id = lxml.etree.SubElement(entry_root, "id")
entry_id.text = post.permalink(lang, absolute=True)
entry_updated = lxml.etree.SubElement(entry_root, "updated")
- entry_updated.text = post.updated.isoformat()
+ entry_updated.text = post.formatted_updated('webiso')
entry_published = lxml.etree.SubElement(entry_root, "published")
- entry_published.text = post.date.isoformat()
+ entry_published.text = post.formatted_date('webiso')
entry_author = lxml.etree.SubElement(entry_root, "author")
entry_author_name = lxml.etree.SubElement(entry_author, "name")
entry_author_name.text = post.author(lang)
@@ -1757,7 +1850,7 @@ class Nikola(object):
atom_file.write(data)
def generic_index_renderer(self, lang, posts, indexes_title, template_name, context_source, kw, basename, page_link, page_path, additional_dependencies=[]):
- """Creates an index page.
+ """Create an index page.
lang: The language
posts: A list of posts
@@ -1812,6 +1905,8 @@ class Nikola(object):
num_pages = len(lists)
for i, post_list in enumerate(lists):
context = context_source.copy()
+ if 'pagekind' not in context:
+ context['pagekind'] = ['index']
ipages_i = utils.get_displayed_page_number(i, num_pages, self)
if kw["indexes_pages"]:
indexes_pages = kw["indexes_pages"] % ipages_i
@@ -1885,8 +1980,8 @@ class Nikola(object):
context["feedpagecount"] = num_pages
atom_task = {
"basename": basename,
- "file_dep": [output_name],
"name": atom_output_name,
+ "file_dep": sorted([_.base_path for _ in post_list]),
"targets": [atom_output_name],
"actions": [(self.atom_feed_renderer,
(lang,
@@ -1913,11 +2008,12 @@ class Nikola(object):
}, kw["filters"])
def __repr__(self):
+ """Representation of a Nikola site."""
return '<Nikola Site: {0!r}>'.format(self.config['BLOG_TITLE']())
def sanitized_locales(locale_fallback, locale_default, locales, translations):
- """Sanitizes all locales availble into a nikola session
+ """Sanitize all locales availble in Nikola.
There will be one locale for each language in translations.
@@ -1994,10 +2090,7 @@ def sanitized_locales(locale_fallback, locale_default, locales, translations):
def is_valid_locale(locale_n):
- """True if locale_n is acceptable for locale.setlocale
-
- for py2x compat locale_n should be of type str
- """
+ """Check if locale (type str) is valid."""
try:
locale.setlocale(locale.LC_ALL, locale_n)
return True
@@ -2006,7 +2099,7 @@ def is_valid_locale(locale_n):
def valid_locale_fallback(desired_locale=None):
- """returns a default fallback_locale, a string that locale.setlocale will accept
+ """Provide a default fallback_locale, a string that locale.setlocale will accept.
If desired_locale is provided must be of type str for py2x compatibility
"""
@@ -2032,13 +2125,15 @@ def valid_locale_fallback(desired_locale=None):
def guess_locale_from_lang_windows(lang):
- locale_n = str(_windows_locale_guesses.get(lang, None))
+ """Guess a locale, basing on Windows language."""
+ locale_n = str(LEGAL_VALUES['_WINDOWS_LOCALE_GUESSES'].get(lang, None))
if not is_valid_locale(locale_n):
locale_n = None
return locale_n
def guess_locale_from_lang_posix(lang):
+ """Guess a locale, basing on POSIX system language."""
# compatibility v6.0.4
if is_valid_locale(str(lang)):
locale_n = str(lang)
@@ -2065,28 +2160,3 @@ def workaround_empty_LC_ALL_posix():
os.environ['LC_ALL'] = lc_time
except Exception:
pass
-
-
-_windows_locale_guesses = {
- # some languages may need that the appropiate Microsoft's Language Pack
- # be instaled; the 'str' bit will be added in the guess function
- "bg": "Bulgarian",
- "ca": "Catalan",
- "de": "German",
- "el": "Greek",
- "en": "English",
- "eo": "Esperanto",
- "es": "Spanish",
- "fa": "Farsi", # Persian
- "fr": "French",
- "hr": "Croatian",
- "it": "Italian",
- "jp": "Japanese",
- "nl": "Dutch",
- "pl": "Polish",
- "pt_br": "Portuguese_Brazil",
- "ru": "Russian",
- "sl_si": "Slovenian",
- "tr_tr": "Turkish",
- "zh_cn": "Chinese_China", # Chinese (Simplified)
-}
diff --git a/nikola/packages/__init__.py b/nikola/packages/__init__.py
index 0a704f5..34beaea 100644
--- a/nikola/packages/__init__.py
+++ b/nikola/packages/__init__.py
@@ -1 +1 @@
-# Packages vendored in by Nikola.
+"""Third-party packages for Nikola."""
diff --git a/nikola/packages/tzlocal/__init__.py b/nikola/packages/tzlocal/__init__.py
index 10716ec..4a6b1d6 100644
--- a/nikola/packages/tzlocal/__init__.py
+++ b/nikola/packages/tzlocal/__init__.py
@@ -1,3 +1,5 @@
+"""tzlocal init."""
+
import sys
if sys.platform == 'win32':
from .win32 import get_localzone, reload_localzone # NOQA
diff --git a/nikola/packages/tzlocal/darwin.py b/nikola/packages/tzlocal/darwin.py
index 8bfe807..0dbf1c1 100644
--- a/nikola/packages/tzlocal/darwin.py
+++ b/nikola/packages/tzlocal/darwin.py
@@ -1,4 +1,5 @@
-from __future__ import with_statement
+"""tzlocal for OS X."""
+
import os
import dateutil.tz
import subprocess
diff --git a/nikola/packages/tzlocal/unix.py b/nikola/packages/tzlocal/unix.py
index 4cd3752..8f7fc84 100644
--- a/nikola/packages/tzlocal/unix.py
+++ b/nikola/packages/tzlocal/unix.py
@@ -1,3 +1,5 @@
+"""tzlocal for UNIX."""
+
from __future__ import with_statement
import os
import re
@@ -7,7 +9,7 @@ _cache_tz = None
def _get_localzone():
- """Tries to find the local timezone configuration.
+ """Try to find the local timezone configuration.
This method prefers finding the timezone name and passing that to pytz,
over passing in the localtime file, as in the later case the zoneinfo
@@ -15,8 +17,8 @@ def _get_localzone():
The parameter _root makes the function look for files like /etc/localtime
beneath the _root directory. This is primarily used by the tests.
- In normal usage you call the function without parameters."""
-
+ In normal usage you call the function without parameters.
+ """
tz = os.environ.get('TZ')
if tz and tz[0] == ':':
tz = tz[1:]
diff --git a/nikola/packages/tzlocal/win32.py b/nikola/packages/tzlocal/win32.py
index 7005422..cb19284 100644
--- a/nikola/packages/tzlocal/win32.py
+++ b/nikola/packages/tzlocal/win32.py
@@ -1,3 +1,5 @@
+"""tzlocal for Windows."""
+
try:
import _winreg as winreg
except ImportError:
@@ -22,6 +24,7 @@ def valuestodict(key):
def get_localzone_name():
+ """Get local time zone name."""
# Windows is special. It has unique time zone names (in several
# meanings of the word) available, but unfortunately, they can be
# translated to the language of the operating system, so we need to
@@ -78,7 +81,7 @@ def get_localzone_name():
def get_localzone():
- """Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
+ """Return the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
global _cache_tz
if _cache_tz is None:
_cache_tz = get_localzone_name()
diff --git a/nikola/packages/tzlocal/windows_tz.py b/nikola/packages/tzlocal/windows_tz.py
index 1084478..c171aa5 100644
--- a/nikola/packages/tzlocal/windows_tz.py
+++ b/nikola/packages/tzlocal/windows_tz.py
@@ -1,3 +1,4 @@
+"""Windows timezone names."""
# This file is autogenerated by the get_windows_info.py script
# Do not edit.
win_tz = {
diff --git a/nikola/plugin_categories.py b/nikola/plugin_categories.py
index e9af6b5..ecbbb82 100644
--- a/nikola/plugin_categories.py
+++ b/nikola/plugin_categories.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Nikola plugin categories."""
+
from __future__ import absolute_import
import sys
import os
@@ -34,7 +36,7 @@ from doit.cmd_base import Command as DoitCommand
from .utils import LOGGER, first_line
-__all__ = [
+__all__ = (
'Command',
'LateTask',
'PageCompiler',
@@ -46,22 +48,20 @@ __all__ = [
'SignalHandler',
'ConfigPlugin',
'PostScanner',
-]
+)
class BasePlugin(IPlugin):
+
"""Base plugin class."""
def set_site(self, site):
- """Sets site, which is a Nikola instance."""
+ """Set site, which is a Nikola instance."""
self.site = site
self.inject_templates()
def inject_templates(self):
- """If this plugin contains a 'templates' folder,
- then templates/mako or templates/jinja will be inserted very early in
- the theme chain."""
-
+ """Inject 'templates/<engine>' (if exists) very early in the theme chain."""
try:
# Sorry, found no other way to get this
mod_path = sys.modules[self.__class__.__module__].__file__
@@ -79,21 +79,22 @@ class BasePlugin(IPlugin):
pass
def inject_dependency(self, target, dependency):
- """Add 'dependency' to the target task's task_deps"""
+ """Add 'dependency' to the target task's task_deps."""
self.site.injected_deps[target].append(dependency)
class PostScanner(BasePlugin):
+
"""The scan method of these plugins is called by Nikola.scan_posts."""
def scan(self):
- """Creates a list of posts from some source. Returns a list of Post objects."""
+ """Create a list of posts from some source. Returns a list of Post objects."""
raise NotImplementedError()
class Command(BasePlugin, DoitCommand):
- """These plugins are exposed via the command line.
- They implement the doit Command interface."""
+
+ """Doit command implementation."""
name = "dummy_command"
@@ -105,17 +106,18 @@ class Command(BasePlugin, DoitCommand):
needs_config = True
def __init__(self, *args, **kwargs):
+ """Initialize a command."""
BasePlugin.__init__(self, *args, **kwargs)
DoitCommand.__init__(self)
def __call__(self, config=None, **kwargs):
+ """Reset doit arguments (workaround)."""
self._doitargs = kwargs
DoitCommand.__init__(self, config, **kwargs)
return self
def execute(self, options=None, args=None):
- """Check if the command can run in the current environment,
- fail if needed, or call _execute."""
+ """Check if the command can run in the current environment, fail if needed, or call _execute."""
options = options or {}
args = args or []
@@ -126,6 +128,7 @@ class Command(BasePlugin, DoitCommand):
def _execute(self, options, args):
"""Do whatever this command does.
+
@param options (dict) with values from cmd_options
@param args (list) list of positional arguments
"""
@@ -133,7 +136,7 @@ class Command(BasePlugin, DoitCommand):
def help(self):
- """return help text"""
+ """Return help text for a command."""
text = []
text.append("Purpose: %s" % self.doc_purpose)
text.append("Usage: nikola %s %s" % (self.name, self.doc_usage))
@@ -153,7 +156,8 @@ DoitCommand.help = help
class BaseTask(BasePlugin):
- """Plugins of this type are task generators."""
+
+ """Base for task generators."""
name = "dummy_task"
@@ -162,11 +166,11 @@ class BaseTask(BasePlugin):
is_default = True
def gen_tasks(self):
- """Task generator."""
+ """Generate tasks."""
raise NotImplementedError()
def group_task(self):
- """dict for group task"""
+ """Return dict for group task."""
return {
'basename': self.name,
'name': None,
@@ -175,32 +179,35 @@ class BaseTask(BasePlugin):
class Task(BaseTask):
- """Plugins of this type are task generators."""
+
+ """Task generator."""
name = "dummy_task"
class LateTask(BaseTask):
- """Plugins of this type are executed after all plugins of type Task."""
+
+ """Late task generator (plugin executed after all Task plugins)."""
name = "dummy_latetask"
class TemplateSystem(BasePlugin):
- """Plugins of this type wrap templating systems."""
+
+ """Provide support for templating systems."""
name = "dummy_templates"
def set_directories(self, directories, cache_folder):
- """Sets the list of folders where templates are located and cache."""
+ """Set the list of folders where templates are located and cache."""
raise NotImplementedError()
def template_deps(self, template_name):
- """Returns filenames which are dependencies for a template."""
+ """Return filenames which are dependencies for a template."""
raise NotImplementedError()
def render_template(self, template_name, output_name, context):
- """Renders template to a file using context.
+ """Render template to a file using context.
This must save the data to output_name *and* return it
so that the caller may do additional processing.
@@ -208,28 +215,28 @@ class TemplateSystem(BasePlugin):
raise NotImplementedError()
def render_template_to_string(self, template, context):
- """Renders template to a string using context. """
+ """Render template to a string using context."""
raise NotImplementedError()
def inject_directory(self, directory):
- """Injects the directory with the lowest priority in the
- template search mechanism."""
+ """Inject the directory with the lowest priority in the template search mechanism."""
raise NotImplementedError()
class TaskMultiplier(BasePlugin):
- """Plugins that take a task and return *more* tasks."""
+
+ """Take a task and return *more* tasks."""
name = "dummy multiplier"
def process(self, task):
- """Examine task and create more tasks.
- Returns extra tasks only."""
+ """Examine task and create more tasks. Returns extra tasks only."""
return []
class PageCompiler(BasePlugin):
- """Plugins that compile text files into HTML."""
+
+ """Compile text files into HTML."""
name = "dummy_compiler"
friendly_name = ''
@@ -251,7 +258,8 @@ class PageCompiler(BasePlugin):
"""Add additional dependencies to the post object.
Current main use is the ReST page compiler, which puts extra
- dependencies into a .deb file."""
+ dependencies into a .dep file.
+ """
pass
def compile_html(self, source, dest, is_two_file=False):
@@ -267,41 +275,81 @@ class PageCompiler(BasePlugin):
return ".html"
def read_metadata(self, post, file_metadata_regexp=None, unslugify_titles=False, lang=None):
- """
- Read the metadata from a post, and return a metadata dict
- """
+ """Read the metadata from a post, and return a metadata dict."""
return {}
def split_metadata(self, data):
"""Split data from metadata in the raw post content.
This splits in the first empty line that is NOT at the beginning
- of the document."""
+ of the document.
+ """
split_result = re.split('(\n\n|\r\n\r\n)', data.lstrip(), maxsplit=1)
if len(split_result) == 1:
return '', split_result[0]
# ['metadata', '\n\n', 'post content']
return split_result[0], split_result[-1]
+ def get_compiler_extensions(self):
+ """Activate all the compiler extension plugins for a given compiler and return them."""
+ plugins = []
+ for plugin_info in self.site.compiler_extensions:
+ if plugin_info.plugin_object.compiler_name == self.name:
+ plugins.append(plugin_info)
+ return plugins
+
+
+class CompilerExtension(BasePlugin):
+
+ """An extension for a Nikola compiler.
+
+ If you intend to implement those in your own compiler, you can:
+ (a) create a new plugin class for them; or
+ (b) use this class and filter them yourself.
+ If you choose (b), you should the compiler name to the .plugin
+ file in the Nikola/Compiler section and filter all plugins of
+ this category, getting the compiler name with:
+ p.details.get('Nikola', 'Compiler')
+ Note that not all compiler plugins have this option and you might
+ need to catch configparser.NoOptionError exceptions.
+ """
+
+ name = "dummy_compiler_extension"
+ compiler_name = "dummy_compiler"
+
+
+class RestExtension(CompilerExtension):
+
+ """Extensions for reStructuredText."""
-class RestExtension(BasePlugin):
name = "dummy_rest_extension"
+ compiler_name = "rest"
+
+class MarkdownExtension(CompilerExtension):
+
+ """Extensions for Markdown."""
-class MarkdownExtension(BasePlugin):
name = "dummy_markdown_extension"
+ compiler_name = "markdown"
class SignalHandler(BasePlugin):
+
+ """Signal handlers."""
+
name = "dummy_signal_handler"
class ConfigPlugin(BasePlugin):
+
"""A plugin that can edit config (or modify the site) on-the-fly."""
+
name = "dummy_config_plugin"
class Importer(Command):
+
"""Basic structure for importing data into Nikola.
The flow is:
@@ -345,7 +393,7 @@ class Importer(Command):
raise NotImplementedError()
def read_data(self, source):
- """Fetch data into self.data"""
+ """Fetch data into self.data."""
raise NotImplementedError()
def preprocess_data(self):
@@ -353,7 +401,7 @@ class Importer(Command):
pass
def parse_data(self):
- """Convert self.data into self.items"""
+ """Convert self.data into self.items."""
raise NotImplementedError()
def filter_data(self):
diff --git a/nikola/plugins/__init__.py b/nikola/plugins/__init__.py
index 139759b..b83f43f 100644
--- a/nikola/plugins/__init__.py
+++ b/nikola/plugins/__init__.py
@@ -1,2 +1,5 @@
# -*- coding: utf-8 -*-
+
+"""Plugins for Nikola."""
+
from __future__ import absolute_import
diff --git a/nikola/plugins/basic_import.py b/nikola/plugins/basic_import.py
index f8a3a3c..073a539 100644
--- a/nikola/plugins/basic_import.py
+++ b/nikola/plugins/basic_import.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Mixin for importer plugins."""
+
from __future__ import unicode_literals, print_function
import io
import csv
@@ -46,6 +48,7 @@ links = {}
class ImportMixin(object):
+
"""Mixin with common used methods."""
name = "import_mixin"
@@ -68,12 +71,14 @@ class ImportMixin(object):
@classmethod
def get_channel_from_file(cls, filename):
+ """Get channel from XML file."""
tree = etree.fromstring(cls.read_xml_file(filename))
channel = tree.find('channel')
return channel
@staticmethod
def configure_redirections(url_map):
+ """Configure redirections from an url_map."""
redirections = []
for k, v in url_map.items():
if not k[-1] == '/':
@@ -90,6 +95,7 @@ class ImportMixin(object):
return redirections
def generate_base_site(self):
+ """Generate a base Nikola site."""
if not os.path.exists(self.output_folder):
os.system('nikola init -q ' + self.output_folder)
else:
@@ -108,14 +114,17 @@ class ImportMixin(object):
@staticmethod
def populate_context(channel):
+ """Populate context with settings."""
raise NotImplementedError("Must be implemented by a subclass.")
@classmethod
def transform_content(cls, content):
+ """Transform content to a Nikola-friendly format."""
return content
@classmethod
def write_content(cls, filename, content, rewrite_html=True):
+ """Write content to file."""
if rewrite_html:
doc = html.document_fromstring(content)
doc.rewrite_links(replacer)
@@ -129,6 +138,7 @@ class ImportMixin(object):
@staticmethod
def write_metadata(filename, title, slug, post_date, description, tags, **kwargs):
+ """Write metadata to meta file."""
if not description:
description = ""
@@ -140,6 +150,7 @@ class ImportMixin(object):
@staticmethod
def write_urlmap_csv(output_file, url_map):
+ """Write urlmap to csv file."""
utils.makedirs(os.path.dirname(output_file))
fmode = 'wb+' if sys.version_info[0] == 2 else 'w+'
with io.open(output_file, fmode) as fd:
@@ -148,6 +159,7 @@ class ImportMixin(object):
csv_writer.writerow(item)
def get_configuration_output_path(self):
+ """Get path for the output configuration file."""
if not self.import_into_existing_site:
filename = 'conf.py'
else:
@@ -161,10 +173,12 @@ class ImportMixin(object):
@staticmethod
def write_configuration(filename, rendered_template):
+ """Write the configuration file."""
utils.makedirs(os.path.dirname(filename))
with io.open(filename, 'w+', encoding='utf8') as fd:
fd.write(rendered_template)
def replacer(dst):
+ """Replace links."""
return links.get(dst, dst)
diff --git a/nikola/plugins/command/__init__.py b/nikola/plugins/command/__init__.py
index a1d17a6..2aa5267 100644
--- a/nikola/plugins/command/__init__.py
+++ b/nikola/plugins/command/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Commands for Nikola."""
diff --git a/nikola/plugins/command/auto.plugin b/nikola/plugins/command/auto.plugin
index a1c6820..3e2b17d 100644
--- a/nikola/plugins/command/auto.plugin
+++ b/nikola/plugins/command/auto.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = auto
-Module = auto
+name = auto
+module = auto
[Documentation]
-Author = Roberto Alsina
-Version = 2.1.0
-Website = http://getnikola.com
-Description = Automatically detect site changes, rebuild and optionally refresh a browser.
+author = Roberto Alsina
+version = 2.1.0
+website = http://getnikola.com
+description = Automatically detect site changes, rebuild and optionally refresh a browser.
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/auto/__init__.py b/nikola/plugins/command/auto/__init__.py
index c25ef8a..71f9624 100644
--- a/nikola/plugins/command/auto/__init__.py
+++ b/nikola/plugins/command/auto/__init__.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Automatic rebuilds for Nikola."""
+
from __future__ import print_function
import json
@@ -31,10 +33,13 @@ import mimetypes
import os
import re
import subprocess
+import sys
+import time
try:
from urlparse import urlparse
+ from urllib2 import unquote
except ImportError:
- from urllib.parse import urlparse # NOQA
+ from urllib.parse import urlparse, unquote # NOQA
import webbrowser
from wsgiref.simple_server import make_server
import wsgiref.util
@@ -42,7 +47,7 @@ import wsgiref.util
from blinker import signal
try:
from ws4py.websocket import WebSocket
- from ws4py.server.wsgirefserver import WSGIServer, WebSocketWSGIRequestHandler
+ from ws4py.server.wsgirefserver import WSGIServer, WebSocketWSGIRequestHandler, WebSocketWSGIHandler
from ws4py.server.wsgiutils import WebSocketWSGIApplication
from ws4py.messaging import TextMessage
except ImportError:
@@ -58,7 +63,7 @@ except ImportError:
from nikola.plugin_categories import Command
-from nikola.utils import req_missing, get_logger, get_theme_path
+from nikola.utils import req_missing, get_logger, get_theme_path, STDERR_HANDLER
LRJS_PATH = os.path.join(os.path.dirname(__file__), 'livereload.js')
error_signal = signal('error')
refresh_signal = signal('refresh')
@@ -74,9 +79,12 @@ ERROR {}
class CommandAuto(Command):
- """Start debugging console."""
+
+ """Automatic rebuilds for Nikola."""
+
name = "auto"
logger = None
+ has_server = True
doc_purpose = "builds and serves a site; automatically detects site changes, rebuilds, and optionally refreshes a browser"
cmd_options = [
{
@@ -100,7 +108,7 @@ class CommandAuto(Command):
'short': 'b',
'long': 'browser',
'type': bool,
- 'help': 'Start a web browser.',
+ 'help': 'Start a web browser',
'default': False,
},
{
@@ -111,12 +119,18 @@ class CommandAuto(Command):
'type': bool,
'help': 'Use IPv6',
},
+ {
+ 'name': 'no-server',
+ 'long': 'no-server',
+ 'default': False,
+ 'type': bool,
+ 'help': 'Disable the server, automate rebuilds only'
+ },
]
def _execute(self, options, args):
"""Start the watcher."""
-
- self.logger = get_logger('auto', self.site.loghandlers)
+ self.logger = get_logger('auto', STDERR_HANDLER)
LRSocket.logger = self.logger
if WebSocket is object and watchdog is None:
@@ -166,10 +180,14 @@ class CommandAuto(Command):
host = options['address'].strip('[').strip(']') or dhost
+ # Server can be disabled (Issue #1883)
+ self.has_server = not options['no-server']
+
# Instantiate global observer
observer = Observer()
- # Watch output folders and trigger reloads
- observer.schedule(OurWatchHandler(self.do_refresh), out_folder, recursive=True)
+ if self.has_server:
+ # Watch output folders and trigger reloads
+ observer.schedule(OurWatchHandler(self.do_refresh), out_folder, recursive=True)
# Watch input folders and trigger rebuilds
for p in watched:
@@ -181,101 +199,155 @@ class CommandAuto(Command):
_conf_dn = os.path.dirname(_conf_fn)
observer.schedule(ConfigWatchHandler(_conf_fn, self.do_rebuild), _conf_dn, recursive=False)
- observer.start()
+ try:
+ self.logger.info("Watching files for changes...")
+ observer.start()
+ except KeyboardInterrupt:
+ pass
parent = self
class Mixed(WebSocketWSGIApplication):
- """A class that supports WS and HTTP protocols in the same port."""
+
+ """A class that supports WS and HTTP protocols on the same port."""
+
def __call__(self, environ, start_response):
if environ.get('HTTP_UPGRADE') is None:
return parent.serve_static(environ, start_response)
return super(Mixed, self).__call__(environ, start_response)
- ws = make_server(
- host, port, server_class=WSGIServer,
- handler_class=WebSocketWSGIRequestHandler,
- app=Mixed(handler_cls=LRSocket)
- )
- ws.initialize_websockets_manager()
- self.logger.info("Serving HTTP on {0} port {1}...".format(host, port))
- if browser:
- if options['ipv6'] or '::' in host:
- server_url = "http://[{0}]:{1}/".format(host, port)
- else:
- server_url = "http://{0}:{1}/".format(host, port)
-
- self.logger.info("Opening {0} in the default web browser...".format(server_url))
- # Yes, this is racy
- webbrowser.open('http://{0}:{1}'.format(host, port))
-
- try:
- ws.serve_forever()
- except KeyboardInterrupt:
- self.logger.info("Server is shutting down.")
- observer.stop()
- observer.join()
+ if self.has_server:
+ ws = make_server(
+ host, port, server_class=WSGIServer,
+ handler_class=WebSocketWSGIRequestHandler,
+ app=Mixed(handler_cls=LRSocket)
+ )
+ ws.initialize_websockets_manager()
+ self.logger.info("Serving HTTP on {0} port {1}...".format(host, port))
+ if browser:
+ if options['ipv6'] or '::' in host:
+ server_url = "http://[{0}]:{1}/".format(host, port)
+ else:
+ server_url = "http://{0}:{1}/".format(host, port)
+
+ self.logger.info("Opening {0} in the default web browser...".format(server_url))
+ # Yes, this is racy
+ webbrowser.open('http://{0}:{1}'.format(host, port))
+
+ try:
+ ws.serve_forever()
+ except KeyboardInterrupt:
+ self.logger.info("Server is shutting down.")
+ # This is a hack, but something is locking up in a futex
+ # and exit() doesn't work.
+ os.kill(os.getpid(), 15)
+ else:
+ # Workaround: can’t have nothing running (instant exit)
+ # but also can’t join threads (no way to exit)
+ # The joys of threading.
+ try:
+ while True:
+ time.sleep(1)
+ except KeyboardInterrupt:
+ self.logger.info("Shutting down.")
+ # This is a hack, but something is locking up in a futex
+ # and exit() doesn't work.
+ os.kill(os.getpid(), 15)
def do_rebuild(self, event):
- self.logger.info('REBUILDING SITE (from {0})'.format(event.src_path))
+ """Rebuild the site."""
+ # Move events have a dest_path, some editors like gedit use a
+ # move on larger save operations for write protection
+ event_path = event.dest_path if hasattr(event, 'dest_path') else event.src_path
+ fname = os.path.basename(event_path)
+ if (fname.endswith('~') or
+ fname.startswith('.') or
+ os.path.isdir(event_path)): # Skip on folders, these are usually duplicates
+ return
+ self.logger.info('REBUILDING SITE (from {0})'.format(event_path))
p = subprocess.Popen(self.cmd_arguments, stderr=subprocess.PIPE)
+ error = p.stderr.read()
+ errord = error.decode('utf-8')
if p.wait() != 0:
- error = p.stderr.read()
- self.logger.error(error)
- error_signal.send(error=error)
+ self.logger.error(errord)
+ error_signal.send(error=errord)
else:
- error = p.stderr.read()
- print(error)
+ print(errord)
def do_refresh(self, event):
- self.logger.info('REFRESHING: {0}'.format(event.src_path))
- p = os.path.relpath(event.src_path, os.path.abspath(self.site.config['OUTPUT_FOLDER']))
+ """Refresh the page."""
+ # Move events have a dest_path, some editors like gedit use a
+ # move on larger save operations for write protection
+ event_path = event.dest_path if hasattr(event, 'dest_path') else event.src_path
+ self.logger.info('REFRESHING: {0}'.format(event_path))
+ p = os.path.relpath(event_path, os.path.abspath(self.site.config['OUTPUT_FOLDER']))
refresh_signal.send(path=p)
def serve_static(self, environ, start_response):
"""Trivial static file server."""
uri = wsgiref.util.request_uri(environ)
p_uri = urlparse(uri)
- f_path = os.path.join(self.site.config['OUTPUT_FOLDER'], *p_uri.path.split('/'))
- mimetype = mimetypes.guess_type(uri)[0] or 'text/html'
+ f_path = os.path.join(self.site.config['OUTPUT_FOLDER'], *[unquote(x) for x in p_uri.path.split('/')])
+
+ # ‘Pretty’ URIs and root are assumed to be HTML
+ mimetype = 'text/html' if uri.endswith('/') else mimetypes.guess_type(uri)[0] or 'application/octet-stream'
if os.path.isdir(f_path):
+ if not f_path.endswith('/'): # Redirect to avoid breakage
+ start_response('301 Redirect', [('Location', p_uri.path + '/')])
+ return []
f_path = os.path.join(f_path, self.site.config['INDEX_FILE'])
+ mimetype = 'text/html'
if p_uri.path == '/robots.txt':
start_response('200 OK', [('Content-type', 'text/plain')])
- return ['User-Agent: *\nDisallow: /\n']
+ return ['User-Agent: *\nDisallow: /\n'.encode('utf-8')]
elif os.path.isfile(f_path):
with open(f_path, 'rb') as fd:
start_response('200 OK', [('Content-type', mimetype)])
- return [self.inject_js(mimetype, fd.read())]
+ return [self.file_filter(mimetype, fd.read())]
elif p_uri.path == '/livereload.js':
with open(LRJS_PATH, 'rb') as fd:
start_response('200 OK', [('Content-type', mimetype)])
- return [self.inject_js(mimetype, fd.read())]
+ return [self.file_filter(mimetype, fd.read())]
start_response('404 ERR', [])
- return [self.inject_js('text/html', ERROR_N.format(404).format(uri))]
+ return [self.file_filter('text/html', ERROR_N.format(404).format(uri).encode('utf-8'))]
- def inject_js(self, mimetype, data):
- """Inject livereload.js in HTML files."""
+ def file_filter(self, mimetype, data):
+ """Apply necessary changes to document before serving."""
if mimetype == 'text/html':
- data = re.sub('</head>', self.snippet, data.decode('utf8'), 1, re.IGNORECASE)
+ data = data.decode('utf8')
+ data = self.remove_base_tag(data)
+ data = self.inject_js(data)
data = data.encode('utf8')
return data
+ def inject_js(self, data):
+ """Inject livereload.js."""
+ data = re.sub('</head>', self.snippet, data, 1, re.IGNORECASE)
+ return data
+
+ def remove_base_tag(self, data):
+ """Comment out any <base> to allow local resolution of relative URLs."""
+ data = re.sub(r'<base\s([^>]*)>', '<!--base \g<1>-->', data, re.IGNORECASE)
+ return data
+
pending = []
class LRSocket(WebSocket):
+
"""Speak Livereload protocol."""
def __init__(self, *a, **kw):
+ """Initialize protocol handler."""
refresh_signal.connect(self.notify)
error_signal.connect(self.send_error)
super(LRSocket, self).__init__(*a, **kw)
def received_message(self, message):
+ """Handle received message."""
message = json.loads(message.data.decode('utf8'))
self.logger.info('<--- {0}'.format(message))
response = None
@@ -364,3 +436,25 @@ class ConfigWatchHandler(FileSystemEventHandler):
"""Call the provided function on any event."""
if event._src_path == self.configuration_filename:
self.function(event)
+
+
+try:
+ # Monkeypatch to hide Broken Pipe Errors
+ f = WebSocketWSGIHandler.finish_response
+
+ if sys.version_info[0] == 3:
+ EX = BrokenPipeError # NOQA
+ else:
+ EX = IOError
+
+ def finish_response(self):
+ """Monkeypatched finish_response that ignores broken pipes."""
+ try:
+ f(self)
+ except EX: # Client closed the connection, not a real error
+ pass
+
+ WebSocketWSGIHandler.finish_response = finish_response
+except NameError:
+ # In case there is no WebSocketWSGIHandler because of a failed import.
+ pass
diff --git a/nikola/plugins/command/bootswatch_theme.plugin b/nikola/plugins/command/bootswatch_theme.plugin
index b428da3..fc25045 100644
--- a/nikola/plugins/command/bootswatch_theme.plugin
+++ b/nikola/plugins/command/bootswatch_theme.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = bootswatch_theme
-Module = bootswatch_theme
+name = bootswatch_theme
+module = bootswatch_theme
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Given a swatch name and a parent theme, creates a custom theme.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Given a swatch name and a parent theme, creates a custom theme.
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/bootswatch_theme.py b/nikola/plugins/command/bootswatch_theme.py
index e19c937..b5644a1 100644
--- a/nikola/plugins/command/bootswatch_theme.py
+++ b/nikola/plugins/command/bootswatch_theme.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Given a swatch name from bootswatch.com and a parent theme, creates a custom theme."""
+
from __future__ import print_function
import os
import requests
@@ -35,6 +37,7 @@ LOGGER = utils.get_logger('bootswatch_theme', utils.STDERR_HANDLER)
class CommandBootswatchTheme(Command):
+
"""Given a swatch name from bootswatch.com and a parent theme, creates a custom theme."""
name = "bootswatch_theme"
diff --git a/nikola/plugins/command/check.plugin b/nikola/plugins/command/check.plugin
index dd0980e..e380e64 100644
--- a/nikola/plugins/command/check.plugin
+++ b/nikola/plugins/command/check.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = check
-Module = check
+name = check
+module = check
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Check the generated site
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Check the generated site
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/check.py b/nikola/plugins/command/check.py
index a9bc44a..abf183e 100644
--- a/nikola/plugins/command/check.py
+++ b/nikola/plugins/command/check.py
@@ -24,11 +24,14 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Check the generated site."""
+
from __future__ import print_function
from collections import defaultdict
import os
import re
import sys
+import time
try:
from urllib import unquote
from urlparse import urlparse, urljoin, urldefrag
@@ -40,7 +43,7 @@ import lxml.html
import requests
from nikola.plugin_categories import Command
-from nikola.utils import get_logger
+from nikola.utils import get_logger, STDERR_HANDLER
def _call_nikola_list(site):
@@ -58,6 +61,7 @@ def _call_nikola_list(site):
def real_scan_files(site):
+ """Scan for files."""
task_fnames = set([])
real_fnames = set([])
output_folder = site.config['OUTPUT_FOLDER']
@@ -80,7 +84,8 @@ def real_scan_files(site):
def fs_relpath_from_url_path(url_path):
- """Expects as input an urlparse(s).path"""
+ """Create a filesystem relative path from an URL path."""
+ # Expects as input an urlparse(s).path
url_path = unquote(url_path)
# in windows relative paths don't begin with os.sep
if sys.platform == 'win32' and len(url_path):
@@ -89,6 +94,7 @@ def fs_relpath_from_url_path(url_path):
class CommandCheck(Command):
+
"""Check the generated site."""
name = "check"
@@ -147,7 +153,7 @@ class CommandCheck(Command):
def _execute(self, options, args):
"""Check the generated site."""
- self.logger = get_logger('check', self.site.loghandlers)
+ self.logger = get_logger('check', STDERR_HANDLER)
if not options['links'] and not options['files'] and not options['clean']:
print(self.help())
@@ -169,6 +175,7 @@ class CommandCheck(Command):
checked_remote_targets = {}
def analyze(self, fname, find_sources=False, check_remote=False):
+ """Analyze links on a page."""
rv = False
self.whitelist = [re.compile(x) for x in self.site.config['LINK_CHECK_WHITELIST']]
base_url = urlparse(self.site.config['BASE_URL'])
@@ -217,15 +224,45 @@ class CommandCheck(Command):
if parsed.netloc == base_url.netloc: # absolute URL to self.site
continue
if target in self.checked_remote_targets: # already checked this exact target
- if self.checked_remote_targets[target] > 399:
- self.logger.warn("Broken link in {0}: {1} [Error {2}]".format(filename, target, self.checked_remote_targets[target]))
+ if self.checked_remote_targets[target] in [301, 307]:
+ self.logger.warn("Remote link PERMANENTLY redirected in {0}: {1} [Error {2}]".format(filename, target, self.checked_remote_targets[target]))
+ elif self.checked_remote_targets[target] in [302, 308]:
+ self.logger.info("Remote link temporarily redirected in {1}: {2} [HTTP: {3}]".format(filename, target, self.checked_remote_targets[target]))
+ elif self.checked_remote_targets[target] > 399:
+ self.logger.error("Broken link in {0}: {1} [Error {2}]".format(filename, target, self.checked_remote_targets[target]))
continue
+
+ # Skip whitelisted targets
+ if any(re.search(_, target) for _ in self.whitelist):
+ continue
+
# Check the remote link works
req_headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 (Nikola)'} # I’m a real boy!
- resp = requests.head(target, headers=req_headers)
- self.checked_remote_targets[target] = resp.status_code
+ resp = requests.head(target, headers=req_headers, allow_redirects=False)
+
+ # Retry client errors (4xx) as GET requests because many servers are broken
+ if resp.status_code >= 400 and resp.status_code <= 499:
+ time.sleep(0.5)
+ resp = requests.get(target, headers=req_headers, allow_redirects=False)
+
+ # Follow redirects and see where they lead, redirects to errors will be reported twice
+ if resp.status_code in [301, 302, 307, 308]:
+ redir_status_code = resp.status_code
+ time.sleep(0.5)
+ # Known redirects are retested using GET because IIS servers otherwise get HEADaches
+ resp = requests.get(target, headers=req_headers, allow_redirects=True)
+ # Permanent redirects should be updated
+ if redir_status_code in [301, 308]:
+ self.logger.warn("Remote link moved PERMANENTLY to \"{0}\" and should be updated in {1}: {2} [HTTP: {3}]".format(resp.url, filename, target, redir_status_code))
+ if redir_status_code in [302, 307]:
+ self.logger.info("Remote link temporarily redirected to \"{0}\" in {1}: {2} [HTTP: {3}]".format(resp.url, filename, target, redir_status_code))
+ self.checked_remote_targets[resp.url] = resp.status_code
+ self.checked_remote_targets[target] = redir_status_code
+ else:
+ self.checked_remote_targets[target] = resp.status_code
+
if resp.status_code > 399: # Error
- self.logger.warn("Broken link in {0}: {1} [Error {2}]".format(filename, target, resp.status_code))
+ self.logger.error("Broken link in {0}: {1} [Error {2}]".format(filename, target, resp.status_code))
continue
elif resp.status_code <= 399: # The address leads *somewhere* that is not an error
self.logger.debug("Successfully checked remote link in {0}: {1} [HTTP: {2}]".format(filename, target, resp.status_code))
@@ -271,6 +308,7 @@ class CommandCheck(Command):
return rv
def scan_links(self, find_sources=False, check_remote=False):
+ """Check links on the site."""
self.logger.info("Checking Links:")
self.logger.info("===============\n")
self.logger.notice("{0} mode".format(self.site.config['URL_TYPE']))
@@ -286,6 +324,7 @@ class CommandCheck(Command):
return failure
def scan_files(self):
+ """Check files in the site, find missing and orphaned files."""
failure = False
self.logger.info("Checking Files:")
self.logger.info("===============\n")
@@ -311,7 +350,22 @@ class CommandCheck(Command):
return failure
def clean_files(self):
+ """Remove orphaned files."""
only_on_output, _ = real_scan_files(self.site)
for f in only_on_output:
+ self.logger.info('removed: {0}'.format(f))
os.unlink(f)
+
+ # Find empty directories and remove them
+ output_folder = self.site.config['OUTPUT_FOLDER']
+ all_dirs = []
+ for root, dirs, files in os.walk(output_folder, followlinks=True):
+ all_dirs.append(root)
+ all_dirs.sort(key=len, reverse=True)
+ for d in all_dirs:
+ try:
+ os.rmdir(d)
+ self.logger.info('removed: {0}/'.format(d))
+ except OSError:
+ pass
return True
diff --git a/nikola/plugins/command/console.plugin b/nikola/plugins/command/console.plugin
index 3aef2e7..333762c 100644
--- a/nikola/plugins/command/console.plugin
+++ b/nikola/plugins/command/console.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = console
-Module = console
+name = console
+module = console
[Documentation]
-Author = Chris Warrick, Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Start a debugging python console
+author = Chris Warrick, Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Start a debugging python console
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/console.py b/nikola/plugins/command/console.py
index b8e7825..539fa08 100644
--- a/nikola/plugins/command/console.py
+++ b/nikola/plugins/command/console.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Start debugging console."""
+
from __future__ import print_function, unicode_literals
import os
@@ -36,7 +38,9 @@ LOGGER = get_logger('console', STDERR_HANDLER)
class CommandConsole(Command):
+
"""Start debugging console."""
+
name = "console"
shells = ['ipython', 'bpython', 'plain']
doc_purpose = "start an interactive Python console with access to your site"
diff --git a/nikola/plugins/command/deploy.plugin b/nikola/plugins/command/deploy.plugin
index 14fd53f..4743ca2 100644
--- a/nikola/plugins/command/deploy.plugin
+++ b/nikola/plugins/command/deploy.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = deploy
-Module = deploy
+name = deploy
+module = deploy
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Deploy the site
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Deploy the site
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/deploy.py b/nikola/plugins/command/deploy.py
index 2c44e87..821ea11 100644
--- a/nikola/plugins/command/deploy.py
+++ b/nikola/plugins/command/deploy.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Deploy site."""
+
from __future__ import print_function
import io
from datetime import datetime
@@ -35,11 +37,13 @@ import time
from blinker import signal
from nikola.plugin_categories import Command
-from nikola.utils import get_logger, remove_file, unicode_str, makedirs
+from nikola.utils import get_logger, remove_file, unicode_str, makedirs, STDERR_HANDLER
class CommandDeploy(Command):
+
"""Deploy site."""
+
name = "deploy"
doc_usage = "[[preset [preset...]]"
@@ -48,7 +52,8 @@ class CommandDeploy(Command):
logger = None
def _execute(self, command, args):
- self.logger = get_logger('deploy', self.site.loghandlers)
+ """Execute the deploy command."""
+ self.logger = get_logger('deploy', STDERR_HANDLER)
# Get last successful deploy date
timestamp_path = os.path.join(self.site.config['CACHE_FOLDER'], 'lastdeploy')
if self.site.config['COMMENT_SYSTEM_ID'] == 'nikolademo':
@@ -116,7 +121,7 @@ class CommandDeploy(Command):
outf.write(unicode_str(new_deploy.isoformat()))
def _emit_deploy_event(self, last_deploy, new_deploy, clean=False, undeployed=None):
- """ Emit events for all timeline entries newer than last deploy.
+ """Emit events for all timeline entries newer than last deploy.
last_deploy: datetime
Time stamp of the last successful deployment.
@@ -128,7 +133,6 @@ class CommandDeploy(Command):
True when it appears like deploy is being run after a clean.
"""
-
event = {
'last_deploy': last_deploy,
'new_deploy': new_deploy,
diff --git a/nikola/plugins/command/github_deploy.plugin b/nikola/plugins/command/github_deploy.plugin
index 74e7902..e793548 100644
--- a/nikola/plugins/command/github_deploy.plugin
+++ b/nikola/plugins/command/github_deploy.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = github_deploy
-Module = github_deploy
+name = github_deploy
+module = github_deploy
[Documentation]
-Author = Puneeth Chaganti
-Version = 1,0
-Website = http://getnikola.com
-Description = Deploy the site to GitHub pages.
+author = Puneeth Chaganti
+version = 1,0
+website = http://getnikola.com
+description = Deploy the site to GitHub pages.
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/github_deploy.py b/nikola/plugins/command/github_deploy.py
index 888a4f9..0ab9332 100644
--- a/nikola/plugins/command/github_deploy.py
+++ b/nikola/plugins/command/github_deploy.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Deploy site to GitHub Pages."""
+
from __future__ import print_function
from datetime import datetime
import io
@@ -33,17 +35,19 @@ from textwrap import dedent
from nikola.plugin_categories import Command
from nikola.plugins.command.check import real_scan_files
-from nikola.utils import get_logger, req_missing, makedirs, unicode_str
+from nikola.utils import get_logger, req_missing, makedirs, unicode_str, STDERR_HANDLER
from nikola.__main__ import main
from nikola import __version__
def uni_check_output(*args, **kwargs):
+ """Run command and return output as Unicode (UTf-8)."""
o = subprocess.check_output(*args, **kwargs)
return o.decode('utf-8')
def check_ghp_import_installed():
+ """Check if ghp-import is installed."""
try:
subprocess.check_output(['ghp-import', '-h'])
except OSError:
@@ -53,7 +57,9 @@ def check_ghp_import_installed():
class CommandGitHubDeploy(Command):
- """ Deploy site to GitHub Pages. """
+
+ """Deploy site to GitHub Pages."""
+
name = 'github_deploy'
doc_usage = ''
@@ -70,10 +76,8 @@ class CommandGitHubDeploy(Command):
logger = None
def _execute(self, command, args):
-
- self.logger = get_logger(
- CommandGitHubDeploy.name, self.site.loghandlers
- )
+ """Run the deployment."""
+ self.logger = get_logger(CommandGitHubDeploy.name, STDERR_HANDLER)
# Check if ghp-import is installed
check_ghp_import_installed()
@@ -95,8 +99,7 @@ class CommandGitHubDeploy(Command):
return
def _commit_and_push(self):
- """ Commit all the files and push. """
-
+ """Commit all the files and push."""
source = self.site.config['GITHUB_SOURCE_BRANCH']
deploy = self.site.config['GITHUB_DEPLOY_BRANCH']
remote = self.site.config['GITHUB_REMOTE_NAME']
diff --git a/nikola/plugins/command/import_wordpress.plugin b/nikola/plugins/command/import_wordpress.plugin
index e072224..6c4384e 100644
--- a/nikola/plugins/command/import_wordpress.plugin
+++ b/nikola/plugins/command/import_wordpress.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = import_wordpress
-Module = import_wordpress
+name = import_wordpress
+module = import_wordpress
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Import a wordpress site from a XML dump (requires markdown).
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Import a wordpress site from a XML dump (requires markdown).
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/import_wordpress.py b/nikola/plugins/command/import_wordpress.py
index 674fc2a..a652ec8 100644
--- a/nikola/plugins/command/import_wordpress.py
+++ b/nikola/plugins/command/import_wordpress.py
@@ -24,13 +24,18 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Import a WordPress dump."""
+
from __future__ import unicode_literals, print_function
import os
import re
import sys
import datetime
+import io
+import json
import requests
from lxml import etree
+from collections import defaultdict
try:
from urlparse import urlparse
@@ -53,7 +58,37 @@ from nikola.plugins.command.init import SAMPLE_CONF, prepare_config, format_defa
LOGGER = utils.get_logger('import_wordpress', utils.STDERR_HANDLER)
+def install_plugin(site, plugin_name, output_dir=None, show_install_notes=False):
+ """Install a Nikola plugin."""
+ LOGGER.notice("Installing plugin '{0}'".format(plugin_name))
+ # Get hold of the 'plugin' plugin
+ plugin_installer_info = site.plugin_manager.getPluginByName('plugin', 'Command')
+ if plugin_installer_info is None:
+ LOGGER.error('Internal error: cannot find the "plugin" plugin which is supposed to come with Nikola!')
+ return False
+ if not plugin_installer_info.is_activated:
+ # Someone might have disabled the plugin in the `conf.py` used
+ site.plugin_manager.activatePluginByName(plugin_installer_info.name)
+ plugin_installer_info.plugin_object.set_site(site)
+ plugin_installer = plugin_installer_info.plugin_object
+ # Try to install the requested plugin
+ options = {}
+ for option in plugin_installer.cmd_options:
+ options[option['name']] = option['default']
+ options['install'] = plugin_name
+ options['output_dir'] = output_dir
+ options['show_install_notes'] = show_install_notes
+ if plugin_installer.execute(options=options) > 0:
+ return False
+ # Let the plugin manager find newly installed plugins
+ site.plugin_manager.collectPlugins()
+ # Re-scan for compiler extensions
+ site.compiler_extensions = site._activate_plugins_of_category("CompilerExtension")
+ return True
+
+
class CommandImportWordpress(Command, ImportMixin):
+
"""Import a WordPress dump."""
name = "import_wordpress"
@@ -70,6 +105,20 @@ class CommandImportWordpress(Command, ImportMixin):
'help': "Don't import drafts",
},
{
+ 'name': 'exclude_privates',
+ 'long': 'exclude-privates',
+ 'default': False,
+ 'type': bool,
+ 'help': "Don't import private posts",
+ },
+ {
+ 'name': 'include_empty_items',
+ 'long': 'include-empty-items',
+ 'default': False,
+ 'type': bool,
+ 'help': "Include empty posts and pages",
+ },
+ {
'name': 'squash_newlines',
'long': 'squash-newlines',
'default': False,
@@ -107,15 +156,57 @@ class CommandImportWordpress(Command, ImportMixin):
'type': str,
'help': "The pattern for translation files names",
},
+ {
+ 'name': 'export_categories_as_categories',
+ 'long': 'export-categories-as-categories',
+ 'default': False,
+ 'type': bool,
+ 'help': "Export categories as categories, instead of treating them as tags",
+ },
+ {
+ 'name': 'export_comments',
+ 'long': 'export-comments',
+ 'default': False,
+ 'type': bool,
+ 'help': "Export comments as .wpcomment files",
+ },
+ {
+ 'name': 'transform_to_html',
+ 'long': 'transform-to-html',
+ 'default': False,
+ 'type': bool,
+ 'help': "Uses WordPress page compiler to transform WordPress posts directly to HTML during import",
+ },
+ {
+ 'name': 'use_wordpress_compiler',
+ 'long': 'use-wordpress-compiler',
+ 'default': False,
+ 'type': bool,
+ 'help': "Instead of converting posts to markdown, leave them as is and use the WordPress page compiler",
+ },
+ {
+ 'name': 'install_wordpress_compiler',
+ 'long': 'install-wordpress-compiler',
+ 'default': False,
+ 'type': bool,
+ 'help': "Automatically installs the WordPress page compiler (either locally or in the new site) if required by other options.\nWarning: the compiler is GPL software!",
+ },
]
all_tags = set([])
- def _execute(self, options={}, args=[]):
- """Import a WordPress blog from an export file into a Nikola site."""
- if not args:
- print(self.help())
+ def _find_wordpress_compiler(self):
+ """Find WordPress compiler plugin."""
+ if self.wordpress_page_compiler is not None:
return
-
+ plugin_info = self.site.plugin_manager.getPluginByName('wordpress', 'PageCompiler')
+ if plugin_info is not None:
+ if not plugin_info.is_activated:
+ self.site.plugin_manager.activatePluginByName(plugin_info.name)
+ plugin_info.plugin_object.set_site(self.site)
+ self.wordpress_page_compiler = plugin_info.plugin_object
+
+ def _read_options(self, options, args):
+ """Read command-line options."""
options['filename'] = args.pop(0)
if args and ('output_folder' not in args or
@@ -136,19 +227,76 @@ class CommandImportWordpress(Command, ImportMixin):
self.output_folder = options.get('output_folder', 'new_site')
self.exclude_drafts = options.get('exclude_drafts', False)
+ self.exclude_privates = options.get('exclude_privates', False)
self.no_downloads = options.get('no_downloads', False)
+ self.import_empty_items = options.get('include_empty_items', False)
+
+ self.export_categories_as_categories = options.get('export_categories_as_categories', False)
+ self.export_comments = options.get('export_comments', False)
+
+ self.transform_to_html = options.get('transform_to_html', False)
+ self.use_wordpress_compiler = options.get('use_wordpress_compiler', False)
+ self.install_wordpress_compiler = options.get('install_wordpress_compiler', False)
+ self.wordpress_page_compiler = None
self.auth = None
if options.get('download_auth') is not None:
username_password = options.get('download_auth')
self.auth = tuple(username_password.split(':', 1))
if len(self.auth) < 2:
- print("Please specify HTTP authentication credentials in the form username:password.")
+ LOGGER.error("Please specify HTTP authentication credentials in the form username:password.")
return False
self.separate_qtranslate_content = options.get('separate_qtranslate_content')
self.translations_pattern = options.get('translations_pattern')
+ if self.transform_to_html and self.use_wordpress_compiler:
+ LOGGER.warn("It does not make sense to combine --transform-to-html with --use-wordpress-compiler, as the first converts all posts to HTML and the latter option affects zero posts.")
+
+ if self.transform_to_html:
+ self._find_wordpress_compiler()
+ if not self.wordpress_page_compiler and self.install_wordpress_compiler:
+ if not install_plugin(self.site, 'wordpress_compiler', output_dir='plugins'): # local install
+ return False
+ self._find_wordpress_compiler()
+ if not self.wordpress_page_compiler:
+ LOGGER.error("To compile WordPress posts to HTML, the WordPress post compiler is needed. You can install it via:")
+ LOGGER.error(" nikola plugin -i wordpress_compiler")
+ LOGGER.error("Please note that the WordPress post compiler is licensed under the GPL v2.")
+ return False
+
+ return True
+
+ def _prepare(self, channel):
+ """Prepare context and category hierarchy."""
+ self.context = self.populate_context(channel)
+ self.base_dir = urlparse(self.context['BASE_URL']).path
+
+ if self.export_categories_as_categories:
+ wordpress_namespace = channel.nsmap['wp']
+ cat_map = dict()
+ for cat in channel.findall('{{{0}}}category'.format(wordpress_namespace)):
+ # cat_id = get_text_tag(cat, '{{{0}}}term_id'.format(wordpress_namespace), None)
+ cat_slug = get_text_tag(cat, '{{{0}}}category_nicename'.format(wordpress_namespace), None)
+ cat_parent_slug = get_text_tag(cat, '{{{0}}}category_parent'.format(wordpress_namespace), None)
+ cat_name = get_text_tag(cat, '{{{0}}}cat_name'.format(wordpress_namespace), None)
+ cat_path = [cat_name]
+ if cat_parent_slug in cat_map:
+ cat_path = cat_map[cat_parent_slug] + cat_path
+ cat_map[cat_slug] = cat_path
+ self._category_paths = dict()
+ for cat, path in cat_map.items():
+ self._category_paths[cat] = utils.join_hierarchical_category_path(path)
+
+ def _execute(self, options={}, args=[]):
+ """Import a WordPress blog from an export file into a Nikola site."""
+ if not args:
+ print(self.help())
+ return False
+
+ if not self._read_options(options, args):
+ return False
+
# A place holder where extra language (if detected) will be stored
self.extra_languages = set()
@@ -166,8 +314,7 @@ class CommandImportWordpress(Command, ImportMixin):
req_missing(['phpserialize'], 'import WordPress dumps without --no-downloads')
channel = self.get_channel_from_file(self.wordpress_export_file)
- self.context = self.populate_context(channel)
- self.base_dir = urlparse(self.context['BASE_URL']).path
+ self._prepare(channel)
conf_template = self.generate_base_site()
# If user has specified a custom pattern for translation files we
@@ -181,6 +328,11 @@ class CommandImportWordpress(Command, ImportMixin):
self.extra_languages)
self.context['REDIRECTIONS'] = self.configure_redirections(
self.url_map)
+ if self.timezone:
+ self.context['TIMEZONE'] = self.timezone
+ if self.export_categories_as_categories:
+ self.context['CATEGORY_ALLOW_HIERARCHIES'] = True
+ self.context['CATEGORY_OUTPUT_FLAT_HIERARCHY'] = True
# Add tag redirects
for tag in self.all_tags:
@@ -197,18 +349,21 @@ class CommandImportWordpress(Command, ImportMixin):
self.write_urlmap_csv(
os.path.join(self.output_folder, 'url_map.csv'), self.url_map)
rendered_template = conf_template.render(**prepare_config(self.context))
- rendered_template = re.sub('# REDIRECTIONS = ', 'REDIRECTIONS = ',
- rendered_template)
-
- if self.timezone:
- rendered_template = re.sub('# TIMEZONE = \'UTC\'',
- 'TIMEZONE = \'' + self.timezone + '\'',
- rendered_template)
self.write_configuration(self.get_configuration_output_path(),
rendered_template)
+ if self.use_wordpress_compiler:
+ if self.install_wordpress_compiler:
+ if not install_plugin(self.site, 'wordpress_compiler', output_dir=os.path.join(self.output_folder, 'plugins')):
+ return False
+ else:
+ LOGGER.warn("Make sure to install the WordPress page compiler via")
+ LOGGER.warn(" nikola plugin -i wordpress_compiler")
+ LOGGER.warn("in your imported blog's folder ({0}), if you haven't installed it system-wide or user-wide. Otherwise, your newly imported blog won't compile.".format(self.output_folder))
+
@classmethod
def read_xml_file(cls, filename):
+ """Read XML file into memory."""
xml = []
with open(filename, 'rb') as fd:
@@ -221,12 +376,13 @@ class CommandImportWordpress(Command, ImportMixin):
@classmethod
def get_channel_from_file(cls, filename):
+ """Get channel from XML file."""
tree = etree.fromstring(cls.read_xml_file(filename))
channel = tree.find('channel')
return channel
- @staticmethod
- def populate_context(channel):
+ def populate_context(self, channel):
+ """Populate context with config for the site."""
wordpress_namespace = channel.nsmap['wp']
context = SAMPLE_CONF.copy()
@@ -255,28 +411,31 @@ class CommandImportWordpress(Command, ImportMixin):
author,
'{{{0}}}author_display_name'.format(wordpress_namespace),
"Joe Example")
- context['POSTS'] = '''(
- ("posts/*.rst", "posts", "post.tmpl"),
- ("posts/*.txt", "posts", "post.tmpl"),
- ("posts/*.md", "posts", "post.tmpl"),
- ("posts/*.wp", "posts", "post.tmpl"),
- )'''
- context['PAGES'] = '''(
- ("stories/*.rst", "stories", "story.tmpl"),
- ("stories/*.txt", "stories", "story.tmpl"),
- ("stories/*.md", "stories", "story.tmpl"),
- ("stories/*.wp", "stories", "story.tmpl"),
- )'''
- context['COMPILERS'] = '''{
- "rest": ('.txt', '.rst'),
- "markdown": ('.md', '.mdown', '.markdown', '.wp'),
- "html": ('.html', '.htm')
- }
- '''
+ extensions = ['rst', 'txt', 'md', 'html']
+ if self.use_wordpress_compiler:
+ extensions.append('wp')
+ POSTS = '(\n'
+ PAGES = '(\n'
+ for extension in extensions:
+ POSTS += ' ("posts/*.{0}", "posts", "post.tmpl"),\n'.format(extension)
+ PAGES += ' ("stories/*.{0}", "stories", "story.tmpl"),\n'.format(extension)
+ POSTS += ')\n'
+ PAGES += ')\n'
+ context['POSTS'] = POSTS
+ context['PAGES'] = PAGES
+ COMPILERS = '{\n'
+ COMPILERS += ''' "rest": ('.txt', '.rst'),''' + '\n'
+ COMPILERS += ''' "markdown": ('.md', '.mdown', '.markdown'),''' + '\n'
+ COMPILERS += ''' "html": ('.html', '.htm'),''' + '\n'
+ if self.use_wordpress_compiler:
+ COMPILERS += ''' "wordpress": ('.wp'),''' + '\n'
+ COMPILERS += '}'
+ context['COMPILERS'] = COMPILERS
return context
def download_url_content_to_file(self, url, dst_path):
+ """Download some content (attachments) to a file."""
if self.no_downloads:
return
@@ -291,6 +450,8 @@ class CommandImportWordpress(Command, ImportMixin):
LOGGER.warn("Downloading {0} to {1} failed: {2}".format(url, dst_path, err))
def import_attachment(self, item, wordpress_namespace):
+ """Import an attachment to the site."""
+ # Download main image
url = get_text_tag(
item, '{{{0}}}attachment_url'.format(wordpress_namespace), 'foo')
link = get_text_tag(item, '{{{0}}}link'.format(wordpress_namespace),
@@ -305,59 +466,136 @@ class CommandImportWordpress(Command, ImportMixin):
links[link] = '/' + dst_url
links[url] = '/' + dst_url
- self.download_additional_image_sizes(
- item,
- wordpress_namespace,
- os.path.dirname(url)
- )
-
- def download_additional_image_sizes(self, item, wordpress_namespace, source_path):
- if phpserialize is None:
- return
+ files = [path]
+ files_meta = [{}]
additional_metadata = item.findall('{{{0}}}postmeta'.format(wordpress_namespace))
- if additional_metadata is None:
- return
-
- for element in additional_metadata:
- meta_key = element.find('{{{0}}}meta_key'.format(wordpress_namespace))
- if meta_key is not None and meta_key.text == '_wp_attachment_metadata':
- meta_value = element.find('{{{0}}}meta_value'.format(wordpress_namespace))
-
- if meta_value is None:
- continue
-
- # Someone from Wordpress thought it was a good idea
- # serialize PHP objects into that metadata field. Given
- # that the export should give you the power to insert
- # your blogging into another site or system its not.
- # Why don't they just use JSON?
- if sys.version_info[0] == 2:
- try:
- metadata = phpserialize.loads(utils.sys_encode(meta_value.text))
- except ValueError:
- # local encoding might be wrong sometimes
+ if phpserialize and additional_metadata:
+ source_path = os.path.dirname(url)
+ for element in additional_metadata:
+ meta_key = element.find('{{{0}}}meta_key'.format(wordpress_namespace))
+ if meta_key is not None and meta_key.text == '_wp_attachment_metadata':
+ meta_value = element.find('{{{0}}}meta_value'.format(wordpress_namespace))
+
+ if meta_value is None:
+ continue
+
+ # Someone from Wordpress thought it was a good idea
+ # serialize PHP objects into that metadata field. Given
+ # that the export should give you the power to insert
+ # your blogging into another site or system its not.
+ # Why don't they just use JSON?
+ if sys.version_info[0] == 2:
+ try:
+ metadata = phpserialize.loads(utils.sys_encode(meta_value.text))
+ except ValueError:
+ # local encoding might be wrong sometimes
+ metadata = phpserialize.loads(meta_value.text.encode('utf-8'))
+ else:
metadata = phpserialize.loads(meta_value.text.encode('utf-8'))
- else:
- metadata = phpserialize.loads(meta_value.text.encode('utf-8'))
- size_key = b'sizes'
- file_key = b'file'
-
- if size_key not in metadata:
- continue
-
- for filename in [metadata[size_key][size][file_key] for size in metadata[size_key]]:
- url = '/'.join([source_path, filename.decode('utf-8')])
- path = urlparse(url).path
- dst_path = os.path.join(*([self.output_folder, 'files'] + list(path.split('/'))))
- dst_dir = os.path.dirname(dst_path)
- utils.makedirs(dst_dir)
- LOGGER.info("Downloading {0} => {1}".format(url, dst_path))
- self.download_url_content_to_file(url, dst_path)
- dst_url = '/'.join(dst_path.split(os.sep)[2:])
- links[url] = '/' + dst_url
- links[url] = '/' + dst_url
+ meta_key = b'image_meta'
+ size_key = b'sizes'
+ file_key = b'file'
+ width_key = b'width'
+ height_key = b'height'
+
+ # Extract metadata
+ if width_key in metadata and height_key in metadata:
+ files_meta[0]['width'] = int(metadata[width_key])
+ files_meta[0]['height'] = int(metadata[height_key])
+
+ if meta_key in metadata:
+ image_meta = metadata[meta_key]
+ dst_meta = {}
+
+ def add(our_key, wp_key, is_int=False, ignore_zero=False, is_float=False):
+ if wp_key in image_meta:
+ value = image_meta[wp_key]
+ if is_int:
+ value = int(value)
+ if ignore_zero and value == 0:
+ return
+ elif is_float:
+ value = float(value)
+ if ignore_zero and value == 0:
+ return
+ else:
+ value = value.decode('utf-8') # assume UTF-8
+ if value == '': # skip empty values
+ return
+ dst_meta[our_key] = value
+
+ add('aperture', b'aperture', is_float=True, ignore_zero=True)
+ add('credit', b'credit')
+ add('camera', b'camera')
+ add('caption', b'caption')
+ add('created_timestamp', b'created_timestamp', is_float=True, ignore_zero=True)
+ add('copyright', b'copyright')
+ add('focal_length', b'focal_length', is_float=True, ignore_zero=True)
+ add('iso', b'iso', is_float=True, ignore_zero=True)
+ add('shutter_speed', b'shutter_speed', ignore_zero=True, is_float=True)
+ add('title', b'title')
+
+ if len(dst_meta) > 0:
+ files_meta[0]['meta'] = dst_meta
+
+ # Find other sizes of image
+ if size_key not in metadata:
+ continue
+
+ for size in metadata[size_key]:
+ filename = metadata[size_key][size][file_key]
+ url = '/'.join([source_path, filename.decode('utf-8')])
+
+ # Construct metadata
+ meta = {}
+ meta['size'] = size.decode('utf-8')
+ if width_key in metadata[size_key][size] and height_key in metadata[size_key][size]:
+ meta['width'] = metadata[size_key][size][width_key]
+ meta['height'] = metadata[size_key][size][height_key]
+
+ path = urlparse(url).path
+ dst_path = os.path.join(*([self.output_folder, 'files'] + list(path.split('/'))))
+ dst_dir = os.path.dirname(dst_path)
+ utils.makedirs(dst_dir)
+ LOGGER.info("Downloading {0} => {1}".format(url, dst_path))
+ self.download_url_content_to_file(url, dst_path)
+ dst_url = '/'.join(dst_path.split(os.sep)[2:])
+ links[url] = '/' + dst_url
+
+ files.append(path)
+ files_meta.append(meta)
+
+ # Prepare result
+ result = {}
+ result['files'] = files
+ result['files_meta'] = files_meta
+
+ # Prepare extraction of more information
+ dc_namespace = item.nsmap['dc']
+ content_namespace = item.nsmap['content']
+ excerpt_namespace = item.nsmap['excerpt']
+
+ def add(result_key, key, namespace=None, filter=None, store_empty=False):
+ if namespace is not None:
+ value = get_text_tag(item, '{{{0}}}{1}'.format(namespace, key), None)
+ else:
+ value = get_text_tag(item, key, None)
+ if value is not None:
+ if filter:
+ value = filter(value)
+ if value or store_empty:
+ result[result_key] = value
+
+ add('title', 'title')
+ add('date_utc', 'post_date_gmt', namespace=wordpress_namespace)
+ add('wordpress_user_name', 'creator', namespace=dc_namespace)
+ add('content', 'encoded', namespace=content_namespace)
+ add('excerpt', 'encoded', namespace=excerpt_namespace)
+ add('description', 'description')
+
+ return result
code_re1 = re.compile(r'\[code.* lang.*?="(.*?)?".*\](.*?)\[/code\]', re.DOTALL | re.MULTILINE)
code_re2 = re.compile(r'\[sourcecode.* lang.*?="(.*?)?".*\](.*?)\[/sourcecode\]', re.DOTALL | re.MULTILINE)
@@ -365,6 +603,7 @@ class CommandImportWordpress(Command, ImportMixin):
code_re4 = re.compile(r'\[sourcecode.*?\](.*?)\[/sourcecode\]', re.DOTALL | re.MULTILINE)
def transform_code(self, content):
+ """Transform code blocks."""
# http://en.support.wordpress.com/code/posting-source-code/. There are
# a ton of things not supported here. We only do a basic [code
# lang="x"] -> ```x translation, and remove quoted html entities (<,
@@ -390,26 +629,126 @@ class CommandImportWordpress(Command, ImportMixin):
@staticmethod
def transform_caption(content):
+ """Transform captions."""
new_caption = re.sub(r'\[/caption\]', '', content)
new_caption = re.sub(r'\[caption.*\]', '', new_caption)
return new_caption
def transform_multiple_newlines(self, content):
- """Replaces multiple newlines with only two."""
+ """Replace multiple newlines with only two."""
if self.squash_newlines:
return re.sub(r'\n{3,}', r'\n\n', content)
else:
return content
- def transform_content(self, content):
- content = self.transform_code(content)
- content = self.transform_caption(content)
- content = self.transform_multiple_newlines(content)
- return content
+ def transform_content(self, content, post_format, attachments):
+ """Transform content into appropriate format."""
+ if post_format == 'wp':
+ if self.transform_to_html:
+ additional_data = {}
+ if attachments is not None:
+ additional_data['attachments'] = attachments
+ try:
+ content = self.wordpress_page_compiler.compile_to_string(content, additional_data=additional_data)
+ except TypeError: # old versions of the plugin don't support the additional argument
+ content = self.wordpress_page_compiler.compile_to_string(content)
+ return content, 'html', True
+ elif self.use_wordpress_compiler:
+ return content, 'wp', False
+ else:
+ content = self.transform_code(content)
+ content = self.transform_caption(content)
+ content = self.transform_multiple_newlines(content)
+ return content, 'md', True
+ elif post_format == 'markdown':
+ return content, 'md', True
+ elif post_format == 'none':
+ return content, 'html', True
+ else:
+ return None
+
+ def _extract_comment(self, comment, wordpress_namespace):
+ """Extract comment from dump."""
+ id = int(get_text_tag(comment, "{{{0}}}comment_id".format(wordpress_namespace), None))
+ author = get_text_tag(comment, "{{{0}}}comment_author".format(wordpress_namespace), None)
+ author_email = get_text_tag(comment, "{{{0}}}comment_author_email".format(wordpress_namespace), None)
+ author_url = get_text_tag(comment, "{{{0}}}comment_author_url".format(wordpress_namespace), None)
+ author_IP = get_text_tag(comment, "{{{0}}}comment_author_IP".format(wordpress_namespace), None)
+ # date = get_text_tag(comment, "{{{0}}}comment_date".format(wordpress_namespace), None)
+ date_gmt = get_text_tag(comment, "{{{0}}}comment_date_gmt".format(wordpress_namespace), None)
+ content = get_text_tag(comment, "{{{0}}}comment_content".format(wordpress_namespace), None)
+ approved = get_text_tag(comment, "{{{0}}}comment_approved".format(wordpress_namespace), '0')
+ if approved == '0':
+ approved = 'hold'
+ elif approved == '1':
+ approved = 'approved'
+ elif approved == 'spam' or approved == 'trash':
+ pass
+ else:
+ LOGGER.warn("Unknown comment approved status: " + str(approved))
+ parent = int(get_text_tag(comment, "{{{0}}}comment_parent".format(wordpress_namespace), 0))
+ if parent == 0:
+ parent = None
+ user_id = int(get_text_tag(comment, "{{{0}}}comment_user_id".format(wordpress_namespace), 0))
+ if user_id == 0:
+ user_id = None
+
+ if approved == 'trash' or approved == 'spam':
+ return None
+
+ return {"id": id, "status": str(approved), "approved": approved == "approved",
+ "author": author, "email": author_email, "url": author_url, "ip": author_IP,
+ "date": date_gmt, "content": content, "parent": parent, "user_id": user_id}
+
+ def _write_comment(self, filename, comment):
+ """Write comment to file."""
+ def write_header_line(fd, header_field, header_content):
+ """Write comment header line."""
+ if header_content is None:
+ return
+ header_content = str(header_content).replace('\n', ' ')
+ line = '.. ' + header_field + ': ' + header_content + '\n'
+ fd.write(line.encode('utf8'))
+
+ with open(filename, "wb+") as fd:
+ write_header_line(fd, "id", comment["id"])
+ write_header_line(fd, "status", comment["status"])
+ write_header_line(fd, "approved", comment["approved"])
+ write_header_line(fd, "author", comment["author"])
+ write_header_line(fd, "author_email", comment["email"])
+ write_header_line(fd, "author_url", comment["url"])
+ write_header_line(fd, "author_IP", comment["ip"])
+ write_header_line(fd, "date_utc", comment["date"])
+ write_header_line(fd, "parent_id", comment["parent"])
+ write_header_line(fd, "wordpress_user_id", comment["user_id"])
+ fd.write(('\n' + comment['content']).encode('utf8'))
+
+ def _create_metadata(self, status, excerpt, tags, categories, post_name=None):
+ """Create post metadata."""
+ other_meta = {'wp-status': status}
+ if excerpt is not None:
+ other_meta['excerpt'] = excerpt
+ if self.export_categories_as_categories:
+ cats = []
+ for text in categories:
+ if text in self._category_paths:
+ cats.append(self._category_paths[text])
+ else:
+ cats.append(utils.join_hierarchical_category_path([text]))
+ other_meta['categories'] = ','.join(cats)
+ if len(cats) > 0:
+ other_meta['category'] = cats[0]
+ if len(cats) > 1:
+ LOGGER.warn(('Post "{0}" has more than one category! ' +
+ 'Will only use the first one.').format(post_name))
+ tags_cats = tags
+ else:
+ tags_cats = tags + categories
+ return tags_cats, other_meta
- def import_item(self, item, wordpress_namespace, out_folder=None):
- """Takes an item from the feed and creates a post file."""
+ def import_postpage_item(self, item, wordpress_namespace, out_folder=None, attachments=None):
+ """Take an item from the feed and creates a post file."""
if out_folder is None:
out_folder = 'posts'
@@ -439,7 +778,7 @@ class CommandImportWordpress(Command, ImportMixin):
item, '{{{0}}}post_id'.format(wordpress_namespace), None)
if not slug: # should never happen
LOGGER.error("Error converting post:", title)
- return
+ return False
else:
if len(pathlist) > 1:
out_folder = os.path.join(*([out_folder] + pathlist[:-1]))
@@ -461,23 +800,42 @@ class CommandImportWordpress(Command, ImportMixin):
item, '{{{0}}}status'.format(wordpress_namespace), 'publish')
content = get_text_tag(
item, '{http://purl.org/rss/1.0/modules/content/}encoded', '')
+ excerpt = get_text_tag(
+ item, '{http://wordpress.org/export/1.2/excerpt/}encoded', None)
+
+ if excerpt is not None:
+ if len(excerpt) == 0:
+ excerpt = None
tags = []
+ categories = []
if status == 'trash':
LOGGER.warn('Trashed post "{0}" will not be imported.'.format(title))
- return
+ return False
+ elif status == 'private':
+ tags.append('private')
+ is_draft = False
+ is_private = True
elif status != 'publish':
tags.append('draft')
is_draft = True
+ is_private = False
else:
is_draft = False
+ is_private = False
for tag in item.findall('category'):
text = tag.text
- if text == 'Uncategorized':
+ type = 'category'
+ if 'domain' in tag.attrib:
+ type = tag.attrib['domain']
+ if text == 'Uncategorized' and type == 'category':
continue
- tags.append(text)
self.all_tags.add(text)
+ if type == 'category':
+ categories.append(type)
+ else:
+ tags.append(text)
if '$latex' in content:
tags.append('mathjax')
@@ -487,11 +845,16 @@ class CommandImportWordpress(Command, ImportMixin):
format_tag = [x for x in item.findall('*//{%s}meta_key' % wordpress_namespace) if x.text == '_tc_post_format']
if format_tag:
post_format = format_tag[0].getparent().find('{%s}meta_value' % wordpress_namespace).text
+ if post_format == 'wpautop':
+ post_format = 'wp'
if is_draft and self.exclude_drafts:
LOGGER.notice('Draft "{0}" will not be imported.'.format(title))
-
- elif content.strip():
+ return False
+ elif is_private and self.exclude_privates:
+ LOGGER.notice('Private post "{0}" will not be imported.'.format(title))
+ return False
+ elif content.strip() or self.import_empty_items:
# If no content is found, no files are written.
self.url_map[link] = (self.context['SITE_URL'] +
out_folder.rstrip('/') + '/' + slug +
@@ -503,53 +866,121 @@ class CommandImportWordpress(Command, ImportMixin):
content_translations = {"": content}
default_language = self.context["DEFAULT_LANG"]
for lang, content in content_translations.items():
+ try:
+ content, extension, rewrite_html = self.transform_content(content, post_format, attachments)
+ except:
+ LOGGER.error(('Cannot interpret post "{0}" (language {1}) with post ' +
+ 'format {2}!').format(os.path.join(out_folder, slug), lang, post_format))
+ return False
if lang:
out_meta_filename = slug + '.meta'
if lang == default_language:
- out_content_filename = slug + '.wp'
+ out_content_filename = slug + '.' + extension
else:
out_content_filename \
= utils.get_translation_candidate(self.context,
- slug + ".wp", lang)
+ slug + "." + extension, lang)
self.extra_languages.add(lang)
meta_slug = slug
else:
out_meta_filename = slug + '.meta'
- out_content_filename = slug + '.wp'
+ out_content_filename = slug + '.' + extension
meta_slug = slug
- if post_format == 'wp':
- content = self.transform_content(content)
+ tags, other_meta = self._create_metadata(status, excerpt, tags, categories,
+ post_name=os.path.join(out_folder, slug))
self.write_metadata(os.path.join(self.output_folder, out_folder,
out_meta_filename),
- title, meta_slug, post_date, description, tags)
+ title, meta_slug, post_date, description, tags, **other_meta)
self.write_content(
os.path.join(self.output_folder,
out_folder, out_content_filename),
- content)
+ content,
+ rewrite_html)
+
+ if self.export_comments:
+ comments = []
+ for tag in item.findall('{{{0}}}comment'.format(wordpress_namespace)):
+ comment = self._extract_comment(tag, wordpress_namespace)
+ if comment is not None:
+ comments.append(comment)
+
+ for comment in comments:
+ comment_filename = slug + "." + str(comment['id']) + ".wpcomment"
+ self._write_comment(os.path.join(self.output_folder, out_folder, comment_filename), comment)
+
+ return (out_folder, slug)
else:
- LOGGER.warn('Not going to import "{0}" because it seems to contain'
- ' no content.'.format(title))
+ LOGGER.warn(('Not going to import "{0}" because it seems to contain'
+ ' no content.').format(title))
+ return False
- def process_item(self, item):
+ def _extract_item_info(self, item):
+ """Extract information about an item."""
# The namespace usually is something like:
# http://wordpress.org/export/1.2/
wordpress_namespace = item.nsmap['wp']
post_type = get_text_tag(
item, '{{{0}}}post_type'.format(wordpress_namespace), 'post')
+ post_id = int(get_text_tag(
+ item, '{{{0}}}post_id'.format(wordpress_namespace), "0"))
+ parent_id = get_text_tag(
+ item, '{{{0}}}post_parent'.format(wordpress_namespace), None)
+ return wordpress_namespace, post_type, post_id, parent_id
+
+ def process_item_if_attachment(self, item):
+ """Process attachments."""
+ wordpress_namespace, post_type, post_id, parent_id = self._extract_item_info(item)
if post_type == 'attachment':
- self.import_attachment(item, wordpress_namespace)
- elif post_type == 'post':
- self.import_item(item, wordpress_namespace, 'posts')
- else:
- self.import_item(item, wordpress_namespace, 'stories')
+ data = self.import_attachment(item, wordpress_namespace)
+ # If parent was found, store relation with imported files
+ if parent_id is not None and int(parent_id) != 0:
+ self.attachments[int(parent_id)][post_id] = data
+ else:
+ LOGGER.warn("Attachment #{0} ({1}) has no parent!".format(post_id, data['files']))
+
+ def write_attachments_info(self, path, attachments):
+ """Write attachments info file."""
+ with io.open(path, "wb") as file:
+ file.write(json.dumps(attachments).encode('utf-8'))
+
+ def process_item_if_post_or_page(self, item):
+ """Process posts and pages."""
+ wordpress_namespace, post_type, post_id, parent_id = self._extract_item_info(item)
+
+ if post_type != 'attachment':
+ # Get attachments for post
+ attachments = self.attachments.pop(post_id, None)
+ # Import item
+ if post_type == 'post':
+ out_folder_slug = self.import_postpage_item(item, wordpress_namespace, 'posts', attachments)
+ else:
+ out_folder_slug = self.import_postpage_item(item, wordpress_namespace, 'stories', attachments)
+ # Process attachment data
+ if attachments is not None:
+ # If post was exported, store data
+ if out_folder_slug:
+ destination = os.path.join(self.output_folder, out_folder_slug[0],
+ out_folder_slug[1] + ".attachments.json")
+ self.write_attachments_info(destination, attachments)
def import_posts(self, channel):
+ """Import posts into the site."""
+ self.attachments = defaultdict(dict)
+ # First process attachments
+ for item in channel.findall('item'):
+ self.process_item_if_attachment(item)
+ # Next process posts
for item in channel.findall('item'):
- self.process_item(item)
+ self.process_item_if_post_or_page(item)
+ # Assign attachments to posts
+ for post_id in self.attachments:
+ LOGGER.warn(("Found attachments for post or page #{0}, but didn't find post or page. " +
+ "(Attachments: {1})").format(post_id, [e['files'][0] for e in self.attachments[post_id].values()]))
def get_text_tag(tag, name, default):
+ """Get the text of an XML tag."""
if tag is None:
return default
t = tag.find(name)
@@ -560,9 +991,10 @@ def get_text_tag(tag, name, default):
def separate_qtranslate_content(text):
- """Parse the content of a wordpress post or page and separate
- the various language specific contents when they are delimited
- with qtranslate tags: <!--:LL-->blabla<!--:-->"""
+ """Parse the content of a wordpress post or page and separate qtranslate languages.
+
+ qtranslate tags: <!--:LL-->blabla<!--:-->
+ """
# TODO: uniformize qtranslate tags <!--/en--> => <!--:-->
qt_start = "<!--:"
qt_end = "-->"
diff --git a/nikola/plugins/command/init.plugin b/nikola/plugins/command/init.plugin
index 850dba9..a5404c4 100644
--- a/nikola/plugins/command/init.plugin
+++ b/nikola/plugins/command/init.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = init
-Module = init
+name = init
+module = init
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create a new site.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create a new site.
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/init.py b/nikola/plugins/command/init.py
index 7a36894..91ccdb4 100644
--- a/nikola/plugins/command/init.py
+++ b/nikola/plugins/command/init.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Create a new site."""
+
from __future__ import print_function, unicode_literals
import os
import shutil
@@ -54,6 +56,7 @@ SAMPLE_CONF = {
'BLOG_EMAIL': "joe@demo.site",
'BLOG_DESCRIPTION': "This is a demo site for Nikola.",
'PRETTY_URLS': False,
+ 'STRIP_INDEXES': False,
'DEFAULT_LANG': "en",
'TRANSLATIONS': """{
DEFAULT_LANG: "",
@@ -64,6 +67,8 @@ SAMPLE_CONF = {
'TIMEZONE': 'UTC',
'COMMENT_SYSTEM': 'disqus',
'COMMENT_SYSTEM_ID': 'nikolademo',
+ 'CATEGORY_ALLOW_HIERARCHIES': False,
+ 'CATEGORY_OUTPUT_FLAT_HIERARCHY': False,
'TRANSLATIONS_PATTERN': DEFAULT_TRANSLATIONS_PATTERN,
'INDEX_READ_MORE_LINK': DEFAULT_INDEX_READ_MORE_LINK,
'RSS_READ_MORE_LINK': DEFAULT_RSS_READ_MORE_LINK,
@@ -103,6 +108,7 @@ SAMPLE_CONF = {
'REDIRECTIONS': [],
}
+
# Generate a list of supported languages here.
# Ugly code follows.
_suplang = {}
@@ -154,8 +160,7 @@ SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'] = '\n'.join(textwrap.wrap(
def format_default_translations_config(additional_languages):
- """Return the string to configure the TRANSLATIONS config variable to
- make each additional language visible on the generated site."""
+ """Adapt TRANSLATIONS setting for all additional languages."""
if not additional_languages:
return SAMPLE_CONF["TRANSLATIONS"]
lang_paths = [' DEFAULT_LANG: "",']
@@ -164,12 +169,12 @@ def format_default_translations_config(additional_languages):
return "{{\n{0}\n}}".format("\n".join(lang_paths))
-def format_navigation_links(additional_languages, default_lang, messages):
+def format_navigation_links(additional_languages, default_lang, messages, strip_indexes=False):
"""Return the string to configure NAVIGATION_LINKS."""
f = u"""\
{0}: (
("{1}/archive.html", "{2[Archive]}"),
- ("{1}/categories/index.html", "{2[Tags]}"),
+ ("{1}/categories/{3}", "{2[Tags]}"),
("{1}/rss.xml", "{2[RSS feed]}"),
),"""
@@ -185,27 +190,32 @@ def format_navigation_links(additional_languages, default_lang, messages):
fmsg[i] = i
return fmsg
+ if strip_indexes:
+ index_html = ''
+ else:
+ index_html = 'index.html'
+
# handle the default language
- pairs.append(f.format('DEFAULT_LANG', '', get_msg(default_lang)))
+ pairs.append(f.format('DEFAULT_LANG', '', get_msg(default_lang), index_html))
for l in additional_languages:
- pairs.append(f.format(json.dumps(l, ensure_ascii=False), '/' + l, get_msg(l)))
+ pairs.append(f.format(json.dumps(l, ensure_ascii=False), '/' + l, get_msg(l), index_html))
return u'{{\n{0}\n}}'.format('\n\n'.join(pairs))
-# In order to ensure proper escaping, all variables but the three
-# pre-formatted ones are handled by json.dumps().
+# In order to ensure proper escaping, all variables but the pre-formatted ones
+# are handled by json.dumps().
def prepare_config(config):
"""Parse sample config with JSON."""
p = config.copy()
- p.update(dict((k, json.dumps(v, ensure_ascii=False)) for k, v in p.items()
- if k not in ('POSTS', 'PAGES', 'COMPILERS', 'TRANSLATIONS', 'NAVIGATION_LINKS', '_SUPPORTED_LANGUAGES', '_SUPPORTED_COMMENT_SYSTEMS', 'INDEX_READ_MORE_LINK', 'RSS_READ_MORE_LINK', 'PRETTY_URLS')))
+ p.update({k: json.dumps(v, ensure_ascii=False) for k, v in p.items()
+ if k not in ('POSTS', 'PAGES', 'COMPILERS', 'TRANSLATIONS', 'NAVIGATION_LINKS', '_SUPPORTED_LANGUAGES', '_SUPPORTED_COMMENT_SYSTEMS', 'INDEX_READ_MORE_LINK', 'RSS_READ_MORE_LINK')})
# READ_MORE_LINKs require some special treatment.
p['INDEX_READ_MORE_LINK'] = "'" + p['INDEX_READ_MORE_LINK'].replace("'", "\\'") + "'"
p['RSS_READ_MORE_LINK'] = "'" + p['RSS_READ_MORE_LINK'].replace("'", "\\'") + "'"
- # json would make that `true` instead of `True`
- p['PRETTY_URLS'] = str(p['PRETTY_URLS'])
+ # fix booleans and None
+ p.update({k: str(v) for k, v in config.items() if isinstance(v, bool) or v is None})
return p
@@ -239,11 +249,13 @@ class CommandInit(Command):
@classmethod
def copy_sample_site(cls, target):
+ """Copy sample site data to target directory."""
src = resource_filename('nikola', os.path.join('data', 'samplesite'))
shutil.copytree(src, target)
@staticmethod
def create_configuration(target):
+ """Create configuration file."""
template_path = resource_filename('nikola', 'conf.py.in')
conf_template = Template(filename=template_path)
conf_path = os.path.join(target, 'conf.py')
@@ -252,12 +264,14 @@ class CommandInit(Command):
@staticmethod
def create_configuration_to_string():
+ """Return configuration file as a string."""
template_path = resource_filename('nikola', 'conf.py.in')
conf_template = Template(filename=template_path)
return conf_template.render(**prepare_config(SAMPLE_CONF))
@classmethod
def create_empty_site(cls, target):
+ """Create an empty site with directories only."""
for folder in ('files', 'galleries', 'listings', 'posts', 'stories'):
makedirs(os.path.join(target, folder))
@@ -295,7 +309,8 @@ class CommandInit(Command):
SAMPLE_CONF['SITE_URL'] = answer
def prettyhandler(default, toconf):
- SAMPLE_CONF['PRETTY_URLS'] = ask_yesno('Enable pretty URLs (/page/ instead of /page.html) that don’t need web server configuration?', default=True)
+ SAMPLE_CONF['PRETTY_URLS'] = ask_yesno('Enable pretty URLs (/page/ instead of /page.html) that don\'t need web server configuration?', default=True)
+ SAMPLE_CONF['STRIP_INDEXES'] = SAMPLE_CONF['PRETTY_URLS']
def lhandler(default, toconf, show_header=True):
if show_header:
@@ -333,7 +348,7 @@ class CommandInit(Command):
# not inherit from anywhere.
try:
messages = load_messages(['base'], tr, default)
- SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(langs, default, messages)
+ SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(langs, default, messages, SAMPLE_CONF['STRIP_INDEXES'])
except nikola.utils.LanguageNotFoundError as e:
print(" ERROR: the language '{0}' is not supported.".format(e.lang))
print(" Are you sure you spelled the name correctly? Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any).")
diff --git a/nikola/plugins/command/install_theme.plugin b/nikola/plugins/command/install_theme.plugin
index 54a91ff..8434f2e 100644
--- a/nikola/plugins/command/install_theme.plugin
+++ b/nikola/plugins/command/install_theme.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = install_theme
-Module = install_theme
+name = install_theme
+module = install_theme
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Install a theme into the current site.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Install a theme into the current site.
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/install_theme.py b/nikola/plugins/command/install_theme.py
index 4937509..f02252e 100644
--- a/nikola/plugins/command/install_theme.py
+++ b/nikola/plugins/command/install_theme.py
@@ -24,10 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Install a theme."""
+
from __future__ import print_function
import os
import io
-import json
+import time
import requests
import pygments
@@ -41,6 +43,7 @@ LOGGER = utils.get_logger('install_theme', utils.STDERR_HANDLER)
class CommandInstallTheme(Command):
+
"""Install a theme."""
name = "install_theme"
@@ -95,8 +98,13 @@ class CommandInstallTheme(Command):
if name is None and not listing:
LOGGER.error("This command needs either a theme name or the -l option.")
return False
- data = requests.get(url).text
- data = json.loads(data)
+ try:
+ data = requests.get(url).json()
+ except requests.exceptions.SSLError:
+ LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
+ time.sleep(1)
+ url = url.replace('https', 'http', 1)
+ data = requests.get(url).json()
if listing:
print("Themes:")
print("-------")
@@ -122,11 +130,21 @@ class CommandInstallTheme(Command):
LOGGER.notice('Remember to set THEME="{0}" in conf.py to use this theme.'.format(origname))
def do_install(self, name, data):
+ """Download and install a theme."""
if name in data:
utils.makedirs(self.output_dir)
- LOGGER.info("Downloading '{0}'".format(data[name]))
+ url = data[name]
+ LOGGER.info("Downloading '{0}'".format(url))
+ try:
+ zip_data = requests.get(url).content
+ except requests.exceptions.SSLError:
+ LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
+ time.sleep(1)
+ url = url.replace('https', 'http', 1)
+ zip_data = requests.get(url).content
+
zip_file = io.BytesIO()
- zip_file.write(requests.get(data[name]).content)
+ zip_file.write(zip_data)
LOGGER.info("Extracting '{0}' into themes/".format(name))
utils.extract_all(zip_file)
dest_path = os.path.join(self.output_dir, name)
diff --git a/nikola/plugins/command/new_page.plugin b/nikola/plugins/command/new_page.plugin
index f078dd6..145a419 100644
--- a/nikola/plugins/command/new_page.plugin
+++ b/nikola/plugins/command/new_page.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = new_page
-Module = new_page
+name = new_page
+module = new_page
[Documentation]
-Author = Roberto Alsina, Chris Warrick
-Version = 1.0
-Website = http://getnikola.com
-Description = Create a new page.
+author = Roberto Alsina, Chris Warrick
+version = 1.0
+website = http://getnikola.com
+description = Create a new page.
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/new_page.py b/nikola/plugins/command/new_page.py
index 39a85bd..811e28b 100644
--- a/nikola/plugins/command/new_page.py
+++ b/nikola/plugins/command/new_page.py
@@ -24,12 +24,15 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Create a new page."""
+
from __future__ import unicode_literals, print_function
from nikola.plugin_categories import Command
class CommandNewPage(Command):
+
"""Create a new page."""
name = "new_page"
diff --git a/nikola/plugins/command/new_post.plugin b/nikola/plugins/command/new_post.plugin
index fec4b1d..d88469f 100644
--- a/nikola/plugins/command/new_post.plugin
+++ b/nikola/plugins/command/new_post.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = new_post
-Module = new_post
+name = new_post
+module = new_post
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create a new post.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create a new post.
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/new_post.py b/nikola/plugins/command/new_post.py
index 5141c7e..f9fe3ff 100644
--- a/nikola/plugins/command/new_post.py
+++ b/nikola/plugins/command/new_post.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Create a new post."""
+
from __future__ import unicode_literals, print_function
import io
import datetime
@@ -44,107 +46,8 @@ PAGELOGGER = utils.get_logger('new_page', utils.STDERR_HANDLER)
LOGGER = POSTLOGGER
-def filter_post_pages(compiler, is_post, compilers, post_pages, compiler_objs, compilers_raw):
- """Given a compiler ("markdown", "rest"), and whether it's meant for
- a post or a page, and compilers, return the correct entry from
- post_pages."""
-
- # First throw away all the post_pages with the wrong is_post
- filtered = [entry for entry in post_pages if entry[3] == is_post]
-
- # These are the extensions supported by the required format
- extensions = compilers.get(compiler)
- if extensions is None:
- if compiler in compiler_objs:
- LOGGER.error("There is a {0} compiler available, but it's not set in your COMPILERS option.".format(compiler))
- LOGGER.info("Read more: {0}".format(COMPILERS_DOC_LINK))
- else:
- LOGGER.error('Unknown format {0}'.format(compiler))
- print_compilers(compilers_raw, post_pages, compiler_objs)
- return False
-
- # Throw away the post_pages with the wrong extensions
- filtered = [entry for entry in filtered if any([ext in entry[0] for ext in
- extensions])]
-
- if not filtered:
- type_name = "post" if is_post else "page"
- LOGGER.error("Can't find a way, using your configuration, to create "
- "a {0} in format {1}. You may want to tweak "
- "COMPILERS or {2}S in conf.py".format(
- type_name, compiler, type_name.upper()))
- LOGGER.info("Read more: {0}".format(COMPILERS_DOC_LINK))
-
- return False
- return filtered[0]
-
-
-def print_compilers(compilers_raw, post_pages, compiler_objs):
- """
- List all available compilers in a human-friendly format.
-
- :param compilers_raw: The compilers dict, mapping compiler names to tuples of extensions
- :param post_pages: The post_pages structure
- :param compilers_objs: Compiler objects
- """
-
- # We use compilers_raw, because the normal dict can contain
- # garbage coming from the translation candidate implementation.
- # Entries are in format: (name, extensions, used_in_post_pages)
- parsed_compilers = {'used': [], 'unused': [], 'disabled': []}
-
- for compiler_name, compiler_obj in compiler_objs.items():
- fname = compiler_obj.friendly_name or compiler_name
- if compiler_name not in compilers_raw:
- parsed_compilers['disabled'].append((compiler_name, fname, (), False))
- else:
- # stolen from filter_post_pages
- extensions = compilers_raw[compiler_name]
- filtered = [entry for entry in post_pages if any(
- [ext in entry[0] for ext in extensions])]
- if filtered:
- parsed_compilers['used'].append((compiler_name, fname, extensions, True))
- else:
- parsed_compilers['unused'].append((compiler_name, fname, extensions, False))
-
- # Sort compilers alphabetically by name, just so it’s prettier (and
- # deterministic)
- parsed_compilers['used'].sort(key=operator.itemgetter(0))
- parsed_compilers['unused'].sort(key=operator.itemgetter(0))
- parsed_compilers['disabled'].sort(key=operator.itemgetter(0))
-
- # We also group the compilers by status for readability.
- parsed_list = parsed_compilers['used'] + parsed_compilers['unused'] + parsed_compilers['disabled']
-
- print("Available input formats:\n")
-
- name_width = max([len(i[0]) for i in parsed_list] + [4]) # 4 == len('NAME')
- fname_width = max([len(i[1]) for i in parsed_list] + [11]) # 11 == len('DESCRIPTION')
-
- print((' {0:<' + str(name_width) + '} {1:<' + str(fname_width) + '} EXTENSIONS\n').format('NAME', 'DESCRIPTION'))
-
- for name, fname, extensions, used in parsed_list:
- flag = ' ' if used else '!'
- flag = flag if extensions else '~'
-
- extensions = ', '.join(extensions) if extensions else '(disabled: not in COMPILERS)'
-
- print(('{flag}{name:<' + str(name_width) + '} {fname:<' + str(fname_width) + '} {extensions}').format(flag=flag, name=name, fname=fname, extensions=extensions))
-
- print("""
-More compilers are available in the Plugins Index.
-
-Compilers marked with ! and ~ require additional configuration:
- ! not in the PAGES/POSTS tuples (unused)
- ~ not in the COMPILERS dict (disabled)
-Read more: {0}""".format(COMPILERS_DOC_LINK))
-
-
def get_default_compiler(is_post, compilers, post_pages):
- """Given compilers and post_pages, return a reasonable
- default compiler for this kind of post/page.
- """
-
+ """Given compilers and post_pages, return a reasonable default compiler for this kind of post/page."""
# First throw away all the post_pages with the wrong is_post
filtered = [entry for entry in post_pages if entry[3] == is_post]
@@ -159,7 +62,7 @@ def get_default_compiler(is_post, compilers, post_pages):
def get_date(schedule=False, rule=None, last_date=None, tz=None, iso8601=False):
- """Returns a date stamp, given a recurrence rule.
+ """Return a date stamp, given a recurrence rule.
schedule - bool:
whether to use the recurrence rule or not
@@ -177,7 +80,6 @@ def get_date(schedule=False, rule=None, last_date=None, tz=None, iso8601=False):
whether to force ISO 8601 dates (instead of locale-specific ones)
"""
-
if tz is None:
tz = dateutil.tz.tzlocal()
date = now = datetime.datetime.now(tz)
@@ -212,6 +114,7 @@ def get_date(schedule=False, rule=None, last_date=None, tz=None, iso8601=False):
class CommandNewPost(Command):
+
"""Create a new post."""
name = "new_post"
@@ -333,7 +236,7 @@ class CommandNewPost(Command):
wants_available = options['available-formats']
if wants_available:
- print_compilers(self.site.config['_COMPILERS_RAW'], self.site.config['post_pages'], self.site.compilers)
+ self.print_compilers()
return
if is_page:
@@ -360,17 +263,13 @@ class CommandNewPost(Command):
if content_format not in compiler_names:
LOGGER.error("Unknown {0} format {1}, maybe you need to install a plugin?".format(content_type, content_format))
- print_compilers(self.site.config['_COMPILERS_RAW'], self.site.config['post_pages'], self.site.compilers)
+ self.print_compilers()
return
compiler_plugin = self.site.plugin_manager.getPluginByName(
content_format, "PageCompiler").plugin_object
# Guess where we should put this
- entry = filter_post_pages(content_format, is_post,
- self.site.config['COMPILERS'],
- self.site.config['post_pages'],
- self.site.compilers,
- self.site.config['_COMPILERS_RAW'])
+ entry = self.filter_post_pages(content_format, is_post)
if entry is False:
return 1
@@ -497,3 +396,122 @@ class CommandNewPost(Command):
subprocess.call(to_run)
else:
LOGGER.error('$EDITOR not set, cannot edit the post. Please do it manually.')
+
+ def filter_post_pages(self, compiler, is_post):
+ """Return the correct entry from post_pages.
+
+ Information based on:
+ * selected compilers
+ * available compilers
+ * post/page status
+ """
+ compilers = self.site.config['COMPILERS']
+ post_pages = self.site.config['post_pages']
+ compiler_objs = self.site.compilers
+
+ # First throw away all the post_pages with the wrong is_post
+ filtered = [entry for entry in post_pages if entry[3] == is_post]
+
+ # These are the extensions supported by the required format
+ extensions = compilers.get(compiler)
+ if extensions is None:
+ if compiler in compiler_objs:
+ LOGGER.error("There is a {0} compiler available, but it's not set in your COMPILERS option.".format(compiler))
+ LOGGER.info("Read more: {0}".format(COMPILERS_DOC_LINK))
+ else:
+ LOGGER.error('Unknown format {0}'.format(compiler))
+ self.print_compilers()
+ return False
+
+ # Throw away the post_pages with the wrong extensions
+ filtered = [entry for entry in filtered if any([ext in entry[0] for ext in
+ extensions])]
+
+ if not filtered:
+ type_name = "post" if is_post else "page"
+ LOGGER.error("Can't find a way, using your configuration, to create "
+ "a {0} in format {1}. You may want to tweak "
+ "COMPILERS or {2}S in conf.py".format(
+ type_name, compiler, type_name.upper()))
+ LOGGER.info("Read more: {0}".format(COMPILERS_DOC_LINK))
+
+ return False
+ return filtered[0]
+
+ def print_compilers(self):
+ """List all available compilers in a human-friendly format."""
+ # We use compilers_raw, because the normal dict can contain
+ # garbage coming from the translation candidate implementation.
+ # Entries are in format: (name, extensions, used_in_post_pages)
+
+ compilers_raw = self.site.config['_COMPILERS_RAW']
+
+ used_compilers = []
+ unused_compilers = []
+ disabled_compilers = []
+
+ for name, plugin in self.site.compilers.items():
+ if name in compilers_raw:
+ used_compilers.append([
+ name,
+ plugin.friendly_name or name,
+ compilers_raw[name],
+ True
+ ])
+ else:
+ disabled_compilers.append([
+ name,
+ plugin.friendly_name or name,
+ (),
+ False
+ ])
+
+ for name, (_, _, pi) in self.site.disabled_compilers.items():
+ if pi.details.has_option('Nikola', 'Friendlyname'):
+ f_name = pi.details.get('Nikola', 'Friendlyname')
+ else:
+ f_name = name
+ if name in compilers_raw:
+ unused_compilers.append([
+ name,
+ f_name,
+ compilers_raw[name],
+ False
+ ])
+ else:
+ disabled_compilers.append([
+ name,
+ f_name,
+ (),
+ False
+ ])
+
+ used_compilers.sort(key=operator.itemgetter(0))
+ unused_compilers.sort(key=operator.itemgetter(0))
+ disabled_compilers.sort(key=operator.itemgetter(0))
+
+ # We also group the compilers by status for readability.
+ parsed_list = used_compilers + unused_compilers + disabled_compilers
+
+ print("Available input formats:\n")
+
+ name_width = max([len(i[0]) for i in parsed_list] + [4]) # 4 == len('NAME')
+ fname_width = max([len(i[1]) for i in parsed_list] + [11]) # 11 == len('DESCRIPTION')
+
+ print((' {0:<' + str(name_width) + '} {1:<' + str(fname_width) + '} EXTENSIONS\n').format('NAME', 'DESCRIPTION'))
+
+ for name, fname, extensions, used in parsed_list:
+ flag = ' ' if used else '!'
+ flag = flag if extensions else '~'
+
+ extensions = ', '.join(extensions) if extensions else '(disabled: not in COMPILERS)'
+
+ print(('{flag}{name:<' + str(name_width) + '} {fname:<' + str(fname_width) + '} {extensions}').format(flag=flag, name=name, fname=fname, extensions=extensions))
+
+ print("""
+ More compilers are available in the Plugins Index.
+
+ Compilers marked with ! and ~ require additional configuration:
+ ! not in the PAGES/POSTS tuples (unused)
+ ~ not in the COMPILERS dict (disabled)
+ Read more: {0}""".format(COMPILERS_DOC_LINK))
diff --git a/nikola/plugins/command/orphans.plugin b/nikola/plugins/command/orphans.plugin
index f491eaf..669429d 100644
--- a/nikola/plugins/command/orphans.plugin
+++ b/nikola/plugins/command/orphans.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = orphans
-Module = orphans
+name = orphans
+module = orphans
[Documentation]
-Author = Roberto Alsina, Chris Warrick
-Version = 1.0
-Website = http://getnikola.com
-Description = List all orphans
+author = Roberto Alsina, Chris Warrick
+version = 1.0
+website = http://getnikola.com
+description = List all orphans
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/orphans.py b/nikola/plugins/command/orphans.py
index f550e17..b12cc67 100644
--- a/nikola/plugins/command/orphans.py
+++ b/nikola/plugins/command/orphans.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""List all orphans."""
+
from __future__ import print_function
import os
@@ -32,6 +34,9 @@ from nikola.plugins.command.check import real_scan_files
class CommandOrphans(Command):
+
+ """List all orphans."""
+
name = "orphans"
doc_purpose = "list all orphans"
doc_description = """\
@@ -41,5 +46,6 @@ but are not generated by Nikola.
Output contains filenames only (it is passable to `xargs rm` or the like)."""
def _execute(self, options, args):
+ """Run the orphans command."""
orphans = real_scan_files(self.site)[0]
print('\n'.join([p for p in orphans if not os.path.isdir(p)]))
diff --git a/nikola/plugins/command/plugin.plugin b/nikola/plugins/command/plugin.plugin
index 2815caa..d44dcf3 100644
--- a/nikola/plugins/command/plugin.plugin
+++ b/nikola/plugins/command/plugin.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = plugin
-Module = plugin
+name = plugin
+module = plugin
[Documentation]
-Author = Roberto Alsina and Chris Warrick
-Version = 1.0
-Website = http://getnikola.com
-Description = Manage Nikola plugins
+author = Roberto Alsina and Chris Warrick
+version = 1.0
+website = http://getnikola.com
+description = Manage Nikola plugins
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/plugin.py b/nikola/plugins/command/plugin.py
index 56eb1d7..f892ee9 100644
--- a/nikola/plugins/command/plugin.py
+++ b/nikola/plugins/command/plugin.py
@@ -24,12 +24,14 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Manage plugins."""
+
from __future__ import print_function
import io
import os
import shutil
import subprocess
-import sys
+import time
import requests
import pygments
@@ -43,6 +45,7 @@ LOGGER = utils.get_logger('plugin', utils.STDERR_HANDLER)
class CommandPlugin(Command):
+
"""Manage plugins."""
json = None
@@ -119,6 +122,7 @@ class CommandPlugin(Command):
upgrade = options.get('upgrade')
list_available = options.get('list')
list_installed = options.get('list_installed')
+ show_install_notes = options.get('show_install_notes', True)
command_count = [bool(x) for x in (
install,
uninstall,
@@ -127,37 +131,42 @@ class CommandPlugin(Command):
list_installed)].count(True)
if command_count > 1 or command_count == 0:
print(self.help())
- return
+ return 2
- if not self.site.configured and not user_mode and install:
- LOGGER.notice('No site found, assuming --user')
- user_mode = True
-
- if user_mode:
- self.output_dir = os.path.expanduser('~/.nikola/plugins')
+ if options.get('output_dir') is not None:
+ self.output_dir = options.get('output_dir')
else:
- self.output_dir = 'plugins'
+ if not self.site.configured and not user_mode and install:
+ LOGGER.notice('No site found, assuming --user')
+ user_mode = True
+
+ if user_mode:
+ self.output_dir = os.path.expanduser('~/.nikola/plugins')
+ else:
+ self.output_dir = 'plugins'
if list_available:
- self.list_available(url)
+ return self.list_available(url)
elif list_installed:
- self.list_installed()
+ return self.list_installed()
elif upgrade:
- self.do_upgrade(url)
+ return self.do_upgrade(url)
elif uninstall:
- self.do_uninstall(uninstall)
+ return self.do_uninstall(uninstall)
elif install:
- self.do_install(url, install)
+ return self.do_install(url, install, show_install_notes)
def list_available(self, url):
+ """List all available plugins."""
data = self.get_json(url)
print("Available Plugins:")
print("------------------")
for plugin in sorted(data.keys()):
print(plugin)
- return True
+ return 0
def list_installed(self):
+ """List installed plugins."""
plugins = []
for plugin in self.site.plugin_manager.getAllPlugins():
p = plugin.path
@@ -170,8 +179,10 @@ class CommandPlugin(Command):
plugins.sort()
for name, path in plugins:
print('{0} at {1}'.format(name, path))
+ return 0
def do_upgrade(self, url):
+ """Upgrade all installed plugins."""
LOGGER.warning('This is not very smart, it just reinstalls some plugins and hopes for the best')
data = self.get_json(url)
plugins = []
@@ -194,18 +205,29 @@ class CommandPlugin(Command):
break
elif tail == '':
LOGGER.error("Can't find the plugins folder for path: {0}".format(p))
- return False
+ return 1
else:
path = tail
self.do_install(url, name)
+ return 0
- def do_install(self, url, name):
+ def do_install(self, url, name, show_install_notes=True):
+ """Download and install a plugin."""
data = self.get_json(url)
if name in data:
utils.makedirs(self.output_dir)
- LOGGER.info('Downloading: ' + data[name])
+ url = data[name]
+ LOGGER.info("Downloading '{0}'".format(url))
+ try:
+ zip_data = requests.get(url).content
+ except requests.exceptions.SSLError:
+ LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
+ time.sleep(1)
+ url = url.replace('https', 'http', 1)
+ zip_data = requests.get(url).content
+
zip_file = io.BytesIO()
- zip_file.write(requests.get(data[name]).content)
+ zip_file.write(zip_data)
LOGGER.info('Extracting: {0} into {1}/'.format(name, self.output_dir))
utils.extract_all(zip_file, self.output_dir)
dest_path = os.path.join(self.output_dir, name)
@@ -214,13 +236,13 @@ class CommandPlugin(Command):
plugin_path = utils.get_plugin_path(name)
except:
LOGGER.error("Can't find plugin " + name)
- return False
+ return 1
utils.makedirs(self.output_dir)
dest_path = os.path.join(self.output_dir, name)
if os.path.exists(dest_path):
LOGGER.error("{0} is already installed".format(name))
- return False
+ return 1
LOGGER.info('Copying {0} into plugins'.format(plugin_path))
shutil.copytree(plugin_path, dest_path)
@@ -256,7 +278,7 @@ class CommandPlugin(Command):
print('You have to install those yourself or through a package '
'manager.')
confpypath = os.path.join(dest_path, 'conf.py.sample')
- if os.path.exists(confpypath):
+ if os.path.exists(confpypath) and show_install_notes:
LOGGER.notice('This plugin has a sample config file. Integrate it with yours in order to make this plugin work!')
print('Contents of the conf.py.sample file:\n')
with io.open(confpypath, 'r', encoding='utf-8') as fh:
@@ -266,9 +288,10 @@ class CommandPlugin(Command):
4 * ' '))
else:
print(utils.indent(fh.read(), 4 * ' '))
- return True
+ return 0
def do_uninstall(self, name):
+ """Uninstall a plugin."""
for plugin in self.site.plugin_manager.getAllPlugins(): # FIXME: this is repeated thrice
p = plugin.path
if os.path.isdir(p):
@@ -278,16 +301,23 @@ class CommandPlugin(Command):
if name == plugin.name: # Uninstall this one
LOGGER.warning('About to uninstall plugin: {0}'.format(name))
LOGGER.warning('This will delete {0}'.format(p))
- inpf = raw_input if sys.version_info[0] == 2 else input
- sure = inpf('Are you sure? [y/n] ')
- if sure.lower().startswith('y'):
+ sure = utils.ask_yesno('Are you sure?')
+ if sure:
LOGGER.warning('Removing {0}'.format(p))
shutil.rmtree(p)
- return True
+ return 0
+ return 1
LOGGER.error('Unknown plugin: {0}'.format(name))
- return False
+ return 1
def get_json(self, url):
+ """Download the JSON file with all plugins."""
if self.json is None:
- self.json = requests.get(url).json()
+ try:
+ self.json = requests.get(url).json()
+ except requests.exceptions.SSLError:
+ LOGGER.warning("SSL error, using http instead of https (press ^C to abort)")
+ time.sleep(1)
+ url = url.replace('https', 'http', 1)
+ self.json = requests.get(url).json()
return self.json
diff --git a/nikola/plugins/command/rst2html.plugin b/nikola/plugins/command/rst2html.plugin
index 0d0d3b0..02c9276 100644
--- a/nikola/plugins/command/rst2html.plugin
+++ b/nikola/plugins/command/rst2html.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = rst2html
-Module = rst2html
+name = rst2html
+module = rst2html
[Documentation]
-Author = Chris Warrick
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile reStructuredText to HTML using the Nikola architecture
+author = Chris Warrick
+version = 1.0
+website = http://getnikola.com
+description = Compile reStructuredText to HTML using the Nikola architecture
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/rst2html/__init__.py b/nikola/plugins/command/rst2html/__init__.py
index 342aaeb..06afffd 100644
--- a/nikola/plugins/command/rst2html/__init__.py
+++ b/nikola/plugins/command/rst2html/__init__.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Compile reStructuredText to HTML, using Nikola architecture."""
+
from __future__ import unicode_literals, print_function
import io
@@ -34,6 +36,7 @@ from nikola.plugin_categories import Command
class CommandRst2Html(Command):
+
"""Compile reStructuredText to HTML, using Nikola architecture."""
name = "rst2html"
diff --git a/nikola/plugins/command/serve.plugin b/nikola/plugins/command/serve.plugin
index 0c1176d..aca71ec 100644
--- a/nikola/plugins/command/serve.plugin
+++ b/nikola/plugins/command/serve.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = serve
-Module = serve
+name = serve
+module = serve
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Start test server.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Start test server.
+
+[Nikola]
+plugincategory = Command
diff --git a/nikola/plugins/command/serve.py b/nikola/plugins/command/serve.py
index 0e4d01f..0441c93 100644
--- a/nikola/plugins/command/serve.py
+++ b/nikola/plugins/command/serve.py
@@ -24,8 +24,11 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Start test server."""
+
from __future__ import print_function
import os
+import re
import socket
import webbrowser
try:
@@ -35,16 +38,25 @@ except ImportError:
from http.server import HTTPServer # NOQA
from http.server import SimpleHTTPRequestHandler # NOQA
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import BytesIO as StringIO # NOQA
+
+
from nikola.plugin_categories import Command
-from nikola.utils import get_logger
+from nikola.utils import get_logger, STDERR_HANDLER
class IPv6Server(HTTPServer):
+
"""An IPv6 HTTPServer."""
+
address_family = socket.AF_INET6
class CommandServe(Command):
+
"""Start test server."""
name = "serve"
@@ -70,6 +82,14 @@ class CommandServe(Command):
'help': 'Address to bind (default: 0.0.0.0 – all local IPv4 interfaces)',
},
{
+ 'name': 'detach',
+ 'short': 'd',
+ 'long': 'detach',
+ 'type': bool,
+ 'default': False,
+ 'help': 'Detach from TTY (work in the background)',
+ },
+ {
'name': 'browser',
'short': 'b',
'long': 'browser',
@@ -89,7 +109,7 @@ class CommandServe(Command):
def _execute(self, options, args):
"""Start test server."""
- self.logger = get_logger('serve', self.site.loghandlers)
+ self.logger = get_logger('serve', STDERR_HANDLER)
out_dir = self.site.config['OUTPUT_FOLDER']
if not os.path.isdir(out_dir):
self.logger.error("Missing '{0}' folder?".format(out_dir))
@@ -117,16 +137,42 @@ class CommandServe(Command):
server_url = "http://{0}:{1}/".format(*sa)
self.logger.info("Opening {0} in the default web browser...".format(server_url))
webbrowser.open(server_url)
- try:
- httpd.serve_forever()
- except KeyboardInterrupt:
- self.logger.info("Server is shutting down.")
- return 130
+ if options['detach']:
+ OurHTTPRequestHandler.quiet = True
+ try:
+ pid = os.fork()
+ if pid == 0:
+ httpd.serve_forever()
+ else:
+ self.logger.info("Detached with PID {0}. Run `kill {0}` to stop the server.".format(pid))
+ except AttributeError as e:
+ if os.name == 'nt':
+ self.logger.warning("Detaching is not available on Windows, server is running in the foreground.")
+ else:
+ raise e
+ else:
+ try:
+ httpd.serve_forever()
+ except KeyboardInterrupt:
+ self.logger.info("Server is shutting down.")
+ return 130
class OurHTTPRequestHandler(SimpleHTTPRequestHandler):
+
+ """A request handler, modified for Nikola."""
+
extensions_map = dict(SimpleHTTPRequestHandler.extensions_map)
extensions_map[""] = "text/plain"
+ quiet = False
+
+ def log_message(self, *args):
+ """Log messages. Or not, depending on a setting."""
+ if self.quiet:
+ return
+ else:
+ # Old-style class in Python 2.7, cannot use super()
+ return SimpleHTTPRequestHandler.log_message(self, *args)
# NOTICE: this is a patched version of send_head() to disable all sorts of
# caching. `nikola serve` is a development server, hence caching should
@@ -182,14 +228,31 @@ class OurHTTPRequestHandler(SimpleHTTPRequestHandler):
except IOError:
self.send_error(404, "File not found")
return None
+
+ filtered_bytes = None
+ if ctype == 'text/html':
+ # Comment out any <base> to allow local resolution of relative URLs.
+ data = f.read().decode('utf8')
+ f.close()
+ data = re.sub(r'<base\s([^>]*)>', '<!--base \g<1>-->', data, re.IGNORECASE)
+ data = data.encode('utf8')
+ f = StringIO()
+ f.write(data)
+ filtered_bytes = len(data)
+ f.seek(0)
+
self.send_response(200)
self.send_header("Content-type", ctype)
if os.path.splitext(path)[1] == '.svgz':
# Special handling for svgz to make it work nice with browsers.
self.send_header("Content-Encoding", 'gzip')
- fs = os.fstat(f.fileno())
- self.send_header("Content-Length", str(fs[6]))
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
+
+ if filtered_bytes is None:
+ fs = os.fstat(f.fileno())
+ self.send_header('Content-Length', str(fs[6]))
+ else:
+ self.send_header('Content-Length', filtered_bytes)
+
# begin no-cache patch
# For standard requests.
self.send_header("Cache-Control", "no-cache, no-store, "
diff --git a/nikola/plugins/command/status.plugin b/nikola/plugins/command/status.plugin
index e02da8b..91390d2 100644
--- a/nikola/plugins/command/status.plugin
+++ b/nikola/plugins/command/status.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = status
-Module = status
+name = status
+module = status
[Documentation]
-Author = Daniel Aleksandersen
-Version = 1.0
-Website = https://getnikola.com
-Description = Site status
+author = Daniel Aleksandersen
+version = 1.0
+website = https://getnikola.com
+description = Site status
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/status.py b/nikola/plugins/command/status.py
index b8a6a60..55e7f95 100644
--- a/nikola/plugins/command/status.py
+++ b/nikola/plugins/command/status.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Display site status."""
+
from __future__ import print_function
import io
import os
@@ -33,8 +35,10 @@ from dateutil.tz import gettz, tzlocal
from nikola.plugin_categories import Command
-class CommandDeploy(Command):
- """ Site status. """
+class CommandStatus(Command):
+
+ """Display site status."""
+
name = "status"
doc_purpose = "display site status"
@@ -69,7 +73,7 @@ class CommandDeploy(Command):
]
def _execute(self, options, args):
-
+ """Display site status."""
self.site.scan_posts()
timestamp_path = os.path.join(self.site.config["CACHE_FOLDER"], "lastdeploy")
@@ -128,6 +132,7 @@ class CommandDeploy(Command):
print("{0} posts in total, {1} scheduled, and {2} drafts.".format(posts_count, len(posts_scheduled), len(posts_drafts)))
def human_time(self, dt):
+ """Translate time into a human-friendly representation."""
days = dt.days
hours = dt.seconds / 60 // 60
minutes = dt.seconds / 60 - (hours * 60)
diff --git a/nikola/plugins/command/version.plugin b/nikola/plugins/command/version.plugin
index a3f58e8..4708bdb 100644
--- a/nikola/plugins/command/version.plugin
+++ b/nikola/plugins/command/version.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = version
-Module = version
+name = version
+module = version
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Show nikola version
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Show nikola version
+
+[Nikola]
+plugincategory = Command
+
diff --git a/nikola/plugins/command/version.py b/nikola/plugins/command/version.py
index b6520d7..ad08f64 100644
--- a/nikola/plugins/command/version.py
+++ b/nikola/plugins/command/version.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Print Nikola version."""
+
from __future__ import print_function
import lxml
@@ -36,7 +38,8 @@ URL = 'https://pypi.python.org/pypi?:action=doap&name=Nikola'
class CommandVersion(Command):
- """Print the version."""
+
+ """Print Nikola version."""
name = "version"
diff --git a/nikola/plugins/compile/__init__.py b/nikola/plugins/compile/__init__.py
index a1d17a6..60f1919 100644
--- a/nikola/plugins/compile/__init__.py
+++ b/nikola/plugins/compile/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Compilers for Nikola."""
diff --git a/nikola/plugins/compile/html.plugin b/nikola/plugins/compile/html.plugin
index 66623b2..53ade61 100644
--- a/nikola/plugins/compile/html.plugin
+++ b/nikola/plugins/compile/html.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = html
-Module = html
+name = html
+module = html
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile HTML into HTML (just copy)
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Compile HTML into HTML (just copy)
+[Nikola]
+plugincategory = Compiler
+friendlyname = HTML
diff --git a/nikola/plugins/compile/html.py b/nikola/plugins/compile/html.py
index ab0c2f6..5f8b244 100644
--- a/nikola/plugins/compile/html.py
+++ b/nikola/plugins/compile/html.py
@@ -36,11 +36,14 @@ from nikola.utils import makedirs, write_metadata
class CompileHtml(PageCompiler):
+
"""Compile HTML into HTML."""
+
name = "html"
friendly_name = "HTML"
def compile_html(self, source, dest, is_two_file=True):
+ """Compile source file into HTML and save as dest."""
makedirs(os.path.dirname(dest))
with io.open(dest, "w+", encoding="utf8") as out_file:
with io.open(source, "r", encoding="utf8") as in_file:
@@ -51,6 +54,7 @@ class CompileHtml(PageCompiler):
return True
def create_post(self, path, **kw):
+ """Create a new post."""
content = kw.pop('content', None)
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
diff --git a/nikola/plugins/compile/ipynb.plugin b/nikola/plugins/compile/ipynb.plugin
index efe6702..c369ab2 100644
--- a/nikola/plugins/compile/ipynb.plugin
+++ b/nikola/plugins/compile/ipynb.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = ipynb
-Module = ipynb
+name = ipynb
+module = ipynb
[Documentation]
-Author = Damian Avila, Chris Warrick and others
-Version = 2.0.0
-Website = http://www.damian.oquanta.info/
-Description = Compile IPython notebooks into Nikola posts
+author = Damian Avila, Chris Warrick and others
+version = 2.0.0
+website = http://www.damian.oquanta.info/
+description = Compile IPython notebooks into Nikola posts
+[Nikola]
+plugincategory = Compiler
+friendlyname = Jupyter/IPython Notebook
diff --git a/nikola/plugins/compile/ipynb.py b/nikola/plugins/compile/ipynb.py
index 82b76c8..a9dedde 100644
--- a/nikola/plugins/compile/ipynb.py
+++ b/nikola/plugins/compile/ipynb.py
@@ -49,10 +49,11 @@ except ImportError:
flag = None
from nikola.plugin_categories import PageCompiler
-from nikola.utils import makedirs, req_missing, get_logger
+from nikola.utils import makedirs, req_missing, get_logger, STDERR_HANDLER
class CompileIPynb(PageCompiler):
+
"""Compile IPynb into HTML."""
name = "ipynb"
@@ -61,24 +62,30 @@ class CompileIPynb(PageCompiler):
default_kernel = 'python2' if sys.version_info[0] == 2 else 'python3'
def set_site(self, site):
- self.logger = get_logger('compile_ipynb', site.loghandlers)
+ """Set Nikola site."""
+ self.logger = get_logger('compile_ipynb', STDERR_HANDLER)
super(CompileIPynb, self).set_site(site)
- def compile_html(self, source, dest, is_two_file=True):
+ def compile_html_string(self, source, is_two_file=True):
+ """Export notebooks as HTML strings."""
if flag is None:
req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)')
- makedirs(os.path.dirname(dest))
HTMLExporter.default_template = 'basic'
c = Config(self.site.config['IPYNB_CONFIG'])
exportHtml = HTMLExporter(config=c)
+ with io.open(source, "r", encoding="utf8") as in_file:
+ nb_json = nbformat.read(in_file, current_nbformat)
+ (body, resources) = exportHtml.from_notebook_node(nb_json)
+ return body
+
+ def compile_html(self, source, dest, is_two_file=True):
+ """Compile source file into HTML and save as dest."""
+ makedirs(os.path.dirname(dest))
with io.open(dest, "w+", encoding="utf8") as out_file:
- with io.open(source, "r", encoding="utf8") as in_file:
- nb_json = nbformat.read(in_file, current_nbformat)
- (body, resources) = exportHtml.from_notebook_node(nb_json)
- out_file.write(body)
+ out_file.write(self.compile_html_string(source, is_two_file))
def read_metadata(self, post, file_metadata_regexp=None, unslugify_titles=False, lang=None):
- """read metadata directly from ipynb file.
+ """Read metadata directly from ipynb file.
As ipynb file support arbitrary metadata as json, the metadata used by Nikola
will be assume to be in the 'nikola' subfield.
@@ -93,6 +100,7 @@ class CompileIPynb(PageCompiler):
return nb_json.get('metadata', {}).get('nikola', {})
def create_post(self, path, **kw):
+ """Create a new post."""
if flag is None:
req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)')
content = kw.pop('content', None)
diff --git a/nikola/plugins/compile/markdown.plugin b/nikola/plugins/compile/markdown.plugin
index a44b798..f7d11b1 100644
--- a/nikola/plugins/compile/markdown.plugin
+++ b/nikola/plugins/compile/markdown.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = markdown
-Module = markdown
+name = markdown
+module = markdown
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile Markdown into HTML
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Compile Markdown into HTML
+[Nikola]
+plugincategory = Compiler
+friendlyname = Markdown
diff --git a/nikola/plugins/compile/markdown/__init__.py b/nikola/plugins/compile/markdown/__init__.py
index fbe049d..c1425a1 100644
--- a/nikola/plugins/compile/markdown/__init__.py
+++ b/nikola/plugins/compile/markdown/__init__.py
@@ -44,6 +44,7 @@ from nikola.utils import makedirs, req_missing, write_metadata
class CompileMarkdown(PageCompiler):
+
"""Compile Markdown into HTML."""
name = "markdown"
@@ -53,21 +54,18 @@ class CompileMarkdown(PageCompiler):
site = None
def set_site(self, site):
+ """Set Nikola site."""
+ super(CompileMarkdown, self).set_site(site)
self.config_dependencies = []
- for plugin_info in site.plugin_manager.getPluginsOfCategory("MarkdownExtension"):
- if plugin_info.name in site.config['DISABLED_PLUGINS']:
- site.plugin_manager.removePluginFromCategory(plugin_info, "MarkdownExtension")
- continue
+ for plugin_info in self.get_compiler_extensions():
self.config_dependencies.append(plugin_info.name)
- site.plugin_manager.activatePluginByName(plugin_info.name)
- plugin_info.plugin_object.set_site(site)
self.extensions.append(plugin_info.plugin_object)
plugin_info.plugin_object.short_help = plugin_info.description
self.config_dependencies.append(str(sorted(site.config.get("MARKDOWN_EXTENSIONS"))))
- return super(CompileMarkdown, self).set_site(site)
def compile_html(self, source, dest, is_two_file=True):
+ """Compile source file into HTML and save as dest."""
if markdown is None:
req_missing(['markdown'], 'build this site (compile Markdown)')
makedirs(os.path.dirname(dest))
@@ -81,6 +79,7 @@ class CompileMarkdown(PageCompiler):
out_file.write(output)
def create_post(self, path, **kw):
+ """Create a new post."""
content = kw.pop('content', None)
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
diff --git a/nikola/plugins/compile/markdown/mdx_gist.plugin b/nikola/plugins/compile/markdown/mdx_gist.plugin
index 0e5c578..7fe676c 100644
--- a/nikola/plugins/compile/markdown/mdx_gist.plugin
+++ b/nikola/plugins/compile/markdown/mdx_gist.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = mdx_gist
-Module = mdx_gist
+name = mdx_gist
+module = mdx_gist
+
+[Nikola]
+compiler = markdown
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Extension for embedding gists
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Extension for embedding gists
+
diff --git a/nikola/plugins/compile/markdown/mdx_gist.py b/nikola/plugins/compile/markdown/mdx_gist.py
index 70e7394..f439fa2 100644
--- a/nikola/plugins/compile/markdown/mdx_gist.py
+++ b/nikola/plugins/compile/markdown/mdx_gist.py
@@ -26,16 +26,16 @@
#
# Inspired by "[Python] reStructuredText GitHub Gist directive"
# (https://gist.github.com/brianhsu/1407759), public domain by Brian Hsu
-'''
-Extension to Python Markdown for Embedded Gists (gist.github.com)
+"""
+Extension to Python Markdown for Embedded Gists (gist.github.com).
Basic Example:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 4747847]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -50,10 +50,10 @@ Basic Example:
Example with filename:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 4747847 zen.py]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -68,10 +68,10 @@ Example with filename:
Basic Example with hexidecimal id:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: c4a43d6fdce612284ac0]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -86,10 +86,10 @@ Basic Example with hexidecimal id:
Example with hexidecimal id filename:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: c4a43d6fdce612284ac0 cow.txt]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -104,10 +104,10 @@ Example with hexidecimal id filename:
Example using reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: 4747847 zen.py
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -122,10 +122,10 @@ Example using reStructuredText syntax:
Example using hexidecimal ID with reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: c4a43d6fdce612284ac0
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -140,10 +140,10 @@ Example using hexidecimal ID with reStructuredText syntax:
Example using hexidecimal ID and filename with reStructuredText syntax:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... .. gist:: c4a43d6fdce612284ac0 cow.txt
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
@@ -158,38 +158,36 @@ Example using hexidecimal ID and filename with reStructuredText syntax:
Error Case: non-existent Gist ID:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 0]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
<div class="gist">
<script src="https://gist.github.com/0.js"></script>
- <noscript><!-- WARNING: Received a 404 response from Gist URL: \
-https://gist.githubusercontent.com/raw/0 --></noscript>
+ <noscript><!-- WARNING: Received a 404 response from Gist URL: https://gist.githubusercontent.com/raw/0 --></noscript>
</div>
</p>
Error Case: non-existent file:
>>> import markdown
- >>> text = """
+ >>> text = '''
... Text of the gist:
... [:gist: 4747847 doesntexist.py]
- ... """
+ ... '''
>>> html = markdown.markdown(text, [GistExtension()])
>>> print(html)
<p>Text of the gist:
<div class="gist">
<script src="https://gist.github.com/4747847.js?file=doesntexist.py"></script>
- <noscript><!-- WARNING: Received a 404 response from Gist URL: \
-https://gist.githubusercontent.com/raw/4747847/doesntexist.py --></noscript>
+ <noscript><!-- WARNING: Received a 404 response from Gist URL: https://gist.githubusercontent.com/raw/4747847/doesntexist.py --></noscript>
</div>
</p>
+"""
-'''
from __future__ import unicode_literals, print_function
try:
@@ -219,20 +217,26 @@ GIST_RST_RE = r'(?m)^\.\.\s*gist::\s*(?P<gist_id>[^\]\s]+)(?:\s*(?P<filename>.+?
class GistFetchException(Exception):
- '''Raised when attempt to fetch content of a Gist from github.com fails.'''
+
+ """Raised when attempt to fetch content of a Gist from github.com fails."""
+
def __init__(self, url, status_code):
+ """Initialize the exception."""
Exception.__init__(self)
self.message = 'Received a {0} response from Gist URL: {1}'.format(
status_code, url)
class GistPattern(Pattern):
- """ InlinePattern for footnote markers in a document's body text. """
+
+ """InlinePattern for footnote markers in a document's body text."""
def __init__(self, pattern, configs):
+ """Initialize the pattern."""
Pattern.__init__(self, pattern)
def get_raw_gist_with_filename(self, gist_id, filename):
+ """Get raw gist text for a filename."""
url = GIST_FILE_RAW_URL.format(gist_id, filename)
resp = requests.get(url)
@@ -242,6 +246,7 @@ class GistPattern(Pattern):
return resp.text
def get_raw_gist(self, gist_id):
+ """Get raw gist text."""
url = GIST_RAW_URL.format(gist_id)
resp = requests.get(url)
@@ -251,6 +256,7 @@ class GistPattern(Pattern):
return resp.text
def handleMatch(self, m):
+ """Handle pattern match."""
gist_id = m.group('gist_id')
gist_file = m.group('filename')
@@ -284,7 +290,11 @@ class GistPattern(Pattern):
class GistExtension(MarkdownExtension, Extension):
+
+ """Gist extension for Markdown."""
+
def __init__(self, configs={}):
+ """Initialize the extension."""
# set extension defaults
self.config = {}
@@ -293,6 +303,7 @@ class GistExtension(MarkdownExtension, Extension):
self.setConfig(key, value)
def extendMarkdown(self, md, md_globals):
+ """Extend Markdown."""
gist_md_pattern = GistPattern(GIST_MD_RE, self.getConfigs())
gist_md_pattern.md = md
md.inlinePatterns.add('gist', gist_md_pattern, "<not_strong")
@@ -304,7 +315,8 @@ class GistExtension(MarkdownExtension, Extension):
md.registerExtension(self)
-def makeExtension(configs=None):
+def makeExtension(configs=None): # pragma: no cover
+ """Make Markdown extension."""
return GistExtension(configs)
if __name__ == '__main__':
diff --git a/nikola/plugins/compile/markdown/mdx_nikola.plugin b/nikola/plugins/compile/markdown/mdx_nikola.plugin
index 7af52a4..12e4fb6 100644
--- a/nikola/plugins/compile/markdown/mdx_nikola.plugin
+++ b/nikola/plugins/compile/markdown/mdx_nikola.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = mdx_nikola
-Module = mdx_nikola
+name = mdx_nikola
+module = mdx_nikola
+
+[Nikola]
+compiler = markdown
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Nikola-specific Markdown extensions
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Nikola-specific Markdown extensions
+
diff --git a/nikola/plugins/compile/markdown/mdx_nikola.py b/nikola/plugins/compile/markdown/mdx_nikola.py
index a03547f..54cc18c 100644
--- a/nikola/plugins/compile/markdown/mdx_nikola.py
+++ b/nikola/plugins/compile/markdown/mdx_nikola.py
@@ -24,7 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Markdown Extension for Nikola-specific post-processing"""
+"""Markdown Extension for Nikola-specific post-processing."""
+
from __future__ import unicode_literals
import re
try:
@@ -41,7 +42,11 @@ CODERE = re.compile('<div class="codehilite"><pre>(.*?)</pre></div>', flags=re.M
class NikolaPostProcessor(Postprocessor):
+
+ """Nikola-specific post-processing for Markdown."""
+
def run(self, text):
+ """Run the postprocessor."""
output = text
# python-markdown's highlighter uses <div class="codehilite"><pre>
@@ -52,11 +57,16 @@ class NikolaPostProcessor(Postprocessor):
class NikolaExtension(MarkdownExtension, Extension):
+
+ """Extension for injecting the postprocessor."""
+
def extendMarkdown(self, md, md_globals):
+ """Extend Markdown with the postprocessor."""
pp = NikolaPostProcessor()
md.postprocessors.add('nikola_post_processor', pp, '_end')
md.registerExtension(self)
-def makeExtension(configs=None):
+def makeExtension(configs=None): # pragma: no cover
+ """Make extension."""
return NikolaExtension(configs)
diff --git a/nikola/plugins/compile/markdown/mdx_podcast.plugin b/nikola/plugins/compile/markdown/mdx_podcast.plugin
index dc16044..c92a8a0 100644
--- a/nikola/plugins/compile/markdown/mdx_podcast.plugin
+++ b/nikola/plugins/compile/markdown/mdx_podcast.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = mdx_podcast
-Module = mdx_podcast
+name = mdx_podcast
+module = mdx_podcast
+
+[Nikola]
+compiler = markdown
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Markdown extensions for embedding podcasts and other audio files
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Markdown extensions for embedding podcasts and other audio files
+
diff --git a/nikola/plugins/compile/markdown/mdx_podcast.py b/nikola/plugins/compile/markdown/mdx_podcast.py
index 670973a..61afdbf 100644
--- a/nikola/plugins/compile/markdown/mdx_podcast.py
+++ b/nikola/plugins/compile/markdown/mdx_podcast.py
@@ -24,21 +24,19 @@
# Inspired by "[Python] reStructuredText GitHub Podcast directive"
# (https://gist.github.com/brianhsu/1407759), public domain by Brian Hsu
-from __future__ import print_function, unicode_literals
-
-
-'''
-Extension to Python Markdown for Embedded Audio
+"""
+Extension to Python Markdown for Embedded Audio.
Basic Example:
>>> import markdown
->>> text = """[podcast]http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3[/podcast]"""
+>>> text = "[podcast]http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3[/podcast]"
>>> html = markdown.markdown(text, [PodcastExtension()])
>>> print(html)
-<p><audio src="http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3"></audio></p>
-'''
+<p><audio controls=""><source src="http://archive.org/download/Rebeldes_Stereotipos/rs20120609_1.mp3" type="audio/mpeg"></source></audio></p>
+"""
+from __future__ import print_function, unicode_literals
from nikola.plugin_categories import MarkdownExtension
try:
from markdown.extensions import Extension
@@ -53,12 +51,15 @@ PODCAST_RE = r'\[podcast\](?P<url>.+)\[/podcast\]'
class PodcastPattern(Pattern):
- """ InlinePattern for footnote markers in a document's body text. """
+
+ """InlinePattern for footnote markers in a document's body text."""
def __init__(self, pattern, configs):
+ """Initialize pattern."""
Pattern.__init__(self, pattern)
def handleMatch(self, m):
+ """Handle pattern matches."""
url = m.group('url').strip()
audio_elem = etree.Element('audio')
audio_elem.set('controls', '')
@@ -69,7 +70,11 @@ class PodcastPattern(Pattern):
class PodcastExtension(MarkdownExtension, Extension):
+
+ """"Podcast extension for Markdown."""
+
def __init__(self, configs={}):
+ """Initialize extension."""
# set extension defaults
self.config = {}
@@ -78,13 +83,15 @@ class PodcastExtension(MarkdownExtension, Extension):
self.setConfig(key, value)
def extendMarkdown(self, md, md_globals):
+ """Extend Markdown."""
podcast_md_pattern = PodcastPattern(PODCAST_RE, self.getConfigs())
podcast_md_pattern.md = md
md.inlinePatterns.add('podcast', podcast_md_pattern, "<not_strong")
md.registerExtension(self)
-def makeExtension(configs=None):
+def makeExtension(configs=None): # pragma: no cover
+ """Make Markdown extension."""
return PodcastExtension(configs)
if __name__ == '__main__':
diff --git a/nikola/plugins/compile/pandoc.plugin b/nikola/plugins/compile/pandoc.plugin
index ad54b3b..3ff3668 100644
--- a/nikola/plugins/compile/pandoc.plugin
+++ b/nikola/plugins/compile/pandoc.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = pandoc
-Module = pandoc
+name = pandoc
+module = pandoc
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile markups into HTML using pandoc
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Compile markups into HTML using pandoc
+[Nikola]
+plugincategory = Compiler
+friendlyname = Pandoc
diff --git a/nikola/plugins/compile/pandoc.py b/nikola/plugins/compile/pandoc.py
index 361f158..3030626 100644
--- a/nikola/plugins/compile/pandoc.py
+++ b/nikola/plugins/compile/pandoc.py
@@ -27,7 +27,6 @@
"""Implementation of compile_html based on pandoc.
You will need, of course, to install pandoc
-
"""
from __future__ import unicode_literals
@@ -41,16 +40,19 @@ from nikola.utils import req_missing, makedirs, write_metadata
class CompilePandoc(PageCompiler):
+
"""Compile markups into HTML using pandoc."""
name = "pandoc"
friendly_name = "pandoc"
def set_site(self, site):
+ """Set Nikola site."""
self.config_dependencies = [str(site.config['PANDOC_OPTIONS'])]
super(CompilePandoc, self).set_site(site)
def compile_html(self, source, dest, is_two_file=True):
+ """Compile source file into HTML and save as dest."""
makedirs(os.path.dirname(dest))
try:
subprocess.check_call(['pandoc', '-o', dest, source] + self.site.config['PANDOC_OPTIONS'])
@@ -59,6 +61,7 @@ class CompilePandoc(PageCompiler):
req_missing(['pandoc'], 'build this site (compile with pandoc)', python=False)
def create_post(self, path, **kw):
+ """Create a new post."""
content = kw.pop('content', None)
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
diff --git a/nikola/plugins/compile/php.plugin b/nikola/plugins/compile/php.plugin
index d6623b5..151c022 100644
--- a/nikola/plugins/compile/php.plugin
+++ b/nikola/plugins/compile/php.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = php
-Module = php
+name = php
+module = php
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile PHP into HTML (just copy and name the file .php)
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Compile PHP into HTML (just copy and name the file .php)
+[Nikola]
+plugincategory = Compiler
+friendlyname = PHP
diff --git a/nikola/plugins/compile/php.py b/nikola/plugins/compile/php.py
index bb436e5..28f4923 100644
--- a/nikola/plugins/compile/php.py
+++ b/nikola/plugins/compile/php.py
@@ -37,12 +37,14 @@ from hashlib import md5
class CompilePhp(PageCompiler):
+
"""Compile PHP into PHP."""
name = "php"
friendly_name = "PHP"
def compile_html(self, source, dest, is_two_file=True):
+ """Compile source file into HTML and save as dest."""
makedirs(os.path.dirname(dest))
with io.open(dest, "w+", encoding="utf8") as out_file:
with open(source, "rb") as in_file:
@@ -51,6 +53,7 @@ class CompilePhp(PageCompiler):
return True
def create_post(self, path, **kw):
+ """Create a new post."""
content = kw.pop('content', None)
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
@@ -80,4 +83,5 @@ class CompilePhp(PageCompiler):
fd.write(content)
def extension(self):
+ """Return extension used for PHP files."""
return ".php"
diff --git a/nikola/plugins/compile/rest.plugin b/nikola/plugins/compile/rest.plugin
index f144809..cf842c7 100644
--- a/nikola/plugins/compile/rest.plugin
+++ b/nikola/plugins/compile/rest.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = rest
-Module = rest
+name = rest
+module = rest
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Compile reSt into HTML
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Compile reSt into HTML
+[Nikola]
+plugincategory = Compiler
+friendlyname = reStructuredText
diff --git a/nikola/plugins/compile/rest/__init__.py b/nikola/plugins/compile/rest/__init__.py
index d446fe8..b99e872 100644
--- a/nikola/plugins/compile/rest/__init__.py
+++ b/nikola/plugins/compile/rest/__init__.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""reStructuredText compiler for Nikola."""
+
from __future__ import unicode_literals
import io
import os
@@ -36,10 +38,11 @@ import docutils.readers.standalone
import docutils.writers.html4css1
from nikola.plugin_categories import PageCompiler
-from nikola.utils import unicode_str, get_logger, makedirs, write_metadata
+from nikola.utils import unicode_str, get_logger, makedirs, write_metadata, STDERR_HANDLER
class CompileRest(PageCompiler):
+
"""Compile reStructuredText into HTML."""
name = "rest"
@@ -48,7 +51,7 @@ class CompileRest(PageCompiler):
logger = None
def _read_extra_deps(self, post):
- """Reads contents of .dep file and returns them as a list"""
+ """Read contents of .dep file and returns them as a list."""
dep_path = post.base_path + '.dep'
if os.path.isfile(dep_path):
with io.open(dep_path, 'r+', encoding='utf8') as depf:
@@ -57,11 +60,11 @@ class CompileRest(PageCompiler):
return []
def register_extra_dependencies(self, post):
- """Adds dependency to post object to check .dep file."""
+ """Add dependency to post object to check .dep file."""
post.add_dependency(lambda: self._read_extra_deps(post), 'fragment')
def compile_html_string(self, data, source_path=None, is_two_file=True):
- """Compile reSt into HTML strings."""
+ """Compile reST into HTML strings."""
# If errors occur, this will be added to the line number reported by
# docutils so the line number matches the actual line number (off by
# 7 with default metadata, could be more or less depending on the post).
@@ -88,7 +91,7 @@ class CompileRest(PageCompiler):
return output, error_level, deps
def compile_html(self, source, dest, is_two_file=True):
- """Compile reSt into HTML files."""
+ """Compile source file into HTML and save as dest."""
makedirs(os.path.dirname(dest))
error_level = 100
with io.open(dest, "w+", encoding="utf8") as out_file:
@@ -110,6 +113,7 @@ class CompileRest(PageCompiler):
return False
def create_post(self, path, **kw):
+ """Create a new post."""
content = kw.pop('content', None)
onefile = kw.pop('onefile', False)
# is_page is not used by create_post as of now.
@@ -127,23 +131,17 @@ class CompileRest(PageCompiler):
fd.write(content)
def set_site(self, site):
+ """Set Nikola site."""
+ super(CompileRest, self).set_site(site)
self.config_dependencies = []
- for plugin_info in site.plugin_manager.getPluginsOfCategory("RestExtension"):
- if plugin_info.name in site.config['DISABLED_PLUGINS']:
- site.plugin_manager.removePluginFromCategory(plugin_info, "RestExtension")
- continue
-
- site.plugin_manager.activatePluginByName(plugin_info.name)
+ for plugin_info in self.get_compiler_extensions():
self.config_dependencies.append(plugin_info.name)
- plugin_info.plugin_object.set_site(site)
plugin_info.plugin_object.short_help = plugin_info.description
- self.logger = get_logger('compile_rest', site.loghandlers)
+ self.logger = get_logger('compile_rest', STDERR_HANDLER)
if not site.debug:
self.logger.level = 4
- return super(CompileRest, self).set_site(site)
-
def get_observer(settings):
"""Return an observer for the docutils Reporter."""
@@ -175,11 +173,15 @@ def get_observer(settings):
class NikolaReader(docutils.readers.standalone.Reader):
+ """Nikola-specific docutils reader."""
+
def __init__(self, *args, **kwargs):
+ """Initialize the reader."""
self.transforms = kwargs.pop('transforms', [])
docutils.readers.standalone.Reader.__init__(self, *args, **kwargs)
def get_transforms(self):
+ """Get docutils transforms."""
return docutils.readers.standalone.Reader(self).get_transforms() + self.transforms
def new_document(self):
@@ -191,8 +193,8 @@ class NikolaReader(docutils.readers.standalone.Reader):
def add_node(node, visit_function=None, depart_function=None):
- """
- Register a Docutils node class.
+ """Register a Docutils node class.
+
This function is completely optional. It is a same concept as
`Sphinx add_node function <http://sphinx-doc.org/ext/appapi.html#sphinx.application.Sphinx.add_node>`_.
@@ -236,8 +238,8 @@ def rst2html(source, source_path=None, source_class=docutils.io.StringInput,
writer_name='html', settings=None, settings_spec=None,
settings_overrides=None, config_section=None,
enable_exit_status=None, logger=None, l_add_ln=0, transforms=None):
- """
- Set up & run a `Publisher`, and return a dictionary of document parts.
+ """Set up & run a ``Publisher``, and return a dictionary of document parts.
+
Dictionary keys are the names of parts, and values are Unicode strings;
encoding is up to the client. For programmatic use with string I/O.
diff --git a/nikola/plugins/compile/rest/chart.plugin b/nikola/plugins/compile/rest/chart.plugin
index 3e27a25..438abe4 100644
--- a/nikola/plugins/compile/rest/chart.plugin
+++ b/nikola/plugins/compile/rest/chart.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_chart
-Module = chart
+name = rest_chart
+module = chart
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Chart directive based in PyGal
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Chart directive based in PyGal
diff --git a/nikola/plugins/compile/rest/chart.py b/nikola/plugins/compile/rest/chart.py
index 59b9dc7..88fdff3 100644
--- a/nikola/plugins/compile/rest/chart.py
+++ b/nikola/plugins/compile/rest/chart.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Chart directive for reSTructuredText."""
+
from ast import literal_eval
from docutils import nodes
@@ -42,9 +44,12 @@ _site = None
class Plugin(RestExtension):
+ """Plugin for chart role."""
+
name = "rest_chart"
def set_site(self, site):
+ """Set Nikola site."""
global _site
_site = self.site = site
directives.register_directive('chart', Chart)
@@ -52,17 +57,18 @@ class Plugin(RestExtension):
class Chart(Directive):
- """ Restructured text extension for inserting charts as SVG
- Usage:
- .. chart:: Bar
- :title: 'Browser usage evolution (in %)'
- :x_labels: ["2002", "2003", "2004", "2005", "2006", "2007"]
+ """reStructuredText extension for inserting charts as SVG.
+
+ Usage:
+ .. chart:: Bar
+ :title: 'Browser usage evolution (in %)'
+ :x_labels: ["2002", "2003", "2004", "2005", "2006", "2007"]
- 'Firefox', [None, None, 0, 16.6, 25, 31]
- 'Chrome', [None, None, None, None, None, None]
- 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
- 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
+ 'Firefox', [None, None, 0, 16.6, 25, 31]
+ 'Chrome', [None, None, None, None, None, None]
+ 'IE', [85.8, 84.6, 84.7, 74.5, 66, 58.6]
+ 'Others', [14.2, 15.4, 15.3, 8.9, 9, 10.4]
"""
has_content = True
@@ -129,6 +135,7 @@ class Chart(Directive):
}
def run(self):
+ """Run the directive."""
if pygal is None:
msg = req_missing(['pygal'], 'use the Chart directive', optional=True)
return [nodes.raw('', '<div class="text-error">{0}</div>'.format(msg), format='html')]
diff --git a/nikola/plugins/compile/rest/doc.plugin b/nikola/plugins/compile/rest/doc.plugin
index 1984f52..facdd03 100644
--- a/nikola/plugins/compile/rest/doc.plugin
+++ b/nikola/plugins/compile/rest/doc.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_doc
-Module = doc
+name = rest_doc
+module = doc
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Manuel Kaufmann
-Version = 0.1
-Website = http://getnikola.com
-Description = Role to link another page / post from the blog
+author = Manuel Kaufmann
+version = 0.1
+website = http://getnikola.com
+description = Role to link another page / post from the blog
diff --git a/nikola/plugins/compile/rest/doc.py b/nikola/plugins/compile/rest/doc.py
index 703c234..99cce81 100644
--- a/nikola/plugins/compile/rest/doc.py
+++ b/nikola/plugins/compile/rest/doc.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""reST role for linking to other documents."""
from docutils import nodes
from docutils.parsers.rst import roles
@@ -34,9 +35,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for doc role."""
+
name = 'rest_doc'
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
roles.register_canonical_role('doc', doc_role)
doc_role.site = site
@@ -45,7 +49,7 @@ class Plugin(RestExtension):
def doc_role(name, rawtext, text, lineno, inliner,
options={}, content=[]):
-
+ """Handle the doc role."""
# split link's text and post's slug in role content
has_explicit_title, title, slug = split_explicit_title(text)
# check if the slug given is part of our blog posts/pages
@@ -82,5 +86,6 @@ def doc_role(name, rawtext, text, lineno, inliner,
def make_link_node(rawtext, text, url, options):
+ """Make a reST link node."""
node = nodes.reference(rawtext, text, refuri=url, *options)
return node
diff --git a/nikola/plugins/compile/rest/gist.plugin b/nikola/plugins/compile/rest/gist.plugin
index 8f498ec..9fa2e82 100644
--- a/nikola/plugins/compile/rest/gist.plugin
+++ b/nikola/plugins/compile/rest/gist.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_gist
-Module = gist
+name = rest_gist
+module = gist
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Gist directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Gist directive
diff --git a/nikola/plugins/compile/rest/gist.py b/nikola/plugins/compile/rest/gist.py
index ab4d56d..736ee37 100644
--- a/nikola/plugins/compile/rest/gist.py
+++ b/nikola/plugins/compile/rest/gist.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# This file is public domain according to its author, Brian Hsu
+"""Gist directive for reStructuredText."""
+
import requests
from docutils.parsers.rst import Directive, directives
from docutils import nodes
@@ -10,26 +12,28 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for gist directive."""
+
name = "rest_gist"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('gist', GitHubGist)
return super(Plugin, self).set_site(site)
class GitHubGist(Directive):
- """ Embed GitHub Gist.
-
- Usage:
- .. gist:: GIST_ID
+ """Embed GitHub Gist.
- or
+ Usage:
- .. gist:: GIST_URL
+ .. gist:: GIST_ID
+ or
+ .. gist:: GIST_URL
"""
required_arguments = 1
@@ -39,10 +43,12 @@ class GitHubGist(Directive):
has_content = False
def get_raw_gist_with_filename(self, gistID, filename):
+ """Get raw gist text for a filename."""
url = '/'.join(("https://gist.github.com/raw", gistID, filename))
return requests.get(url).text
def get_raw_gist(self, gistID):
+ """Get raw gist text."""
url = "https://gist.github.com/raw/{0}".format(gistID)
try:
return requests.get(url).text
@@ -50,6 +56,7 @@ class GitHubGist(Directive):
raise self.error('Cannot get gist for url={0}'.format(url))
def run(self):
+ """Run the gist directive."""
if 'https://' in self.arguments[0]:
gistID = self.arguments[0].split('/')[-1].strip()
else:
diff --git a/nikola/plugins/compile/rest/listing.plugin b/nikola/plugins/compile/rest/listing.plugin
index 4c9883e..85c780f 100644
--- a/nikola/plugins/compile/rest/listing.plugin
+++ b/nikola/plugins/compile/rest/listing.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_listing
-Module = listing
+name = rest_listing
+module = listing
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Extension for source listings
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Extension for source listings
diff --git a/nikola/plugins/compile/rest/listing.py b/nikola/plugins/compile/rest/listing.py
index b8340cf..4871bf3 100644
--- a/nikola/plugins/compile/rest/listing.py
+++ b/nikola/plugins/compile/rest/listing.py
@@ -25,7 +25,7 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-""" Define and register a listing directive using the existing CodeBlock """
+"""Define and register a listing directive using the existing CodeBlock."""
from __future__ import unicode_literals
@@ -55,7 +55,9 @@ from nikola.plugin_categories import RestExtension
# A sanitized version of docutils.parsers.rst.directives.body.CodeBlock.
class CodeBlock(Directive):
+
"""Parse and mark up content of a code block."""
+
optional_arguments = 1
option_spec = {'class': directives.class_option,
'name': directives.unchanged,
@@ -65,6 +67,7 @@ class CodeBlock(Directive):
has_content = True
def run(self):
+ """Run code block directive."""
self.assert_has_content()
if 'linenos' in self.options:
@@ -124,9 +127,12 @@ docutils.parsers.rst.directives.misc.CodeBlock = CodeBlock
class Plugin(RestExtension):
+ """Plugin for listing directive."""
+
name = "rest_listing"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
# Even though listings don't use CodeBlock anymore, I am
# leaving these to make the code directive work with
@@ -146,7 +152,8 @@ listing_spec['linenos'] = directives.unchanged
class Listing(Include):
- """ listing directive: create a highlighted block of code from a file in listings/
+
+ """Create a highlighted block of code from a file in listings/.
Usage:
@@ -154,12 +161,14 @@ class Listing(Include):
:number-lines:
"""
+
has_content = False
required_arguments = 1
optional_arguments = 1
option_spec = listing_spec
def run(self):
+ """Run listing directive."""
_fname = self.arguments.pop(0)
fname = _fname.replace('/', os.sep)
lang = self.arguments.pop(0)
@@ -185,9 +194,9 @@ class Listing(Include):
return generated_nodes
def get_code_from_file(self, data):
- """ Create CodeBlock nodes from file object content """
+ """Create CodeBlock nodes from file object content."""
return super(Listing, self).run()
def assert_has_content(self):
- """ Listing has no content, override check from superclass """
+ """Listing has no content, override check from superclass."""
pass
diff --git a/nikola/plugins/compile/rest/media.plugin b/nikola/plugins/compile/rest/media.plugin
index 5f5276b..9803c8f 100644
--- a/nikola/plugins/compile/rest/media.plugin
+++ b/nikola/plugins/compile/rest/media.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_media
-Module = media
+name = rest_media
+module = media
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Directive to support oembed via micawber
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Directive to support oembed via micawber
diff --git a/nikola/plugins/compile/rest/media.py b/nikola/plugins/compile/rest/media.py
index 0363d28..345e331 100644
--- a/nikola/plugins/compile/rest/media.py
+++ b/nikola/plugins/compile/rest/media.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Media directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -40,21 +41,27 @@ from nikola.utils import req_missing
class Plugin(RestExtension):
+ """Plugin for reST media directive."""
+
name = "rest_media"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('media', Media)
return super(Plugin, self).set_site(site)
class Media(Directive):
- """ Restructured text extension for inserting any sort of media using micawber."""
+
+ """reST extension for inserting any sort of media using micawber."""
+
has_content = False
required_arguments = 1
optional_arguments = 999
def run(self):
+ """Run media directive."""
if micawber is None:
msg = req_missing(['micawber'], 'use the media directive', optional=True)
return [nodes.raw('', '<div class="text-error">{0}</div>'.format(msg), format='html')]
diff --git a/nikola/plugins/compile/rest/post_list.plugin b/nikola/plugins/compile/rest/post_list.plugin
index 82450a0..48969bf 100644
--- a/nikola/plugins/compile/rest/post_list.plugin
+++ b/nikola/plugins/compile/rest/post_list.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = rest_post_list
-Module = post_list
+name = rest_post_list
+module = post_list
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Udo Spallek
-Version = 0.1
-Website = http://getnikola.com
-Description = Includes a list of posts with tag and slide based filters.
+author = Udo Spallek
+version = 0.1
+website = http://getnikola.com
+description = Includes a list of posts with tag and slide based filters.
+
diff --git a/nikola/plugins/compile/rest/post_list.py b/nikola/plugins/compile/rest/post_list.py
index ddbd82d..a22ee85 100644
--- a/nikola/plugins/compile/rest/post_list.py
+++ b/nikola/plugins/compile/rest/post_list.py
@@ -23,6 +23,9 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Post list directive for reStructuredText."""
+
from __future__ import unicode_literals
import os
@@ -40,9 +43,13 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+
+ """Plugin for reST post-list directive."""
+
name = "rest_post_list"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('post-list', PostList)
PostList.site = site
@@ -50,14 +57,15 @@ class Plugin(RestExtension):
class PostList(Directive):
- """
+
+ """Provide a reStructuredText directive to create a list of posts.
+
Post List
=========
:Directive Arguments: None.
- :Directive Options: lang, start, stop, reverse, sort, tags, template, id
+ :Directive Options: lang, start, stop, reverse, sort, tags, categories, slugs, all, template, id
:Directive Content: None.
- Provides a reStructuredText directive to create a list of posts.
The posts appearing in the list can be filtered by options.
*List slicing* is provided with the *start*, *stop* and *reverse* options.
@@ -87,6 +95,10 @@ class PostList(Directive):
Filter posts to show only posts having at least one of the ``tags``.
Defaults to None.
+ ``categories`` : string [, string...]
+ Filter posts to show only posts having one of the ``categories``.
+ Defaults to None.
+
``slugs`` : string [, string...]
Filter posts to show only posts having at least one of the ``slugs``.
Defaults to None.
@@ -107,12 +119,14 @@ class PostList(Directive):
A manual id for the post list.
Defaults to a random name composed by 'post_list_' + uuid.uuid4().hex.
"""
+
option_spec = {
'start': int,
'stop': int,
'reverse': directives.flag,
'sort': directives.unchanged,
'tags': directives.unchanged,
+ 'categories': directives.unchanged,
'slugs': directives.unchanged,
'all': directives.flag,
'lang': directives.unchanged,
@@ -121,11 +135,14 @@ class PostList(Directive):
}
def run(self):
+ """Run post-list directive."""
start = self.options.get('start')
stop = self.options.get('stop')
reverse = self.options.get('reverse', False)
tags = self.options.get('tags')
tags = [t.strip().lower() for t in tags.split(',')] if tags else []
+ categories = self.options.get('categories')
+ categories = [c.strip().lower() for c in categories.split(',')] if categories else []
slugs = self.options.get('slugs')
slugs = [s.strip() for s in slugs.split(',')] if slugs else []
show_all = self.options.get('all', False)
@@ -145,6 +162,9 @@ class PostList(Directive):
else:
timeline = [p for p in self.site.timeline if p.use_in_feeds]
+ if categories:
+ timeline = [p for p in timeline if p.meta('category', lang=lang).lower() in categories]
+
for post in timeline:
if tags:
cont = True
diff --git a/nikola/plugins/compile/rest/slides.plugin b/nikola/plugins/compile/rest/slides.plugin
index cee4b06..5c05b89 100644
--- a/nikola/plugins/compile/rest/slides.plugin
+++ b/nikola/plugins/compile/rest/slides.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_slides
-Module = slides
+name = rest_slides
+module = slides
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Slides directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Slides directive
diff --git a/nikola/plugins/compile/rest/slides.py b/nikola/plugins/compile/rest/slides.py
index 7826f6a..2522e55 100644
--- a/nikola/plugins/compile/rest/slides.py
+++ b/nikola/plugins/compile/rest/slides.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Slides directive for reStructuredText."""
+
from __future__ import unicode_literals
import uuid
@@ -36,9 +38,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for reST slides directive."""
+
name = "rest_slides"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('slides', Slides)
Slides.site = site
@@ -46,11 +51,14 @@ class Plugin(RestExtension):
class Slides(Directive):
- """ Restructured text extension for inserting slideshows."""
+
+ """reST extension for inserting slideshows."""
+
has_content = True
def run(self):
- if len(self.content) == 0:
+ """Run the slides directive."""
+ if len(self.content) == 0: # pragma: no cover
return
if self.site.invariant: # for testing purposes
diff --git a/nikola/plugins/compile/rest/soundcloud.plugin b/nikola/plugins/compile/rest/soundcloud.plugin
index 1d31a8f..75469e4 100644
--- a/nikola/plugins/compile/rest/soundcloud.plugin
+++ b/nikola/plugins/compile/rest/soundcloud.plugin
@@ -1,10 +1,14 @@
[Core]
-Name = rest_soundcloud
-Module = soundcloud
+name = rest_soundcloud
+module = soundcloud
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Roberto Alsina
-Version = 0.1
-Website = http://getnikola.com
-Description = Soundcloud directive
+author = Roberto Alsina
+version = 0.1
+website = http://getnikola.com
+description = Soundcloud directive
diff --git a/nikola/plugins/compile/rest/soundcloud.py b/nikola/plugins/compile/rest/soundcloud.py
index a26806c..30134a9 100644
--- a/nikola/plugins/compile/rest/soundcloud.py
+++ b/nikola/plugins/compile/rest/soundcloud.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+"""SoundCloud directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -10,9 +11,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for soundclound directive."""
+
name = "rest_soundcloud"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('soundcloud', SoundCloud)
directives.register_directive('soundcloud_playlist', SoundCloudPlaylist)
@@ -27,7 +31,8 @@ src="https://w.soundcloud.com/player/?url=http://api.soundcloud.com/{preslug}/""
class SoundCloud(Directive):
- """ Restructured text extension for inserting SoundCloud embedded music
+
+ """reST extension for inserting SoundCloud embedded music.
Usage:
.. soundcloud:: <sound id>
@@ -35,6 +40,7 @@ class SoundCloud(Directive):
:width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -44,7 +50,7 @@ class SoundCloud(Directive):
preslug = "tracks"
def run(self):
- """ Required by the Directive interface. Create docutils nodes """
+ """Run the soundcloud directive."""
self.check_content()
options = {
'sid': self.arguments[0],
@@ -56,12 +62,15 @@ class SoundCloud(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_content(self):
- """ Emit a deprecation warning if there is content """
- if self.content:
+ """Emit a deprecation warning if there is content."""
+ if self.content: # pragma: no cover
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
"use ':key: value' instead")
class SoundCloudPlaylist(SoundCloud):
+
+ """reST directive for SoundCloud playlists."""
+
preslug = "playlists"
diff --git a/nikola/plugins/compile/rest/thumbnail.plugin b/nikola/plugins/compile/rest/thumbnail.plugin
index 3b73340..0084310 100644
--- a/nikola/plugins/compile/rest/thumbnail.plugin
+++ b/nikola/plugins/compile/rest/thumbnail.plugin
@@ -1,9 +1,14 @@
[Core]
-Name = rest_thumbnail
-Module = thumbnail
+name = rest_thumbnail
+module = thumbnail
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Author = Pelle Nilsson
-Version = 0.1
-Website = http://getnikola.com
-Description = reST directive to facilitate enlargeable images with thumbnails
+author = Pelle Nilsson
+version = 0.1
+website = http://getnikola.com
+description = reST directive to facilitate enlargeable images with thumbnails
+
diff --git a/nikola/plugins/compile/rest/thumbnail.py b/nikola/plugins/compile/rest/thumbnail.py
index 5388d8d..1fae06c 100644
--- a/nikola/plugins/compile/rest/thumbnail.py
+++ b/nikola/plugins/compile/rest/thumbnail.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Thumbnail directive for reStructuredText."""
+
import os
from docutils.parsers.rst import directives
@@ -34,9 +36,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for thumbnail directive."""
+
name = "rest_thumbnail"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('thumbnail', Thumbnail)
return super(Plugin, self).set_site(site)
@@ -44,10 +49,14 @@ class Plugin(RestExtension):
class Thumbnail(Figure):
+ """Thumbnail directive for reST."""
+
def align(argument):
+ """Return thumbnail alignment."""
return directives.choice(argument, Image.align_values)
def figwidth_value(argument):
+ """Return figure width."""
if argument.lower() == 'image':
return 'image'
else:
@@ -59,6 +68,7 @@ class Thumbnail(Figure):
has_content = True
def run(self):
+ """Run the thumbnail directive."""
uri = directives.uri(self.arguments[0])
self.options['target'] = uri
self.arguments[0] = '.thumbnail'.join(os.path.splitext(uri))
diff --git a/nikola/plugins/compile/rest/vimeo.plugin b/nikola/plugins/compile/rest/vimeo.plugin
index e0ff3f1..688f981 100644
--- a/nikola/plugins/compile/rest/vimeo.plugin
+++ b/nikola/plugins/compile/rest/vimeo.plugin
@@ -1,7 +1,11 @@
[Core]
-Name = rest_vimeo
-Module = vimeo
+name = rest_vimeo
+module = vimeo
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Description = Vimeo directive
+description = Vimeo directive
diff --git a/nikola/plugins/compile/rest/vimeo.py b/nikola/plugins/compile/rest/vimeo.py
index bc44b0e..c694a87 100644
--- a/nikola/plugins/compile/rest/vimeo.py
+++ b/nikola/plugins/compile/rest/vimeo.py
@@ -24,6 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Vimeo directive for reStructuredText."""
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -37,9 +38,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for vimeo reST directive."""
+
name = "rest_vimeo"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('vimeo', Vimeo)
return super(Plugin, self).set_site(site)
@@ -56,14 +60,16 @@ VIDEO_DEFAULT_WIDTH = 281
class Vimeo(Directive):
- """ Restructured text extension for inserting vimeo embedded videos
- Usage:
- .. vimeo:: 20241459
- :height: 400
- :width: 600
+ """reST extension for inserting vimeo embedded videos.
+
+ Usage:
+ .. vimeo:: 20241459
+ :height: 400
+ :width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -75,6 +81,7 @@ class Vimeo(Directive):
request_size = True
def run(self):
+ """Run the vimeo directive."""
self.check_content()
options = {
'vimeo_id': self.arguments[0],
@@ -90,9 +97,11 @@ class Vimeo(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_modules(self):
+ """Check modules."""
return None
def set_video_size(self):
+ """Set video size."""
# Only need to make a connection if width and height aren't provided
if 'height' not in self.options or 'width' not in self.options:
self.options['height'] = VIDEO_DEFAULT_HEIGHT
@@ -111,6 +120,7 @@ class Vimeo(Directive):
pass
def check_content(self):
+ """Check if content exists."""
if self.content:
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
diff --git a/nikola/plugins/compile/rest/youtube.plugin b/nikola/plugins/compile/rest/youtube.plugin
index 01275be..5fbd67b 100644
--- a/nikola/plugins/compile/rest/youtube.plugin
+++ b/nikola/plugins/compile/rest/youtube.plugin
@@ -1,8 +1,12 @@
[Core]
-Name = rest_youtube
-Module = youtube
+name = rest_youtube
+module = youtube
+
+[Nikola]
+compiler = rest
+plugincategory = CompilerExtension
[Documentation]
-Version = 0.1
-Description = Youtube directive
+version = 0.1
+description = Youtube directive
diff --git a/nikola/plugins/compile/rest/youtube.py b/nikola/plugins/compile/rest/youtube.py
index 7c6bba1..6c5c211 100644
--- a/nikola/plugins/compile/rest/youtube.py
+++ b/nikola/plugins/compile/rest/youtube.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""YouTube directive for reStructuredText."""
+
from docutils import nodes
from docutils.parsers.rst import Directive, directives
@@ -33,9 +35,12 @@ from nikola.plugin_categories import RestExtension
class Plugin(RestExtension):
+ """Plugin for the youtube directive."""
+
name = "rest_youtube"
def set_site(self, site):
+ """Set Nikola site."""
self.site = site
directives.register_directive('youtube', Youtube)
return super(Plugin, self).set_site(site)
@@ -49,7 +54,8 @@ src="//www.youtube.com/embed/{yid}?rel=0&amp;hd=1&amp;wmode=transparent"
class Youtube(Directive):
- """ Restructured text extension for inserting youtube embedded videos
+
+ """reST extension for inserting youtube embedded videos.
Usage:
.. youtube:: lyViVmaBQDg
@@ -57,6 +63,7 @@ class Youtube(Directive):
:width: 600
"""
+
has_content = True
required_arguments = 1
option_spec = {
@@ -65,6 +72,7 @@ class Youtube(Directive):
}
def run(self):
+ """Run the youtube directive."""
self.check_content()
options = {
'yid': self.arguments[0],
@@ -75,7 +83,8 @@ class Youtube(Directive):
return [nodes.raw('', CODE.format(**options), format='html')]
def check_content(self):
- if self.content:
+ """Check if content exists."""
+ if self.content: # pragma: no cover
raise self.warning("This directive does not accept content. The "
"'key=value' format for options is deprecated, "
"use ':key: value' instead")
diff --git a/nikola/plugins/loghandler/smtp.plugin b/nikola/plugins/loghandler/smtp.plugin
deleted file mode 100644
index 38c1d96..0000000
--- a/nikola/plugins/loghandler/smtp.plugin
+++ /dev/null
@@ -1,9 +0,0 @@
-[Core]
-Name = smtp
-Module = smtp
-
-[Documentation]
-Author = Daniel Devine
-Version = 1.0
-Website = http://getnikola.com
-Description = Log over smtp (email).
diff --git a/nikola/plugins/loghandler/smtp.py b/nikola/plugins/loghandler/smtp.py
deleted file mode 100644
index 146a658..0000000
--- a/nikola/plugins/loghandler/smtp.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2012-2015 Daniel Devine and others.
-
-# Permission is hereby granted, free of charge, to any
-# person obtaining a copy of this software and associated
-# documentation files (the "Software"), to deal in the
-# Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the
-# Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice
-# shall be included in all copies or substantial portions of
-# the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from nikola.plugin_categories import SignalHandler
-from blinker import signal
-import logbook
-
-
-class SmtpHandler(SignalHandler):
- name = 'smtp'
-
- def attach_handler(self, sender):
- """Add the handler to a list of handlers that are attached when get_logger() is called.."""
- smtpconf = self.site.config.get('LOGGING_HANDLERS').get('smtp')
- if smtpconf:
- smtpconf['format_string'] = '''\
-Subject: {record.level_name}: {record.channel}
-
-{record.message}
-'''
- self.site.loghandlers.append(logbook.MailHandler(
- smtpconf.pop('from_addr'),
- smtpconf.pop('recipients'),
- **smtpconf
- ))
-
- def set_site(self, site):
- self.site = site
-
- ready = signal('sighandlers_loaded')
- ready.connect(self.attach_handler)
diff --git a/nikola/plugins/loghandler/stderr.plugin b/nikola/plugins/loghandler/stderr.plugin
deleted file mode 100644
index 6c20ea1..0000000
--- a/nikola/plugins/loghandler/stderr.plugin
+++ /dev/null
@@ -1,9 +0,0 @@
-[Core]
-Name = stderr
-Module = stderr
-
-[Documentation]
-Author = Daniel Devine
-Version = 1.0
-Website = http://getnikola.com
-Description = Log to stderr, the default logger.
diff --git a/nikola/plugins/loghandler/stderr.py b/nikola/plugins/loghandler/stderr.py
deleted file mode 100644
index 79ace68..0000000
--- a/nikola/plugins/loghandler/stderr.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2012-2015 Daniel Devine and others.
-
-# Permission is hereby granted, free of charge, to any
-# person obtaining a copy of this software and associated
-# documentation files (the "Software"), to deal in the
-# Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the
-# Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice
-# shall be included in all copies or substantial portions of
-# the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
-# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from nikola.plugin_categories import SignalHandler
-from blinker import signal
-import os
-
-from nikola import DEBUG
-from nikola.utils import ColorfulStderrHandler
-
-
-class StderrHandler(SignalHandler):
- """Logs messages to stderr."""
- name = 'stderr'
-
- def attach_handler(self, sender):
- """Attach the handler to the logger."""
- conf = self.site.config.get('LOGGING_HANDLERS').get('stderr')
- if conf or os.getenv('NIKOLA_DEBUG'):
- self.site.loghandlers.append(ColorfulStderrHandler(
- # We do not allow the level to be something else than 'DEBUG'
- # or 'INFO' Any other level can have bad effects on the user
- # experience and is discouraged.
- # (oh, and it was incorrectly set to WARNING before)
- level='DEBUG' if DEBUG or (conf.get('loglevel', 'INFO').upper() == 'DEBUG') else 'INFO',
- format_string=u'[{record.time:%Y-%m-%dT%H:%M:%SZ}] {record.level_name}: {record.channel}: {record.message}'
- ))
-
- def set_site(self, site):
- self.site = site
-
- ready = signal('sighandlers_loaded')
- ready.connect(self.attach_handler)
diff --git a/nikola/plugins/loghandler/__init__.py b/nikola/plugins/misc/__init__.py
index a1d17a6..c0d8961 100644
--- a/nikola/plugins/loghandler/__init__.py
+++ b/nikola/plugins/misc/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Miscellaneous Nikola plugins."""
diff --git a/nikola/plugins/misc/scan_posts.py b/nikola/plugins/misc/scan_posts.py
index a6f04e6..1f4f995 100644
--- a/nikola/plugins/misc/scan_posts.py
+++ b/nikola/plugins/misc/scan_posts.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""The default post scanner."""
+
from __future__ import unicode_literals, print_function
import glob
import os
@@ -35,13 +37,13 @@ from nikola.post import Post
class ScanPosts(PostScanner):
- """Render pages into output."""
+
+ """Scan posts in the site."""
name = "scan_posts"
def scan(self):
"""Create list of posts from POSTS and PAGES options."""
-
seen = set([])
if not self.site.quiet:
print("Scanning posts", end='', file=sys.stderr)
diff --git a/nikola/plugins/task/__init__.py b/nikola/plugins/task/__init__.py
index a1d17a6..fd9a48f 100644
--- a/nikola/plugins/task/__init__.py
+++ b/nikola/plugins/task/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Tasks for Nikola."""
diff --git a/nikola/plugins/task/archive.plugin b/nikola/plugins/task/archive.plugin
index 6687209..25f1195 100644
--- a/nikola/plugins/task/archive.plugin
+++ b/nikola/plugins/task/archive.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_archive
-Module = archive
+name = render_archive
+module = archive
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generates the blog's archive pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generates the blog's archive pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/archive.py b/nikola/plugins/task/archive.py
index 533be69..126aed4 100644
--- a/nikola/plugins/task/archive.py
+++ b/nikola/plugins/task/archive.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render the post archives."""
+
import copy
import os
@@ -35,17 +37,20 @@ from nikola.utils import config_changed, adjust_name_for_index_path, adjust_name
class Archive(Task):
+
"""Render the post archives."""
name = "render_archive"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('archive', self.archive_path)
site.register_path_handler('archive_atom', self.archive_atom_path)
return super(Archive, self).set_site(site)
def _prepare_task(self, kw, name, lang, posts, items, template_name,
title, deps_translatable=None):
+ """Prepare an archive task."""
# name: used to build permalink and destination
# posts, items: posts or items; only one of them should be used,
# the other be None
@@ -53,17 +58,20 @@ class Archive(Task):
# title: the (translated) title for the generated page
# deps_translatable: dependencies (None if not added)
assert posts is not None or items is not None
-
+ task_cfg = [copy.copy(kw)]
context = {}
context["lang"] = lang
context["title"] = title
context["permalink"] = self.site.link("archive", name, lang)
+ context["pagekind"] = ["list", "archive_page"]
if posts is not None:
context["posts"] = posts
- n = len(posts)
+ # Depend on all post metadata because it can be used in templates (Issue #1931)
+ task_cfg.append([repr(p) for p in posts])
else:
+ # Depend on the content of items, to rebuild if links change (Issue #1931)
context["items"] = items
- n = len(items)
+ task_cfg.append(items)
task = self.site.generic_post_list_renderer(
lang,
[],
@@ -73,7 +81,7 @@ class Archive(Task):
context,
)
- task_cfg = {1: copy.copy(kw), 2: n}
+ task_cfg = {i: x for i, x in enumerate(task_cfg)}
if deps_translatable is not None:
task_cfg[3] = deps_translatable
task['uptodate'] = task['uptodate'] + [config_changed(task_cfg, 'nikola.plugins.task.archive')]
@@ -81,6 +89,7 @@ class Archive(Task):
return task
def _generate_posts_task(self, kw, name, lang, posts, title, deps_translatable=None):
+ """Genereate a task for an archive with posts."""
posts = sorted(posts, key=lambda a: a.date)
posts.reverse()
if kw['archives_are_indexes']:
@@ -97,13 +106,15 @@ class Archive(Task):
uptodate = []
if deps_translatable is not None:
uptodate += [config_changed(deps_translatable, 'nikola.plugins.task.archive')]
+ context = {"archive_name": name,
+ "is_feed_stale": kw["is_feed_stale"],
+ "pagekind": ["index", "archive_page"]}
yield self.site.generic_index_renderer(
lang,
posts,
title,
"archiveindex.tmpl",
- {"archive_name": name,
- "is_feed_stale": kw["is_feed_stale"]},
+ context,
kw,
str(self.name),
page_link,
@@ -113,6 +124,7 @@ class Archive(Task):
yield self._prepare_task(kw, name, lang, posts, None, "list_post.tmpl", title, deps_translatable)
def gen_tasks(self):
+ """Generate archive tasks."""
kw = {
"messages": self.site.MESSAGES,
"translations": self.site.config['TRANSLATIONS'],
@@ -211,6 +223,7 @@ class Archive(Task):
yield self._prepare_task(kw, None, lang, None, items, "list.tmpl", kw["messages"][lang]["Archive"])
def archive_path(self, name, lang, is_feed=False):
+ """Return archive paths."""
if is_feed:
extension = ".atom"
archive_file = os.path.splitext(self.site.config['ARCHIVE_FILENAME'])[0] + extension
@@ -228,4 +241,5 @@ class Archive(Task):
archive_file] if _f]
def archive_atom_path(self, name, lang):
+ """Return Atom archive paths."""
return self.archive_path(name, lang, is_feed=True)
diff --git a/nikola/plugins/task/bundles.plugin b/nikola/plugins/task/bundles.plugin
index 3fe049b..ca997d0 100644
--- a/nikola/plugins/task/bundles.plugin
+++ b/nikola/plugins/task/bundles.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = create_bundles
-Module = bundles
+name = create_bundles
+module = bundles
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Theme bundles using WebAssets
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Theme bundles using WebAssets
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/bundles.py b/nikola/plugins/task/bundles.py
index 6f88d0c..b9c57b9 100644
--- a/nikola/plugins/task/bundles.py
+++ b/nikola/plugins/task/bundles.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Bundle assets using WebAssets."""
+
from __future__ import unicode_literals
import os
@@ -38,12 +40,14 @@ from nikola import utils
class BuildBundles(LateTask):
+
"""Bundle assets using WebAssets."""
name = "create_bundles"
def set_site(self, site):
- self.logger = utils.get_logger('bundles', site.loghandlers)
+ """Set Nikola site."""
+ self.logger = utils.get_logger('bundles', utils.STDERR_HANDLER)
if webassets is None and site.config['USE_BUNDLES']:
utils.req_missing(['webassets'], 'USE_BUNDLES', optional=True)
self.logger.warn('Setting USE_BUNDLES to False.')
@@ -52,7 +56,6 @@ class BuildBundles(LateTask):
def gen_tasks(self):
"""Bundle assets using WebAssets."""
-
kw = {
'filters': self.site.config['FILTERS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/copy_assets.plugin b/nikola/plugins/task/copy_assets.plugin
index 0530ebf..c182150 100644
--- a/nikola/plugins/task/copy_assets.plugin
+++ b/nikola/plugins/task/copy_assets.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = copy_assets
-Module = copy_assets
+name = copy_assets
+module = copy_assets
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Copy theme assets into output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Copy theme assets into output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/copy_assets.py b/nikola/plugins/task/copy_assets.py
index a72bfdf..58521d4 100644
--- a/nikola/plugins/task/copy_assets.py
+++ b/nikola/plugins/task/copy_assets.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Copy theme assets into output."""
+
from __future__ import unicode_literals
import io
@@ -34,6 +36,7 @@ from nikola import utils
class CopyAssets(Task):
+
"""Copy theme assets into output."""
name = "copy_assets"
@@ -44,7 +47,6 @@ class CopyAssets(Task):
If a file is present on two themes, use the version
from the "youngest" theme.
"""
-
kw = {
"themes": self.site.THEMES,
"files_folders": self.site.config['FILES_FOLDERS'],
diff --git a/nikola/plugins/task/copy_files.plugin b/nikola/plugins/task/copy_files.plugin
index 073676b..ce8f5d0 100644
--- a/nikola/plugins/task/copy_files.plugin
+++ b/nikola/plugins/task/copy_files.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = copy_files
-Module = copy_files
+name = copy_files
+module = copy_files
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Copy static files into the output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Copy static files into the output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/copy_files.py b/nikola/plugins/task/copy_files.py
index 9a039f1..1232248 100644
--- a/nikola/plugins/task/copy_files.py
+++ b/nikola/plugins/task/copy_files.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Copy static files into the output folder."""
+
import os
from nikola.plugin_categories import Task
@@ -31,13 +33,13 @@ from nikola import utils
class CopyFiles(Task):
+
"""Copy static files into the output folder."""
name = "copy_files"
def gen_tasks(self):
"""Copy static files into the output folder."""
-
kw = {
'files_folders': self.site.config['FILES_FOLDERS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/galleries.plugin b/nikola/plugins/task/galleries.plugin
index 73085cd..9d3fa28 100644
--- a/nikola/plugins/task/galleries.plugin
+++ b/nikola/plugins/task/galleries.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_galleries
-Module = galleries
+name = render_galleries
+module = galleries
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create image galleries automatically.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create image galleries automatically.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/galleries.py b/nikola/plugins/task/galleries.py
index e887f18..c0df4a4 100644
--- a/nikola/plugins/task/galleries.py
+++ b/nikola/plugins/task/galleries.py
@@ -24,10 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render image galleries."""
+
from __future__ import unicode_literals
-import io
import datetime
import glob
+import io
import json
import mimetypes
import os
@@ -55,17 +57,19 @@ _image_size_cache = {}
class Galleries(Task, ImageProcessor):
+
"""Render image galleries."""
name = 'render_galleries'
dates = {}
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('gallery', self.gallery_path)
site.register_path_handler('gallery_global', self.gallery_global_path)
site.register_path_handler('gallery_rss', self.gallery_rss_path)
- self.logger = utils.get_logger('render_galleries', site.loghandlers)
+ self.logger = utils.get_logger('render_galleries', utils.STDERR_HANDLER)
self.kw = {
'thumbnail_size': site.config['THUMBNAIL_SIZE'],
@@ -118,17 +122,20 @@ class Galleries(Task, ImageProcessor):
sys.exit(1)
def gallery_path(self, name, lang):
+ """Return a gallery path."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in [self.site.config['TRANSLATIONS'][lang]] +
gallery_path.split(os.sep) +
[self.site.config['INDEX_FILE']] if _f]
def gallery_global_path(self, name, lang):
+ """Return the global gallery path, which contains images."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in gallery_path.split(os.sep) +
[self.site.config['INDEX_FILE']] if _f]
def gallery_rss_path(self, name, lang):
+ """Return path to the RSS file for a gallery."""
gallery_path = self._find_gallery_path(name)
return [_f for _f in [self.site.config['TRANSLATIONS'][lang]] +
gallery_path.split(os.sep) +
@@ -136,7 +143,6 @@ class Galleries(Task, ImageProcessor):
def gen_tasks(self):
"""Render image galleries."""
-
self.image_ext_list = self.image_ext_list_builtin
self.image_ext_list.extend(self.site.config.get('EXTRA_IMAGE_EXTENSIONS', []))
@@ -183,11 +189,13 @@ class Galleries(Task, ImageProcessor):
crumbs = utils.get_crumbs(gallery, index_folder=self)
- # Create index.html for each language
for lang in self.kw['translations']:
# save navigation links as dependencies
self.kw['navigation_links|{0}'.format(lang)] = self.kw['global_context']['navigation_links'](lang)
+ # Create index.html for each language
+ for lang in self.kw['translations']:
+
dst = os.path.join(
self.kw['output_folder'],
self.site.path("gallery", gallery, lang))
@@ -238,6 +246,7 @@ class Galleries(Task, ImageProcessor):
context["permalink"] = self.site.link("gallery", gallery, lang)
context["enable_comments"] = self.kw['comments_in_galleries']
context["thumbnail_size"] = self.kw["thumbnail_size"]
+ context["pagekind"] = ["gallery_front"]
if post:
yield {
@@ -246,7 +255,7 @@ class Galleries(Task, ImageProcessor):
'targets': [post.translated_base_path(lang)],
'file_dep': post.fragment_deps(lang),
'actions': [(post.compile, [lang])],
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:post')] + post.fragment_deps_uptodate(lang)
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:post')] + post.fragment_deps_uptodate(lang)
}
context['post'] = post
else:
@@ -259,6 +268,8 @@ class Galleries(Task, ImageProcessor):
file_dep += [post.translated_base_path(l) for l in self.kw['translations']]
file_dep_dest += [post.translated_base_path(l) for l in self.kw['translations']]
+ context["pagekind"] = ["gallery_page"]
+
yield utils.apply_filters({
'basename': self.name,
'name': dst,
@@ -268,14 +279,14 @@ class Galleries(Task, ImageProcessor):
(self.render_gallery_index, (
template_name,
dst,
- context,
+ context.copy(),
dest_img_list,
img_titles,
thumbs,
file_dep))],
'clean': True,
'uptodate': [utils.config_changed({
- 1: self.kw,
+ 1: self.kw.copy(),
2: self.site.config["COMMENTS_IN_GALLERIES"],
3: context.copy(),
}, 'nikola.plugins.task.galleries:gallery')],
@@ -305,21 +316,19 @@ class Galleries(Task, ImageProcessor):
))],
'clean': True,
'uptodate': [utils.config_changed({
- 1: self.kw,
+ 1: self.kw.copy(),
}, 'nikola.plugins.task.galleries:rss')],
}, self.kw['filters'])
def find_galleries(self):
- """Find all galleries to be processed according to conf.py"""
-
+ """Find all galleries to be processed according to conf.py."""
self.gallery_list = []
for input_folder, output_folder in self.kw['gallery_folders'].items():
for root, dirs, files in os.walk(input_folder, followlinks=True):
self.gallery_list.append((root, input_folder, output_folder))
def create_galleries_paths(self):
- """Given a list of galleries, puts their paths into self.gallery_links."""
-
+ """Given a list of galleries, put their paths into self.gallery_links."""
# gallery_path is "gallery/foo/name"
self.proper_gallery_links = dict()
self.improper_gallery_links = dict()
@@ -350,7 +359,6 @@ class Galleries(Task, ImageProcessor):
def create_galleries(self):
"""Given a list of galleries, create the output folders."""
-
# gallery_path is "gallery/foo/name"
for gallery_path, input_folder, _ in self.gallery_list:
# have to use dirname because site.path returns .../index.html
@@ -366,12 +374,11 @@ class Galleries(Task, ImageProcessor):
'actions': [(utils.makedirs, (output_gallery,))],
'targets': [output_gallery],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:mkdir')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:mkdir')],
}
def parse_index(self, gallery, input_folder, output_folder):
- """Returns a Post object if there is an index.txt."""
-
+ """Return a Post object if there is an index.txt."""
index_path = os.path.join(gallery, "index.txt")
destination = os.path.join(
self.kw["output_folder"], output_folder,
@@ -397,6 +404,7 @@ class Galleries(Task, ImageProcessor):
return post
def get_excluded_images(self, gallery_path):
+ """Get list of excluded images."""
exclude_path = os.path.join(gallery_path, "exclude.meta")
try:
@@ -409,7 +417,7 @@ class Galleries(Task, ImageProcessor):
return excluded_image_list
def get_image_list(self, gallery_path):
-
+ """Get list of included images."""
# Gather image_list contains "gallery/name/image_name.jpg"
image_list = []
@@ -424,6 +432,7 @@ class Galleries(Task, ImageProcessor):
return image_list
def create_target_images(self, img, input_path):
+ """Copy images to output."""
gallery_name = os.path.dirname(img)
output_gallery = os.path.dirname(
os.path.join(
@@ -473,6 +482,7 @@ class Galleries(Task, ImageProcessor):
}, self.kw['filters'])
def remove_excluded_image(self, img, input_folder):
+ """Remove excluded images."""
# Remove excluded images
# img is something like input_folder/demo/tesla2_lg.jpg so it's the *source* path
# and we should remove both the large and thumbnail *destination* paths
@@ -493,7 +503,7 @@ class Galleries(Task, ImageProcessor):
(utils.remove_file, (thumb_path,))
],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:clean_thumb')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:clean_thumb')],
}, self.kw['filters'])
yield utils.apply_filters({
@@ -503,7 +513,7 @@ class Galleries(Task, ImageProcessor):
(utils.remove_file, (img_path,))
],
'clean': True,
- 'uptodate': [utils.config_changed(self.kw, 'nikola.plugins.task.galleries:clean_file')],
+ 'uptodate': [utils.config_changed(self.kw.copy(), 'nikola.plugins.task.galleries:clean_file')],
}, self.kw['filters'])
def render_gallery_index(
@@ -516,7 +526,6 @@ class Galleries(Task, ImageProcessor):
thumbs,
file_dep):
"""Build the gallery index."""
-
# The photo array needs to be created here, because
# it relies on thumbnails already being created on
# output
@@ -543,7 +552,7 @@ class Galleries(Task, ImageProcessor):
},
})
context['photo_array'] = photo_array
- context['photo_array_json'] = json.dumps(photo_array)
+ context['photo_array_json'] = json.dumps(photo_array, sort_keys=True)
self.site.render_template(template_name, output_name, context)
def gallery_rss(self, img_list, dest_img_list, img_titles, lang, permalink, output_path, title):
@@ -552,7 +561,6 @@ class Galleries(Task, ImageProcessor):
This doesn't use generic_rss_renderer because it
doesn't involve Post objects.
"""
-
def make_url(url):
return urljoin(self.site.config['BASE_URL'], url.lstrip('/'))
diff --git a/nikola/plugins/task/gzip.plugin b/nikola/plugins/task/gzip.plugin
index 4867fd6..7834d22 100644
--- a/nikola/plugins/task/gzip.plugin
+++ b/nikola/plugins/task/gzip.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = gzip
-Module = gzip
+name = gzip
+module = gzip
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create gzipped copies of files
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create gzipped copies of files
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/gzip.py b/nikola/plugins/task/gzip.py
index 5799839..cf16f63 100644
--- a/nikola/plugins/task/gzip.py
+++ b/nikola/plugins/task/gzip.py
@@ -35,12 +35,14 @@ from nikola.plugin_categories import TaskMultiplier
class GzipFiles(TaskMultiplier):
+
"""If appropiate, create tasks to create gzipped versions of files."""
name = "gzip"
is_default = True
def process(self, task, prefix):
+ """Process tasks."""
if not self.site.config['GZIP_FILES']:
return []
if task.get('name') is None:
@@ -70,6 +72,7 @@ class GzipFiles(TaskMultiplier):
def create_gzipped_copy(in_path, out_path, command=None):
+ """Create gzipped copy of in_path and save it as out_path."""
if command:
subprocess.check_call(shlex.split(command.format(filename=in_path)))
else:
diff --git a/nikola/plugins/task/indexes.plugin b/nikola/plugins/task/indexes.plugin
index 5d2bf5a..d9b0e5f 100644
--- a/nikola/plugins/task/indexes.plugin
+++ b/nikola/plugins/task/indexes.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_indexes
-Module = indexes
+name = render_indexes
+module = indexes
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generates the blog's index pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generates the blog's index pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/indexes.py b/nikola/plugins/task/indexes.py
index 03d36b1..c02818e 100644
--- a/nikola/plugins/task/indexes.py
+++ b/nikola/plugins/task/indexes.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render the blog indexes."""
+
from __future__ import unicode_literals
from collections import defaultdict
import os
@@ -33,16 +35,19 @@ from nikola import utils
class Indexes(Task):
+
"""Render the blog indexes."""
name = "render_indexes"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('index', self.index_path)
site.register_path_handler('index_atom', self.index_atom_path)
return super(Indexes, self).set_site(site)
def gen_tasks(self):
+ """Render the blog indexes."""
self.site.scan_posts()
yield self.group_task()
@@ -80,7 +85,10 @@ class Indexes(Task):
indexes_title = kw['indexes_title'](lang) or kw['blog_title'](lang)
self.number_of_pages[lang] = (len(filtered_posts) + kw['index_display_post_count'] - 1) // kw['index_display_post_count']
- yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, {}, kw, 'render_indexes', page_link, page_path)
+ context = {}
+ context["pagekind"] = ["index"]
+
+ yield self.site.generic_index_renderer(lang, filtered_posts, indexes_title, template_name, context, kw, 'render_indexes', page_link, page_path)
if not self.site.config["STORY_INDEX"]:
return
@@ -93,13 +101,17 @@ class Indexes(Task):
"strip_indexes": self.site.config['STRIP_INDEXES'],
}
template_name = "list.tmpl"
+ index_len = len(kw['index_file'])
for lang in kw["translations"]:
# Need to group by folder to avoid duplicated tasks (Issue #758)
# Group all pages by path prefix
groups = defaultdict(list)
for p in self.site.timeline:
if not p.is_post:
- dirname = os.path.dirname(p.destination_path(lang))
+ destpath = p.destination_path(lang)
+ if destpath[-(1 + index_len):] == '/' + kw['index_file']:
+ destpath = destpath[:-(1 + index_len)]
+ dirname = os.path.dirname(destpath)
groups[dirname].append(p)
for dirname, post_list in groups.items():
context = {}
@@ -108,10 +120,12 @@ class Indexes(Task):
output_name = os.path.join(kw['output_folder'], dirname, kw['index_file'])
short_destination = os.path.join(dirname, kw['index_file'])
link = short_destination.replace('\\', '/')
- index_len = len(kw['index_file'])
if kw['strip_indexes'] and link[-(1 + index_len):] == '/' + kw['index_file']:
link = link[:-index_len]
context["permalink"] = link
+ context["pagekind"] = ["list"]
+ if dirname == "/":
+ context["pagekind"].append("front_page")
for post in post_list:
# If there is an index.html pending to be created from
@@ -133,6 +147,7 @@ class Indexes(Task):
yield task
def index_path(self, name, lang, is_feed=False):
+ """Return path to an index."""
extension = None
if is_feed:
extension = ".atom"
@@ -149,4 +164,5 @@ class Indexes(Task):
extension=extension)
def index_atom_path(self, name, lang):
+ """Return path to an Atom index."""
return self.index_path(name, lang, is_feed=True)
diff --git a/nikola/plugins/task/listings.plugin b/nikola/plugins/task/listings.plugin
index a5ba77a..435234b 100644
--- a/nikola/plugins/task/listings.plugin
+++ b/nikola/plugins/task/listings.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_listings
-Module = listings
+name = render_listings
+module = listings
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Render code listings into output
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Render code listings into output
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/listings.py b/nikola/plugins/task/listings.py
index b913330..5f79724 100644
--- a/nikola/plugins/task/listings.py
+++ b/nikola/plugins/task/listings.py
@@ -24,10 +24,13 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render code listings."""
+
from __future__ import unicode_literals, print_function
import sys
import os
+import lxml.html
from pygments import highlight
from pygments.lexers import get_lexer_for_filename, TextLexer
@@ -38,7 +41,8 @@ from nikola import utils
class Listings(Task):
- """Render pretty listings."""
+
+ """Render code listings."""
name = "render_listings"
@@ -51,6 +55,7 @@ class Listings(Task):
self.proper_input_file_mapping[rel_output_name] = rel_output_name
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('listing', self.listing_path)
# We need to prepare some things for the listings path handler to work.
@@ -105,12 +110,21 @@ class Listings(Task):
def gen_tasks(self):
"""Render pretty code listings."""
-
# Things to ignore in listings
ignored_extensions = (".pyc", ".pyo")
def render_listing(in_name, out_name, input_folder, output_folder, folders=[], files=[]):
- if in_name:
+ needs_ipython_css = False
+ if in_name and in_name.endswith('.ipynb'):
+ # Special handling: render ipynbs in listings (Issue #1900)
+ ipynb_compiler = self.site.plugin_manager.getPluginByName("ipynb", "PageCompiler").plugin_object
+ ipynb_raw = ipynb_compiler.compile_html_string(in_name, True)
+ ipynb_html = lxml.html.fromstring(ipynb_raw)
+ # The raw HTML contains garbage (scripts and styles), we can’t leave it in
+ code = lxml.html.tostring(ipynb_html.xpath('//*[@id="notebook"]')[0], encoding='unicode')
+ title = os.path.basename(in_name)
+ needs_ipython_css = True
+ elif in_name:
with open(in_name, 'r') as fd:
try:
lexer = get_lexer_for_filename(in_name)
@@ -149,7 +163,12 @@ class Listings(Task):
files, alg=natsort.ns.F | natsort.ns.IC),
'description': title,
'source_link': source_link,
+ 'pagekind': ['listing'],
}
+ if needs_ipython_css:
+ # If someone does not have ipynb posts and only listings, we
+ # need to enable ipynb CSS for ipynb listings.
+ context['needs_ipython_css'] = True
self.site.render_template('listing.tmpl', out_name, context)
yield self.group_task()
@@ -236,6 +255,7 @@ class Listings(Task):
}, self.kw["filters"])
def listing_path(self, namep, lang):
+ """Return path to a listing."""
namep = namep.replace('/', os.sep)
nameh = namep + '.html'
for name in (namep, nameh):
diff --git a/nikola/plugins/task/pages.plugin b/nikola/plugins/task/pages.plugin
index 4cad7b7..023d41b 100644
--- a/nikola/plugins/task/pages.plugin
+++ b/nikola/plugins/task/pages.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_pages
-Module = pages
+name = render_pages
+module = pages
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create pages in the output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create pages in the output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/pages.py b/nikola/plugins/task/pages.py
index d0edb56..e6a8a82 100644
--- a/nikola/plugins/task/pages.py
+++ b/nikola/plugins/task/pages.py
@@ -24,12 +24,15 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render pages into output."""
+
from __future__ import unicode_literals
from nikola.plugin_categories import Task
from nikola.utils import config_changed
class RenderPages(Task):
+
"""Render pages into output."""
name = "render_pages"
@@ -49,8 +52,11 @@ class RenderPages(Task):
for post in self.site.timeline:
if not kw["show_untranslated_posts"] and not post.is_translation_available(lang):
continue
- for task in self.site.generic_page_renderer(lang, post,
- kw["filters"]):
+ if post.is_post:
+ context = {'pagekind': ['post_page']}
+ else:
+ context = {'pagekind': ['story_page']}
+ for task in self.site.generic_page_renderer(lang, post, kw["filters"], context):
task['uptodate'] = task['uptodate'] + [config_changed(kw, 'nikola.plugins.task.pages')]
task['basename'] = self.name
task['task_dep'] = ['render_posts']
diff --git a/nikola/plugins/task/posts.plugin b/nikola/plugins/task/posts.plugin
index 707b3c2..79b7c51 100644
--- a/nikola/plugins/task/posts.plugin
+++ b/nikola/plugins/task/posts.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_posts
-Module = posts
+name = render_posts
+module = posts
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create HTML fragments out of posts.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create HTML fragments out of posts.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/posts.py b/nikola/plugins/task/posts.py
index d3f17fd..a3a8375 100644
--- a/nikola/plugins/task/posts.py
+++ b/nikola/plugins/task/posts.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Build HTML fragments from metadata and text."""
+
from copy import copy
import os
@@ -32,7 +34,7 @@ from nikola import filters, utils
def update_deps(post, lang, task):
- """Updates file dependencies as they might have been updated during compilation.
+ """Update file dependencies as they might have been updated during compilation.
This is done for example by the ReST page compiler, which writes its
dependencies into a .dep file. This file is read and incorporated when calling
@@ -42,6 +44,7 @@ def update_deps(post, lang, task):
class RenderPosts(Task):
+
"""Build HTML fragments from metadata and text."""
name = "render_posts"
@@ -74,7 +77,11 @@ class RenderPosts(Task):
deps_dict = copy(kw)
deps_dict.pop('timeline')
for post in kw['timeline']:
-
+ # Extra config dependencies picked from config
+ for p in post.fragment_deps(lang):
+ if p.startswith('####MAGIC####CONFIG:'):
+ k = p.split('####MAGIC####CONFIG:', 1)[-1]
+ deps_dict[k] = self.site.config.get(k)
dest = post.translated_base_path(lang)
file_dep = [p for p in post.fragment_deps(lang) if not p.startswith("####MAGIC####")]
task = {
@@ -110,6 +117,7 @@ class RenderPosts(Task):
yield utils.apply_filters(task, {os.path.splitext(dest): flist})
def dependence_on_timeline(self, post, lang):
+ """Check if a post depends on the timeline."""
if "####MAGIC####TIMELINE" not in post.fragment_deps(lang):
return True # No dependency on timeline
elif self.tl_changed:
diff --git a/nikola/plugins/task/redirect.plugin b/nikola/plugins/task/redirect.plugin
index 0228c70..c3137b9 100644
--- a/nikola/plugins/task/redirect.plugin
+++ b/nikola/plugins/task/redirect.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = redirect
-Module = redirect
+name = redirect
+module = redirect
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Create redirect pages.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Create redirect pages.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/redirect.py b/nikola/plugins/task/redirect.py
index 428dd5a..8530f5e 100644
--- a/nikola/plugins/task/redirect.py
+++ b/nikola/plugins/task/redirect.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate redirections."""
+
from __future__ import unicode_literals
import os
@@ -33,13 +35,13 @@ from nikola import utils
class Redirect(Task):
- """Generate redirections"""
+
+ """Generate redirections."""
name = "redirect"
def gen_tasks(self):
"""Generate redirections tasks."""
-
kw = {
'redirections': self.site.config['REDIRECTIONS'],
'output_folder': self.site.config['OUTPUT_FOLDER'],
diff --git a/nikola/plugins/task/robots.plugin b/nikola/plugins/task/robots.plugin
index b4b43a3..72ce31f 100644
--- a/nikola/plugins/task/robots.plugin
+++ b/nikola/plugins/task/robots.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = robots
-Module = robots
+name = robots
+module = robots
[Documentation]
-Author = Daniel Aleksandersen
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate /robots.txt exclusion file and promote sitemap.
+author = Daniel Aleksandersen
+version = 1.0
+website = http://getnikola.com
+description = Generate /robots.txt exclusion file and promote sitemap.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/robots.py b/nikola/plugins/task/robots.py
index 2f25a21..65254b6 100644
--- a/nikola/plugins/task/robots.py
+++ b/nikola/plugins/task/robots.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate a robots.txt file."""
+
from __future__ import print_function, absolute_import, unicode_literals
import io
import os
@@ -37,12 +39,13 @@ from nikola import utils
class RobotsFile(LateTask):
- """Generate a robots.txt."""
+
+ """Generate a robots.txt file."""
name = "robots_file"
def gen_tasks(self):
- """Generate a robots.txt."""
+ """Generate a robots.txt file."""
kw = {
"base_url": self.site.config["BASE_URL"],
"site_url": self.site.config["SITE_URL"],
diff --git a/nikola/plugins/task/rss.plugin b/nikola/plugins/task/rss.plugin
index 56f0bf4..cf9b7a7 100644
--- a/nikola/plugins/task/rss.plugin
+++ b/nikola/plugins/task/rss.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = generate_rss
-Module = rss
+name = generate_rss
+module = rss
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate RSS feeds.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generate RSS feeds.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/rss.py b/nikola/plugins/task/rss.py
index 26a4da1..9020a06 100644
--- a/nikola/plugins/task/rss.py
+++ b/nikola/plugins/task/rss.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate RSS feeds."""
+
from __future__ import unicode_literals, print_function
import os
try:
@@ -36,11 +38,13 @@ from nikola.plugin_categories import Task
class GenerateRSS(Task):
+
"""Generate RSS feeds."""
name = "generate_rss"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('rss', self.rss_path)
return super(GenerateRSS, self).set_site(site)
@@ -102,5 +106,6 @@ class GenerateRSS(Task):
yield utils.apply_filters(task, kw['filters'])
def rss_path(self, name, lang):
+ """Return RSS path."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['RSS_PATH'], 'rss.xml'] if _f]
diff --git a/nikola/plugins/task/scale_images.plugin b/nikola/plugins/task/scale_images.plugin
index c0f0f28..d906b8c 100644
--- a/nikola/plugins/task/scale_images.plugin
+++ b/nikola/plugins/task/scale_images.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = scale_images
-Module = scale_images
+name = scale_images
+module = scale_images
[Documentation]
-Author = Pelle Nilsson
-Version = 1.0
-Website = http://getnikola.com
-Description = Create down-scaled images and thumbnails.
+author = Pelle Nilsson
+version = 1.0
+website = http://getnikola.com
+description = Create down-scaled images and thumbnails.
+
+[Nikola]
+plugincategory = Task
+
diff --git a/nikola/plugins/task/scale_images.py b/nikola/plugins/task/scale_images.py
index f97027e..22ed2ab 100644
--- a/nikola/plugins/task/scale_images.py
+++ b/nikola/plugins/task/scale_images.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Resize images and create thumbnails for them."""
+
import os
from nikola.plugin_categories import Task
@@ -32,17 +34,18 @@ from nikola import utils
class ScaleImage(Task, ImageProcessor):
- """Copy static files into the output folder."""
+
+ """Resize images and create thumbnails for them."""
name = "scale_images"
def set_site(self, site):
- self.logger = utils.get_logger('scale_images', site.loghandlers)
+ """Set Nikola site."""
+ self.logger = utils.get_logger('scale_images', utils.STDERR_HANDLER)
return super(ScaleImage, self).set_site(site)
def process_tree(self, src, dst):
- """Processes all images in a src tree and put the (possibly) rescaled
- images in the dst folder."""
+ """Process all images in a src tree and put the (possibly) rescaled images in the dst folder."""
ignore = set(['.svn'])
base_len = len(src.split(os.sep))
for root, dirs, files in os.walk(src, followlinks=True):
@@ -68,12 +71,12 @@ class ScaleImage(Task, ImageProcessor):
}
def process_image(self, src, dst, thumb):
+ """Resize an image."""
self.resize_image(src, dst, self.kw['max_image_size'], False)
self.resize_image(src, thumb, self.kw['image_thumbnail_size'], False)
def gen_tasks(self):
"""Copy static files into the output folder."""
-
self.kw = {
'image_thumbnail_size': self.site.config['IMAGE_THUMBNAIL_SIZE'],
'max_image_size': self.site.config['MAX_IMAGE_SIZE'],
diff --git a/nikola/plugins/task/sitemap.plugin b/nikola/plugins/task/sitemap.plugin
index 0b992b8..e3c991f 100644
--- a/nikola/plugins/task/sitemap.plugin
+++ b/nikola/plugins/task/sitemap.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = sitemap
-Module = sitemap
+name = sitemap
+module = sitemap
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Generate google sitemap.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Generate google sitemap.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/sitemap/__init__.py b/nikola/plugins/task/sitemap/__init__.py
index 92d557d..fd781d6 100644
--- a/nikola/plugins/task/sitemap/__init__.py
+++ b/nikola/plugins/task/sitemap/__init__.py
@@ -24,9 +24,12 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Generate a sitemap."""
+
from __future__ import print_function, absolute_import, unicode_literals
import io
import datetime
+import dateutil.tz
import os
try:
from urlparse import urljoin, urlparse
@@ -42,6 +45,7 @@ from nikola.utils import config_changed, apply_filters
urlset_header = """<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
@@ -58,6 +62,7 @@ urlset_footer = "</urlset>"
sitemapindex_header = """<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
@@ -76,7 +81,7 @@ sitemapindex_footer = "</sitemapindex>"
def get_base_path(base):
- """returns the path of a base URL if it contains one.
+ """Return the path of a base URL if it contains one.
>>> get_base_path('http://some.site') == '/'
True
@@ -101,6 +106,7 @@ def get_base_path(base):
class Sitemap(LateTask):
+
"""Generate a sitemap."""
name = "sitemap"
@@ -114,10 +120,12 @@ class Sitemap(LateTask):
"strip_indexes": self.site.config["STRIP_INDEXES"],
"index_file": self.site.config["INDEX_FILE"],
"sitemap_include_fileless_dirs": self.site.config["SITEMAP_INCLUDE_FILELESS_DIRS"],
- "mapped_extensions": self.site.config.get('MAPPED_EXTENSIONS', ['.atom', '.html', '.htm', '.xml', '.rss']),
+ "mapped_extensions": self.site.config.get('MAPPED_EXTENSIONS', ['.atom', '.html', '.htm', '.php', '.xml', '.rss']),
"robots_exclusions": self.site.config["ROBOTS_EXCLUSIONS"],
"filters": self.site.config["FILTERS"],
"translations": self.site.config["TRANSLATIONS"],
+ "tzinfo": self.site.config['__tzinfo__'],
+ "sitemap_plugin_revision": 1,
}
output = kw['output_folder']
@@ -132,6 +140,7 @@ class Sitemap(LateTask):
urlset = {}
def scan_locs():
+ """Scan site locations."""
for root, dirs, files in os.walk(output, followlinks=True):
if not dirs and not files and not kw['sitemap_include_fileless_dirs']:
continue # Totally empty, not on sitemap
@@ -169,17 +178,18 @@ class Sitemap(LateTask):
filehead = fh.read(1024)
fh.close()
- if path.endswith('.html') or path.endswith('.htm'):
+ if path.endswith('.html') or path.endswith('.htm') or path.endswith('.php'):
""" ignores "html" files without doctype """
if b'<!doctype html' not in filehead.lower():
continue
""" ignores "html" files with noindex robot directives """
- robots_directives = [b'<meta content="noindex" name="robots"',
- b'<meta content="none" name="robots"',
- b'<meta name="robots" content="noindex"',
- b'<meta name="robots" content="none"']
- if any([robot_directive in filehead.lower() for robot_directive in robots_directives]):
+ robots_directives = [b'<meta content=noindex name=robots',
+ b'<meta content=none name=robots',
+ b'<meta name=robots content=noindex',
+ b'<meta name=robots content=none']
+ lowquothead = filehead.lower().decode('utf-8', 'ignore').replace('"', '').encode('utf-8')
+ if any([robot_directive in lowquothead for robot_directive in robots_directives]):
continue
# put Atom and RSS in sitemapindex[] instead of in urlset[],
@@ -210,6 +220,7 @@ class Sitemap(LateTask):
urlset[loc] = loc_format.format(loc, lastmod, '\n'.join(alternates))
def robot_fetch(path):
+ """Check if robots can fetch a file."""
for rule in kw["robots_exclusions"]:
robot = robotparser.RobotFileParser()
robot.parse(["User-Agent: *", "Disallow: {0}".format(rule)])
@@ -218,6 +229,7 @@ class Sitemap(LateTask):
return True
def write_sitemap():
+ """Write sitemap to file."""
# Have to rescan, because files may have been added between
# task dep scanning and task execution
with io.open(sitemap_path, 'w+', encoding='utf8') as outf:
@@ -229,16 +241,19 @@ class Sitemap(LateTask):
sitemapindex[sitemap_url] = sitemap_format.format(sitemap_url, self.get_lastmod(sitemap_path))
def write_sitemapindex():
+ """Write sitemap index."""
with io.open(sitemapindex_path, 'w+', encoding='utf8') as outf:
outf.write(sitemapindex_header)
for k in sorted(sitemapindex.keys()):
outf.write(sitemapindex[k])
outf.write(sitemapindex_footer)
- # Yield a task to calculate the dependencies of the sitemap
- # Other tasks can depend on this output, instead of having
- # to scan locations.
def scan_locs_task():
+ """Yield a task to calculate the dependencies of the sitemap.
+
+ Other tasks can depend on this output, instead of having
+ to scan locations.
+ """
scan_locs()
# Generate a list of file dependencies for the actual generation
@@ -290,10 +305,15 @@ class Sitemap(LateTask):
}, kw['filters'])
def get_lastmod(self, p):
+ """Get last modification date."""
if self.site.invariant:
return '2038-01-01'
else:
- return datetime.datetime.fromtimestamp(os.stat(p).st_mtime).isoformat().split('T')[0]
+ # RFC 3339 (web ISO 8601 profile) represented in UTC with Zulu
+ # zone desgignator as recommeded for sitemaps. Second and
+ # microsecond precision is stripped for compatibility.
+ lastmod = datetime.datetime.utcfromtimestamp(os.stat(p).st_mtime).replace(tzinfo=dateutil.tz.gettz('UTC'), second=0, microsecond=0).isoformat().replace('+00:00', 'Z')
+ return lastmod
if __name__ == '__main__':
import doctest
diff --git a/nikola/plugins/task/sources.plugin b/nikola/plugins/task/sources.plugin
index 5560df6..d232c2b 100644
--- a/nikola/plugins/task/sources.plugin
+++ b/nikola/plugins/task/sources.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_sources
-Module = sources
+name = render_sources
+module = sources
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Copy page sources into the output.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Copy page sources into the output.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/sources.py b/nikola/plugins/task/sources.py
index 840a31c..87b4ae7 100644
--- a/nikola/plugins/task/sources.py
+++ b/nikola/plugins/task/sources.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Copy page sources into the output."""
+
import os
from nikola.plugin_categories import Task
@@ -31,20 +33,13 @@ from nikola import utils
class Sources(Task):
+
"""Copy page sources into the output."""
name = "render_sources"
def gen_tasks(self):
- """Publish the page sources into the output.
-
- Required keyword arguments:
-
- translations
- default_lang
- post_pages
- output_folder
- """
+ """Publish the page sources into the output."""
kw = {
"translations": self.site.config["TRANSLATIONS"],
"output_folder": self.site.config["OUTPUT_FOLDER"],
diff --git a/nikola/plugins/task/tags.plugin b/nikola/plugins/task/tags.plugin
index 4ac3800..283a16a 100644
--- a/nikola/plugins/task/tags.plugin
+++ b/nikola/plugins/task/tags.plugin
@@ -1,10 +1,13 @@
[Core]
-Name = render_tags
-Module = tags
+name = render_tags
+module = tags
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Render the tag pages and feeds.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Render the tag pages and feeds.
+
+[Nikola]
+plugincategory = Task
diff --git a/nikola/plugins/task/tags.py b/nikola/plugins/task/tags.py
index 832ceff..3186636 100644
--- a/nikola/plugins/task/tags.py
+++ b/nikola/plugins/task/tags.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""Render the tag/category pages and feeds."""
+
from __future__ import unicode_literals
import json
import os
@@ -39,11 +41,13 @@ from nikola import utils
class RenderTags(Task):
+
"""Render the tag/category pages and feeds."""
name = "render_tags"
def set_site(self, site):
+ """Set Nikola site."""
site.register_path_handler('tag_index', self.tag_index_path)
site.register_path_handler('category_index', self.category_index_path)
site.register_path_handler('tag', self.tag_path)
@@ -56,7 +60,6 @@ class RenderTags(Task):
def gen_tasks(self):
"""Render the tag pages and feeds."""
-
kw = {
"translations": self.site.config["TRANSLATIONS"],
"blog_title": self.site.config["BLOG_TITLE"],
@@ -121,6 +124,7 @@ class RenderTags(Task):
cat_list = list(self.site.posts_per_category.items())
def render_lists(tag, posts, is_category=True):
+ """Render tag pages as RSS files and lists/indexes."""
post_list = sorted(posts, key=lambda a: a.date)
post_list.reverse()
for lang in kw["translations"]:
@@ -161,6 +165,7 @@ class RenderTags(Task):
'assets', 'js', 'tag_cloud_data.json')
def write_tag_data(data):
+ """Write tag data into JSON file, for use in tag clouds."""
utils.makedirs(os.path.dirname(output_name))
with open(output_name, 'w+') as fd:
json.dump(data, fd)
@@ -178,20 +183,20 @@ class RenderTags(Task):
yield utils.apply_filters(task, kw['filters'])
def _create_tags_page(self, kw, include_tags=True, include_categories=True):
- """a global "all your tags/categories" page for each language"""
- tags = natsort.natsorted([tag for tag in self.site.posts_per_tag.keys()
- if len(self.site.posts_per_tag[tag]) >= kw["taglist_minimum_post_count"]],
- alg=natsort.ns.F | natsort.ns.IC)
+ """Create a global "all your tags/categories" page for each language."""
categories = [cat.category_name for cat in self.site.category_hierarchy]
- has_tags = (tags != []) and include_tags
has_categories = (categories != []) and include_categories
template_name = "tags.tmpl"
kw = kw.copy()
- if include_tags:
- kw['tags'] = tags
if include_categories:
kw['categories'] = categories
for lang in kw["translations"]:
+ tags = natsort.natsorted([tag for tag in self.site.tags_per_language[lang]
+ if len(self.site.posts_per_tag[tag]) >= kw["taglist_minimum_post_count"]],
+ alg=natsort.ns.F | natsort.ns.IC)
+ has_tags = (tags != []) and include_tags
+ if include_tags:
+ kw['tags'] = tags
output_name = os.path.join(
kw['output_folder'], self.site.path('tag_index' if has_tags else 'category_index', None, lang))
output_name = output_name
@@ -219,6 +224,7 @@ class RenderTags(Task):
context["cat_items"] = None
context["permalink"] = self.site.link("tag_index" if has_tags else "category_index", None, lang)
context["description"] = context["title"]
+ context["pagekind"] = ["list", "tags_page"]
task = self.site.generic_post_list_renderer(
lang,
[],
@@ -232,7 +238,7 @@ class RenderTags(Task):
yield task
def list_tags_page(self, kw):
- """a global "all your tags/categories" page for each language"""
+ """Create a global "all your tags/categories" page for each language."""
if self.site.config['TAG_PATH'] == self.site.config['CATEGORY_PATH']:
yield self._create_tags_page(kw, True, True)
else:
@@ -254,9 +260,7 @@ class RenderTags(Task):
return [(child.name, self.site.link("category", child.category_name)) for child in node.children]
def tag_page_as_index(self, tag, lang, post_list, kw, is_category):
- """render a sort of index page collection using only this
- tag's posts."""
-
+ """Render a sort of index page collection using only this tag's posts."""
kind = "category" if is_category else "tag"
def page_link(i, displayed_i, num_pages, force_addition, extension=None):
@@ -284,12 +288,13 @@ class RenderTags(Task):
context_source["description"] = self._get_description(tag, is_category, lang)
if is_category:
context_source["subcategories"] = self._get_subcategories(tag)
+ context_source["pagekind"] = ["index", "tag_page"]
template_name = "tagindex.tmpl"
yield self.site.generic_index_renderer(lang, post_list, indexes_title, template_name, context_source, kw, str(self.name), page_link, page_path)
def tag_page_as_list(self, tag, lang, post_list, kw, is_category):
- """We render a single flat link list with this tag's posts"""
+ """Render a single flat link list with this tag's posts."""
kind = "category" if is_category else "tag"
template_name = "tag.tmpl"
output_name = os.path.join(kw['output_folder'], self.site.path(
@@ -308,6 +313,7 @@ class RenderTags(Task):
context["description"] = self._get_description(tag, is_category, lang)
if is_category:
context["subcategories"] = self._get_subcategories(tag)
+ context["pagekind"] = ["list", "tag_page"]
task = self.site.generic_post_list_renderer(
lang,
post_list,
@@ -321,7 +327,7 @@ class RenderTags(Task):
yield task
def tag_rss(self, tag, lang, posts, kw, is_category):
- """RSS for a single tag / language"""
+ """Create a RSS feed for a single tag in a given language."""
kind = "category" if is_category else "tag"
# Render RSS
output_name = os.path.normpath(
@@ -352,21 +358,25 @@ class RenderTags(Task):
return utils.apply_filters(task, kw['filters'])
def slugify_tag_name(self, name):
+ """Slugify a tag name."""
if self.site.config['SLUG_TAG_PATH']:
name = utils.slugify(name)
return name
def tag_index_path(self, name, lang):
+ """Return path to the tag index."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'],
self.site.config['INDEX_FILE']] if _f]
def category_index_path(self, name, lang):
+ """Return path to the category index."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH'],
self.site.config['INDEX_FILE']] if _f]
def tag_path(self, name, lang):
+ """Return path to a tag."""
if self.site.config['PRETTY_URLS']:
return [_f for _f in [
self.site.config['TRANSLATIONS'][lang],
@@ -380,16 +390,19 @@ class RenderTags(Task):
self.slugify_tag_name(name) + ".html"] if _f]
def tag_atom_path(self, name, lang):
+ """Return path to a tag Atom feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'], self.slugify_tag_name(name) + ".atom"] if
_f]
def tag_rss_path(self, name, lang):
+ """Return path to a tag RSS feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['TAG_PATH'], self.slugify_tag_name(name) + ".xml"] if
_f]
def slugify_category_name(self, name):
+ """Slugify a category name."""
path = self.site.parse_category_name(name)
if self.site.config['CATEGORY_OUTPUT_FLAT_HIERARCHY']:
path = path[-1:] # only the leaf
@@ -404,6 +417,7 @@ class RenderTags(Task):
return path
def category_path(self, name, lang):
+ """Return path to a category."""
if self.site.config['PRETTY_URLS']:
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
@@ -414,11 +428,13 @@ class RenderTags(Task):
_f] + self._add_extension(self.slugify_category_name(name), ".html")
def category_atom_path(self, name, lang):
+ """Return path to a category Atom feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
_f] + self._add_extension(self.slugify_category_name(name), ".atom")
def category_rss_path(self, name, lang):
+ """Return path to a category RSS feed."""
return [_f for _f in [self.site.config['TRANSLATIONS'][lang],
self.site.config['CATEGORY_PATH']] if
_f] + self._add_extension(self.slugify_category_name(name), ".xml")
diff --git a/nikola/plugins/template/__init__.py b/nikola/plugins/template/__init__.py
index a1d17a6..d416ad7 100644
--- a/nikola/plugins/template/__init__.py
+++ b/nikola/plugins/template/__init__.py
@@ -23,3 +23,5 @@
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+"""Default template engines for Nikola."""
diff --git a/nikola/plugins/template/jinja.plugin b/nikola/plugins/template/jinja.plugin
index 0bdcb94..cfe9fa8 100644
--- a/nikola/plugins/template/jinja.plugin
+++ b/nikola/plugins/template/jinja.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = jinja
-Module = jinja
+name = jinja
+module = jinja
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Support for Jinja2 templates.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Support for Jinja2 templates.
+
+[Nikola]
+plugincategory = Template
+
diff --git a/nikola/plugins/template/jinja.py b/nikola/plugins/template/jinja.py
index 82e8397..b02d75c 100644
--- a/nikola/plugins/template/jinja.py
+++ b/nikola/plugins/template/jinja.py
@@ -24,8 +24,10 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Jinja template handlers"""
+"""Jinja template handler."""
+
+from __future__ import unicode_literals
import os
import json
from collections import deque
@@ -40,14 +42,15 @@ from nikola.utils import makedirs, req_missing
class JinjaTemplates(TemplateSystem):
- """Wrapper for Jinja2 templates."""
+
+ """Support for Jinja2 templates."""
name = "jinja"
lookup = None
dependency_cache = {}
def __init__(self):
- """ initialize Jinja2 wrapper with extended set of filters"""
+ """Initialize Jinja2 environment with extended set of filters."""
if jinja2 is None:
return
self.lookup = jinja2.Environment()
@@ -59,26 +62,25 @@ class JinjaTemplates(TemplateSystem):
self.lookup.globals['tuple'] = tuple
def set_directories(self, directories, cache_folder):
- """Create a template lookup."""
+ """Create a new template lookup with set directories."""
if jinja2 is None:
req_missing(['jinja2'], 'use this theme')
self.directories = directories
self.create_lookup()
def inject_directory(self, directory):
- """if it's not there, add the directory to the lookup with lowest priority, and
- recreate the lookup."""
+ """Add a directory to the lookup and recreate it if it's not there yet."""
if directory not in self.directories:
self.directories.append(directory)
self.create_lookup()
def create_lookup(self):
- """Create a template lookup object."""
+ """Create a template lookup."""
self.lookup.loader = jinja2.FileSystemLoader(self.directories,
encoding='utf-8')
def set_site(self, site):
- """Sets the site."""
+ """Set the Nikola site."""
self.site = site
self.lookup.filters.update(self.site.config['TEMPLATE_FILTERS'])
@@ -99,6 +101,7 @@ class JinjaTemplates(TemplateSystem):
return self.lookup.from_string(template).render(**context)
def template_deps(self, template_name):
+ """Generate list of dependencies for a template."""
# Cache the lists of dependencies for each template name.
if self.dependency_cache.get(template_name) is None:
# Use a breadth-first search to find all templates this one
diff --git a/nikola/plugins/template/mako.plugin b/nikola/plugins/template/mako.plugin
index 2fe6d98..d256faf 100644
--- a/nikola/plugins/template/mako.plugin
+++ b/nikola/plugins/template/mako.plugin
@@ -1,9 +1,13 @@
[Core]
-Name = mako
-Module = mako
+name = mako
+module = mako
[Documentation]
-Author = Roberto Alsina
-Version = 1.0
-Website = http://getnikola.com
-Description = Support for Mako templates.
+author = Roberto Alsina
+version = 1.0
+website = http://getnikola.com
+description = Support for Mako templates.
+
+[Nikola]
+plugincategory = Template
+
diff --git a/nikola/plugins/template/mako.py b/nikola/plugins/template/mako.py
index e5545f6..aed6596 100644
--- a/nikola/plugins/template/mako.py
+++ b/nikola/plugins/template/mako.py
@@ -24,14 +24,15 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""Mako template handlers"""
+"""Mako template handler."""
+
from __future__ import unicode_literals, print_function, absolute_import
import os
import shutil
import sys
import tempfile
-from mako import util, lexer
+from mako import util, lexer, parsetree
from mako.lookup import TemplateLookup
from mako.template import Template
from markupsafe import Markup # It's ok, Mako requires it
@@ -43,7 +44,8 @@ LOGGER = get_logger('mako', STDERR_HANDLER)
class MakoTemplates(TemplateSystem):
- """Wrapper for Mako templates."""
+
+ """Support for Mako templates."""
name = "mako"
@@ -54,6 +56,7 @@ class MakoTemplates(TemplateSystem):
cache_dir = None
def get_deps(self, filename):
+ """Get dependencies for a template (internal function)."""
text = util.read_file(filename)
lex = lexer.Lexer(text=text, filename=filename)
lex.parse()
@@ -61,13 +64,12 @@ class MakoTemplates(TemplateSystem):
deps = []
for n in lex.template.nodes:
keyword = getattr(n, 'keyword', None)
- if keyword in ["inherit", "namespace"]:
+ if keyword in ["inherit", "namespace"] or isinstance(n, parsetree.IncludeTag):
deps.append(n.attributes['file'])
- # TODO: include tags are not handled
return deps
def set_directories(self, directories, cache_folder):
- """Set directories and create a template lookup."""
+ """Create a new template lookup with set directories."""
cache_dir = os.path.join(cache_folder, '.mako.tmp')
# Workaround for a Mako bug, Issue #825
if sys.version_info[0] == 2:
@@ -83,21 +85,20 @@ class MakoTemplates(TemplateSystem):
self.create_lookup()
def inject_directory(self, directory):
- """if it's not there, add the directory to the lookup with lowest priority, and
- recreate the lookup."""
+ """Add a directory to the lookup and recreate it if it's not there yet."""
if directory not in self.directories:
self.directories.append(directory)
self.create_lookup()
def create_lookup(self):
- """Create a template lookup object."""
+ """Create a template lookup."""
self.lookup = TemplateLookup(
directories=self.directories,
module_directory=self.cache_dir,
output_encoding='utf-8')
def set_site(self, site):
- """Sets the site."""
+ """Set the Nikola site."""
self.site = site
self.filters.update(self.site.config['TEMPLATE_FILTERS'])
@@ -113,14 +114,12 @@ class MakoTemplates(TemplateSystem):
return data
def render_template_to_string(self, template, context):
- """ Render template to a string using context. """
-
+ """Render template to a string using context."""
context.update(self.filters)
-
return Template(template).render(**context)
def template_deps(self, template_name):
- """Returns filenames which are dependencies for a template."""
+ """Generate list of dependencies for a template."""
# We can cache here because dependencies should
# not change between runs
if self.cache.get(template_name, None) is None:
@@ -134,4 +133,5 @@ class MakoTemplates(TemplateSystem):
def striphtml(text):
+ """Strip HTML tags from text."""
return Markup(text).striptags()
diff --git a/nikola/post.py b/nikola/post.py
index 466d5e0..7badfc6 100644
--- a/nikola/post.py
+++ b/nikola/post.py
@@ -24,6 +24,8 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"""The Post class."""
+
from __future__ import unicode_literals, print_function, absolute_import
import io
@@ -68,7 +70,7 @@ from .utils import (
)
from .rc4 import rc4
-__all__ = ['Post']
+__all__ = ('Post',)
TEASER_REGEXP = re.compile('<!--\s*TEASER_END(:(.+))?\s*-->', re.IGNORECASE)
_UPGRADE_METADATA_ADVERTISED = False
@@ -76,7 +78,7 @@ _UPGRADE_METADATA_ADVERTISED = False
class Post(object):
- """Represents a blog post or web page."""
+ """Represent a blog post or site page."""
def __init__(
self,
@@ -102,7 +104,7 @@ class Post(object):
if self.config['FUTURE_IS_NOW']:
self.current_time = None
else:
- self.current_time = current_time()
+ self.current_time = current_time(tzinfo)
self.translated_to = set([])
self._prev_post = None
self._next_post = None
@@ -231,6 +233,7 @@ class Post(object):
self.compiler.register_extra_dependencies(self)
def __repr__(self):
+ """Provide a representation of the post object."""
# Calculate a hash that represents most data about the post
m = hashlib.md5()
# source_path modification date (to avoid reading it)
@@ -255,24 +258,32 @@ class Post(object):
@property
def alltags(self):
- """This is ALL the tags for this post."""
+ """Return ALL the tags for this post."""
tags = []
for l in self._tags:
tags.extend(self._tags[l])
return list(set(tags))
- @property
- def tags(self):
- lang = nikola.utils.LocaleBorg().current_lang
+ def tags_for_language(self, lang):
+ """Return tags for a given language."""
if lang in self._tags:
return self._tags[lang]
+ elif lang not in self.translated_to and self.skip_untranslated:
+ return []
elif self.default_lang in self._tags:
return self._tags[self.default_lang]
else:
return []
@property
+ def tags(self):
+ """Return tags for the current language."""
+ lang = nikola.utils.LocaleBorg().current_lang
+ return self.tags_for_language(lang)
+
+ @property
def prev_post(self):
+ """Return previous post."""
lang = nikola.utils.LocaleBorg().current_lang
rv = self._prev_post
while self.skip_untranslated:
@@ -285,10 +296,12 @@ class Post(object):
@prev_post.setter # NOQA
def prev_post(self, v):
+ """Set previous post."""
self._prev_post = v
@property
def next_post(self):
+ """Return next post."""
lang = nikola.utils.LocaleBorg().current_lang
rv = self._next_post
while self.skip_untranslated:
@@ -301,24 +314,32 @@ class Post(object):
@next_post.setter # NOQA
def next_post(self, v):
+ """Set next post."""
self._next_post = v
@property
def template_name(self):
+ """Return template name for this post."""
return self.meta('template') or self._template_name
def formatted_date(self, date_format, date=None):
- """Return the formatted date, as unicode."""
- if date:
- fmt_date = date.strftime(date_format)
+ """Return the formatted date as unicode."""
+ date = date if date else self.date
+
+ if date_format == 'webiso':
+ # Formatted after RFC 3339 (web ISO 8501 profile) with Zulu
+ # zone desgignator for times in UTC and no microsecond precision.
+ fmt_date = date.replace(microsecond=0).isoformat().replace('+00:00', 'Z')
else:
- fmt_date = self.date.strftime(date_format)
+ fmt_date = date.strftime(date_format)
+
# Issue #383, this changes from py2 to py3
if isinstance(fmt_date, bytes_str):
fmt_date = fmt_date.decode('utf8')
return fmt_date
def formatted_updated(self, date_format):
+ """Return the updated date as unicode."""
return self.formatted_date(date_format, self.updated)
def title(self, lang=None):
@@ -353,7 +374,7 @@ class Post(object):
return self.meta[lang]['description']
def add_dependency(self, dependency, add='both', lang=None):
- """Adds a file dependency for tasks using that post.
+ """Add a file dependency for tasks using that post.
The ``dependency`` should be a string specifying a path, or a callable
which returns such a string or a list of strings.
@@ -365,7 +386,8 @@ class Post(object):
includes the HTML resulting from compiling the fragment ('page' or
'both').
- If ``lang`` is not specified, this dependency is added for all languages."""
+ If ``lang`` is not specified, this dependency is added for all languages.
+ """
if add not in {'fragment', 'page', 'both'}:
raise Exception("Add parameter is '{0}', but must be either 'fragment', 'page', or 'both'.".format(add))
if add == 'fragment' or add == 'both':
@@ -374,7 +396,7 @@ class Post(object):
self._dependency_file_page[lang].append((type(dependency) != str, dependency))
def add_dependency_uptodate(self, dependency, is_callable=False, add='both', lang=None):
- """Adds a dependency for task's ``uptodate`` for tasks using that post.
+ """Add a dependency for task's ``uptodate`` for tasks using that post.
This can be for example an ``utils.config_changed`` object, or a list of
such objects.
@@ -397,7 +419,6 @@ class Post(object):
post.add_dependency_uptodate(
utils.config_changed({1: some_data}, 'uniqueid'), False, 'page')
-
"""
if add == 'fragment' or add == 'both':
self._dependency_uptodate_fragment[lang].append((is_callable, dependency))
@@ -433,13 +454,14 @@ class Post(object):
deps.extend([cand_1, cand_2])
deps += self._get_dependencies(self._dependency_file_page[lang])
deps += self._get_dependencies(self._dependency_file_page[None])
- return deps
+ return sorted(deps)
def deps_uptodate(self, lang):
"""Return a list of uptodate dependencies to build this post's page.
These dependencies should be included in ``uptodate`` for the task
- which generates the page."""
+ which generates the page.
+ """
deps = []
deps += self._get_dependencies(self._dependency_uptodate_page[lang])
deps += self._get_dependencies(self._dependency_uptodate_page[None])
@@ -448,7 +470,6 @@ class Post(object):
def compile(self, lang):
"""Generate the cache/ file with the compiled post."""
-
def wrap_encrypt(path, password):
"""Wrap a post with encryption."""
with io.open(path, 'r+', encoding='utf8') as inf:
@@ -480,7 +501,8 @@ class Post(object):
"""Return a list of uptodate dependencies to build this post's fragment.
These dependencies should be included in ``uptodate`` for the task
- which generates the fragment."""
+ which generates the fragment.
+ """
deps = []
if self.default_lang in self.translated_to:
deps.append(self.source_path)
@@ -493,7 +515,7 @@ class Post(object):
deps = [d for d in deps if os.path.exists(d)]
deps += self._get_dependencies(self._dependency_file_fragment[lang])
deps += self._get_dependencies(self._dependency_file_fragment[None])
- return deps
+ return sorted(deps)
def fragment_deps_uptodate(self, lang):
"""Return a list of file dependencies to build this post's fragment."""
@@ -504,7 +526,7 @@ class Post(object):
return deps
def is_translation_available(self, lang):
- """Return true if the translation actually exists."""
+ """Return True if the translation actually exists."""
return lang in self.translated_to
def translated_source_path(self, lang):
@@ -548,7 +570,6 @@ class Post(object):
All links in the returned HTML will be relative.
The HTML returned is a bare fragment, not a full document.
"""
-
if lang is None:
lang = nikola.utils.LocaleBorg().current_lang
file_name = self._translated_file_path(lang)
@@ -584,23 +605,23 @@ class Post(object):
data = lxml.html.tostring(document, encoding='unicode')
if teaser_only:
- teaser = TEASER_REGEXP.split(data)[0]
+ teaser_regexp = self.config.get('TEASER_REGEXP', TEASER_REGEXP)
+ teaser = teaser_regexp.split(data)[0]
if teaser != data:
if not strip_html and show_read_more_link:
- if TEASER_REGEXP.search(data).groups()[-1]:
- teaser += '<p class="more"><a href="{0}">{1}</a></p>'.format(
- self.permalink(lang),
- TEASER_REGEXP.search(data).groups()[-1])
+ if teaser_regexp.search(data).groups()[-1]:
+ teaser_text = teaser_regexp.search(data).groups()[-1]
else:
- l = self.config['RSS_READ_MORE_LINK'](lang) if rss_read_more_link else self.config['INDEX_READ_MORE_LINK'](lang)
- teaser += l.format(
- link=self.permalink(lang, query=rss_links_append_query),
- read_more=self.messages[lang]["Read more"],
- min_remaining_read=self.messages[lang]["%d min remaining to read"] % (self.remaining_reading_time),
- reading_time=self.reading_time,
- remaining_reading_time=self.remaining_reading_time,
- paragraph_count=self.paragraph_count,
- remaining_paragraph_count=self.remaining_paragraph_count)
+ teaser_text = self.messages[lang]["Read more"]
+ l = self.config['RSS_READ_MORE_LINK'](lang) if rss_read_more_link else self.config['INDEX_READ_MORE_LINK'](lang)
+ teaser += l.format(
+ link=self.permalink(lang, query=rss_links_append_query),
+ read_more=teaser_text,
+ min_remaining_read=self.messages[lang]["%d min remaining to read"] % (self.remaining_reading_time),
+ reading_time=self.reading_time,
+ remaining_reading_time=self.remaining_reading_time,
+ paragraph_count=self.paragraph_count,
+ remaining_paragraph_count=self.remaining_paragraph_count)
# This closes all open tags and sanitizes the broken HTML
document = lxml.html.fromstring(teaser)
try:
@@ -720,6 +741,7 @@ class Post(object):
return path
def permalink(self, lang=None, absolute=False, extension='.html', query=None):
+ """Return permalink for a post."""
if lang is None:
lang = nikola.utils.LocaleBorg().current_lang
@@ -746,6 +768,7 @@ class Post(object):
@property
def previewimage(self, lang=None):
+ """Return the previewimage path."""
if lang is None:
lang = nikola.utils.LocaleBorg().current_lang
@@ -759,13 +782,11 @@ class Post(object):
return image_path
def source_ext(self, prefix=False):
- """
- Return the source file extension.
+ """Return the source file extension.
If `prefix` is True, a `.src.` prefix will be added to the resulting extension
- if it’s equal to the destination extension.
+ if it's equal to the destination extension.
"""
-
ext = os.path.splitext(self.source_path)[1]
# do not publish PHP sources
if prefix and ext == '.html':
@@ -778,7 +799,7 @@ class Post(object):
def re_meta(line, match=None):
- """re.compile for meta"""
+ """Find metadata using regular expressions."""
if match:
reStr = re.compile('^\.\. {0}: (.*)'.format(re.escape(match)))
else:
@@ -793,10 +814,9 @@ def re_meta(line, match=None):
def _get_metadata_from_filename_by_regex(filename, metadata_regexp, unslugify_titles):
- """
- Tries to ried the metadata from the filename based on the given re.
- This requires to use symbolic group names in the pattern.
+ """Try to reed the metadata from the filename based on the given re.
+ This requires to use symbolic group names in the pattern.
The part to read the metadata from the filename based on a regular
expression is taken from Pelican - pelican/readers.py
"""
@@ -816,7 +836,7 @@ def _get_metadata_from_filename_by_regex(filename, metadata_regexp, unslugify_ti
def get_metadata_from_file(source_path, config=None, lang=None):
- """Extracts metadata from the file itself, by parsing contents."""
+ """Extract metadata from the file itself, by parsing contents."""
try:
if lang and config:
source_path = get_translation_candidate(config, source_path, lang)
@@ -832,26 +852,10 @@ def get_metadata_from_file(source_path, config=None, lang=None):
def _get_metadata_from_file(meta_data):
- """Parse file contents and obtain metadata.
-
- >>> g = _get_metadata_from_file
- >>> list(g([]).values())
- []
- >>> str(g(["======","FooBar","======"])["title"])
- 'FooBar'
- >>> str(g(["FooBar","======"])["title"])
- 'FooBar'
- >>> str(g(["#FooBar"])["title"])
- 'FooBar'
- >>> str(g([".. title: FooBar"])["title"])
- 'FooBar'
- >>> 'title' in g(["","",".. title: FooBar"])
- False
- >>> 'title' in g(["",".. title: FooBar"]) # for #520
- True
-
- """
+ """Extract metadata from a post's source file."""
meta = {}
+ if not meta_data:
+ return meta
re_md_title = re.compile(r'^{0}([^{0}].*)'.format(re.escape('#')))
# Assuming rst titles are going to be at least 4 chars long
@@ -859,37 +863,40 @@ def _get_metadata_from_file(meta_data):
re_rst_title = re.compile(r'^([{0}]{{4,}})'.format(re.escape(
string.punctuation)))
+ # Skip up to one empty line at the beginning (for txt2tags)
+ if not meta_data[0]:
+ meta_data = meta_data[1:]
+
+ # First, get metadata from the beginning of the file,
+ # up to first empty line
+
for i, line in enumerate(meta_data):
- # txt2tags requires an empty line at the beginning
- # and since we are here because it's a 1-file post
- # let's be flexible on what we accept, so, skip empty
- # first lines.
- if not line and i > 0:
+ if not line:
break
- if 'title' not in meta:
- match = re_meta(line, 'title')
- if match[0]:
- meta['title'] = match[1]
- if 'title' not in meta:
+ match = re_meta(line)
+ if match[0]:
+ meta[match[0]] = match[1]
+
+ # If we have no title, try to get it from document
+ if 'title' not in meta:
+ piece = meta_data[:]
+ for i, line in enumerate(piece):
if re_rst_title.findall(line) and i > 0:
meta['title'] = meta_data[i - 1].strip()
- if 'title' not in meta:
+ break
if (re_rst_title.findall(line) and i >= 0 and
re_rst_title.findall(meta_data[i + 2])):
meta['title'] = meta_data[i + 1].strip()
- if 'title' not in meta:
+ break
if re_md_title.findall(line):
meta['title'] = re_md_title.findall(line)[0]
-
- match = re_meta(line)
- if match[0]:
- meta[match[0]] = match[1]
+ break
return meta
def get_metadata_from_meta_file(path, config=None, lang=None):
- """Takes a post path, and gets data from a matching .meta file."""
+ """Take a post path, and gets data from a matching .meta file."""
global _UPGRADE_METADATA_ADVERTISED
meta_path = os.path.splitext(path)[0] + '.meta'
if lang and config:
@@ -977,12 +984,15 @@ def get_meta(post, file_metadata_regexp=None, unslugify_titles=False, lang=None)
file_metadata_regexp,
unslugify_titles))
+ compiler_meta = {}
+
if getattr(post, 'compiler', None):
compiler_meta = post.compiler.read_metadata(post, file_metadata_regexp, unslugify_titles, lang)
meta.update(compiler_meta)
- if not post.is_two_file:
+ if not post.is_two_file and not compiler_meta:
# Meta file has precedence over file, which can contain garbage.
+ # Moreover, we should not to talk to the file if we have compiler meta.
meta.update(get_metadata_from_file(post.source_path, config, lang))
if lang is None:
@@ -1002,6 +1012,7 @@ def get_meta(post, file_metadata_regexp=None, unslugify_titles=False, lang=None)
def hyphenate(dom, _lang):
+ """Hyphenate a post."""
# circular import prevention
from .nikola import LEGAL_VALUES
lang = LEGAL_VALUES['PYPHEN_LOCALES'].get(_lang, pyphen.language_fallback(_lang))
@@ -1029,6 +1040,7 @@ def hyphenate(dom, _lang):
def insert_hyphens(node, hyphenator):
+ """Insert hyphens into a node."""
textattrs = ('text', 'tail')
if isinstance(node, lxml.etree._Entity):
# HTML entities have no .text
diff --git a/nikola/rc4.py b/nikola/rc4.py
index b46d602..93b660f 100644
--- a/nikola/rc4.py
+++ b/nikola/rc4.py
@@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
"""
- A RC4 encryption library (used for password-protected posts)
- ---
+A RC4 encryption library (used for password-protected posts).
+
+Original RC4 code license:
+
Copyright (C) 2012 Bo Zhu http://about.bozhu.me
Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,6 +30,7 @@ import sys
def KSA(key):
+ """Run Key Scheduling Algorithm."""
keylength = len(key)
S = list(range(256))
@@ -41,6 +44,7 @@ def KSA(key):
def PRGA(S):
+ """Run Pseudo-Random Generation Algorithm."""
i = 0
j = 0
while True:
@@ -53,16 +57,17 @@ def PRGA(S):
def RC4(key):
+ """Generate RC4 keystream."""
S = KSA(key)
return PRGA(S)
def rc4(key, string):
"""Encrypt things.
+
>>> print(rc4("Key", "Plaintext"))
u/MW6NlArwrT
"""
-
string.encode('utf8')
key.encode('utf8')
diff --git a/nikola/utils.py b/nikola/utils.py
index 3708775..3a268ff 100644
--- a/nikola/utils.py
+++ b/nikola/utils.py
@@ -47,6 +47,7 @@ import logbook
import warnings
import PyRSS2Gen as rss
from collections import defaultdict, Callable
+from logbook.compat import redirect_logging
from logbook.more import ExceptionHandler, ColorizedStderrHandler
from pygments.formatters import HtmlFormatter
from zipfile import ZipFile as zipf
@@ -57,7 +58,7 @@ from doit.cmdparse import CmdParse
from nikola import DEBUG
-__all__ = ['CustomEncoder', 'get_theme_path', 'get_theme_chain', 'load_messages', 'copy_tree',
+__all__ = ('CustomEncoder', 'get_theme_path', 'get_theme_chain', 'load_messages', 'copy_tree',
'copy_file', 'slugify', 'unslugify', 'to_datetime', 'apply_filters',
'config_changed', 'get_crumbs', 'get_tzname', 'get_asset_path',
'_reload', 'unicode_str', 'bytes_str', 'unichr', 'Functionary',
@@ -69,7 +70,7 @@ __all__ = ['CustomEncoder', 'get_theme_path', 'get_theme_chain', 'load_messages'
'adjust_name_for_index_path', 'adjust_name_for_index_link',
'NikolaPygmentsHTML', 'create_redirect', 'TreeNode',
'flatten_tree_structure', 'parse_escaped_hierarchical_category_name',
- 'join_hierarchical_category_path', 'indent']
+ 'join_hierarchical_category_path', 'indent')
# Are you looking for 'generic_rss_renderer'?
# It's defined in nikola.nikola.Nikola (the site object).
@@ -93,7 +94,9 @@ class ApplicationWarning(Exception):
class ColorfulStderrHandler(ColorizedStderrHandler):
+
"""Stream handler with colors."""
+
_colorful = False
def should_colorize(self, record):
@@ -116,14 +119,14 @@ STDERR_HANDLER = [ColorfulStderrHandler(
level=logbook.INFO if not DEBUG else logbook.DEBUG,
format_string=u'[{record.time:%Y-%m-%dT%H:%M:%SZ}] {record.level_name}: {record.channel}: {record.message}'
)]
+
+
LOGGER = get_logger('Nikola', STDERR_HANDLER)
STRICT_HANDLER = ExceptionHandler(ApplicationWarning, level='WARNING')
USE_SLUGIFY = True
-# This will block out the default handler and will hide all unwanted
-# messages, properly.
-logbook.NullHandler().push_application()
+redirect_logging()
if DEBUG:
logging.basicConfig(level=logging.DEBUG)
@@ -132,7 +135,7 @@ else:
def showwarning(message, category, filename, lineno, file=None, line=None):
- """Show a warning (from the warnings subsystem) to the user."""
+ """Show a warning (from the warnings module) to the user."""
try:
n = category.__name__
except AttributeError:
@@ -200,14 +203,14 @@ def sys_encode(thing):
def sys_decode(thing):
- """Returns unicode."""
+ """Return Unicode."""
if isinstance(thing, bytes_str):
return thing.decode(ENCODING)
return thing
def makedirs(path):
- """Create a folder."""
+ """Create a folder and its parents if needed (mkdir -p)."""
if not path:
return
if os.path.exists(path):
@@ -229,13 +232,12 @@ class Functionary(defaultdict):
"""Class that looks like a function, but is a defaultdict."""
def __init__(self, default, default_lang):
+ """Initialize a functionary."""
super(Functionary, self).__init__(default)
self.default_lang = default_lang
def __call__(self, key, lang=None):
- """When called as a function, take an optional lang
- and return self[lang][key]."""
-
+ """When called as a function, take an optional lang and return self[lang][key]."""
if lang is None:
lang = LocaleBorg().current_lang
return self[lang][key]
@@ -243,8 +245,7 @@ class Functionary(defaultdict):
class TranslatableSetting(object):
- """
- A setting that can be translated.
+ """A setting that can be translated.
You can access it via: SETTING(lang). You can omit lang, in which
case Nikola will ask LocaleBorg, unless you set SETTING.lang,
@@ -258,7 +259,6 @@ class TranslatableSetting(object):
The underlying structure is a defaultdict. The language that
is the default value of the dict is provided with __init__().
- If you need access the underlying dict (you generally don’t,
"""
# WARNING: This is generally not used and replaced with a call to
@@ -276,6 +276,7 @@ class TranslatableSetting(object):
return self().__getattribute__(attr)
def __dir__(self):
+ """Return the available methods of TranslatableSettings and strings."""
return list(set(self.__dict__).union(set(dir(str))))
def __init__(self, name, inp, translations):
@@ -286,7 +287,6 @@ class TranslatableSetting(object):
* a string -- the same will be used for all languages
* a dict ({lang: value}) -- each language will use the value specified;
if there is none, default_lang is used.
-
"""
self.name = name
self._inp = inp
@@ -322,8 +322,7 @@ class TranslatableSetting(object):
return self.default_lang
def __call__(self, lang=None):
- """
- Return the value in the requested language.
+ """Return the value in the requested language.
While lang is None, self.lang (currently set language) is used.
Otherwise, the standard algorithm is used (see above).
@@ -335,11 +334,11 @@ class TranslatableSetting(object):
return self.values[lang]
def __str__(self):
- """Return the value in the currently set language. (deprecated)"""
+ """Return the value in the currently set language (deprecated)."""
return self.values[self.get_lang()]
def __unicode__(self):
- """Return the value in the currently set language. (deprecated)"""
+ """Return the value in the currently set language (deprecated)."""
return self.values[self.get_lang()]
def __repr__(self):
@@ -433,8 +432,7 @@ class TranslatableSetting(object):
class TemplateHookRegistry(object):
- """
- A registry for template hooks.
+ r"""A registry for template hooks.
Usage:
@@ -442,7 +440,7 @@ class TemplateHookRegistry(object):
>>> r.append('Hello!')
>>> r.append(lambda x: 'Hello ' + x + '!', False, 'world')
>>> str(r()) # str() call is not recommended in real use
- 'Hello!\\nHello world!'
+ 'Hello!\nHello world!'
>>>
"""
@@ -486,31 +484,47 @@ class TemplateHookRegistry(object):
self._items.append((c, inp, wants_site_and_context, args, kwargs))
def __hash__(self):
+ """Return hash of a registry."""
return hash(config_changed({self.name: self._items})._calc_digest())
def __str__(self):
+ """Stringify a registry."""
return '<TemplateHookRegistry: {0}>'.format(self._items)
+ def __repr__(self):
+ """Provide the representation of a registry."""
+ return '<TemplateHookRegistry: {0}>'.format(self.name)
+
class CustomEncoder(json.JSONEncoder):
+
+ """Custom JSON encoder."""
+
def default(self, obj):
+ """Default encoding handler."""
try:
return super(CustomEncoder, self).default(obj)
except TypeError:
- s = repr(obj).split('0x', 1)[0]
+ if isinstance(obj, (set, frozenset)):
+ return self.encode(sorted(list(obj)))
+ else:
+ s = repr(obj).split('0x', 1)[0]
return s
class config_changed(tools.config_changed):
- """ A copy of doit's but using pickle instead of serializing manually."""
+
+ """A copy of doit's config_changed, using pickle instead of serializing manually."""
def __init__(self, config, identifier=None):
+ """Initialize config_changed."""
super(config_changed, self).__init__(config)
self.identifier = '_config_changed'
if identifier is not None:
self.identifier += ':' + identifier
def _calc_digest(self):
+ """Calculate a config_changed digest."""
if isinstance(self.config, str):
return self.config
elif isinstance(self.config, dict):
@@ -528,6 +542,7 @@ class config_changed(tools.config_changed):
self.config)))
def configure_task(self, task):
+ """Configure a task with a digest."""
task.value_savers.append(lambda: {self.identifier: self._calc_digest()})
def __call__(self, task, values):
@@ -538,12 +553,14 @@ class config_changed(tools.config_changed):
return (last_success == self._calc_digest())
def __repr__(self):
+ """Provide a representation of config_changed."""
return "Change with config: {0}".format(json.dumps(self.config,
- cls=CustomEncoder))
+ cls=CustomEncoder,
+ sort_keys=True))
def get_theme_path(theme, _themes_dir='themes'):
- """Given a theme name, returns the path where its files are located.
+ """Return the path where the given theme's files are located.
Looks in ./themes and in the place where themes go when installed.
"""
@@ -557,6 +574,7 @@ def get_theme_path(theme, _themes_dir='themes'):
def get_template_engine(themes, _themes_dir='themes'):
+ """Get template engine used by a given theme."""
for theme_name in themes:
engine_path = os.path.join(get_theme_path(theme_name, _themes_dir), 'engine')
if os.path.isfile(engine_path):
@@ -567,6 +585,7 @@ def get_template_engine(themes, _themes_dir='themes'):
def get_parent_theme_name(theme_name, _themes_dir='themes'):
+ """Get name of parent theme."""
parent_path = os.path.join(get_theme_path(theme_name, _themes_dir), 'parent')
if os.path.isfile(parent_path):
with open(parent_path) as fd:
@@ -587,20 +606,25 @@ def get_theme_chain(theme, _themes_dir='themes'):
return themes
-warned = []
+language_incomplete_warned = []
class LanguageNotFoundError(Exception):
+
+ """An exception thrown if language is not found."""
+
def __init__(self, lang, orig):
+ """Initialize exception."""
self.lang = lang
self.orig = orig
def __str__(self):
+ """Stringify the exception."""
return 'cannot find language {0}'.format(self.lang)
def load_messages(themes, translations, default_lang):
- """ Load theme's messages into context.
+ """Load theme's messages into context.
All the messages from parent themes are loaded,
and "younger" themes have priority.
@@ -620,8 +644,8 @@ def load_messages(themes, translations, default_lang):
_reload(translation)
if sorted(translation.MESSAGES.keys()) !=\
sorted(english.MESSAGES.keys()) and \
- lang not in warned:
- warned.append(lang)
+ lang not in language_incomplete_warned:
+ language_incomplete_warned.append(lang)
LOGGER.warn("Incomplete translation for language "
"'{0}'.".format(lang))
messages[lang].update(english.MESSAGES)
@@ -673,6 +697,7 @@ def copy_tree(src, dst, link_cutoff=None):
def copy_file(source, dest, cutoff=None):
+ """Copy a file from source to dest. If link target starts with `cutoff`, symlinks are used."""
dst_dir = os.path.dirname(dest)
makedirs(dst_dir)
if os.path.islink(source):
@@ -693,6 +718,7 @@ def copy_file(source, dest, cutoff=None):
def remove_file(source):
+ """Remove file or directory."""
if os.path.isdir(source):
shutil.rmtree(source)
elif os.path.isfile(source) or os.path.islink(source):
@@ -706,13 +732,11 @@ _slugify_hyphenate_re = re.compile(r'[-\s]+')
def slugify(value, force=False):
- """
- Normalizes string, converts to lowercase, removes non-alpha characters,
- and converts spaces to hyphens.
+ u"""Normalize string, convert to lowercase, remove non-alpha characters, convert spaces to hyphens.
From Django's "django/template/defaultfilters.py".
- >>> print(slugify('\xe1\xe9\xed.\xf3\xfa'))
+ >>> print(slugify('áéí.óú'))
aeiou
>>> print(slugify('foo/bar'))
@@ -720,16 +744,15 @@ def slugify(value, force=False):
>>> print(slugify('foo bar'))
foo-bar
-
"""
if not isinstance(value, unicode_str):
raise ValueError("Not a unicode object: {0}".format(value))
if USE_SLUGIFY or force:
# This is the standard state of slugify, which actually does some work.
# It is the preferred style, especially for Western languages.
- value = unidecode(value)
- value = str(_slugify_strip_re.sub('', value).strip().lower())
- return _slugify_hyphenate_re.sub('-', value)
+ value = unicode_str(unidecode(value))
+ value = _slugify_strip_re.sub('', value, re.UNICODE).strip().lower()
+ return _slugify_hyphenate_re.sub('-', value, re.UNICODE)
else:
# This is the “disarmed” state of slugify, which lets the user
# have any character they please (be it regular ASCII with spaces,
@@ -739,7 +762,7 @@ def slugify(value, force=False):
# We still replace some characters, though. In particular, we need
# to replace ? and #, which should not appear in URLs, and some
# Windows-unsafe characters. This list might be even longer.
- rc = '/\\?#"\'\r\n\t*:<>|"'
+ rc = '/\\?#"\'\r\n\t*:<>|'
for c in rc:
value = value.replace(c, '-')
@@ -763,10 +786,14 @@ def unslugify(value, discard_numbers=True):
# python < 2.6
class UnsafeZipException(Exception):
+
+ """Exception for unsafe zip files."""
+
pass
def extract_all(zipfile, path='themes'):
+ """Extract all files from a zip file."""
pwd = os.getcwd()
makedirs(path)
os.chdir(path)
@@ -786,6 +813,7 @@ def extract_all(zipfile, path='themes'):
def to_datetime(value, tzinfo=None):
+ """Convert string to datetime."""
try:
if not isinstance(value, datetime.datetime):
# dateutil does bad things with TZs like UTC-03:00.
@@ -800,8 +828,7 @@ def to_datetime(value, tzinfo=None):
def get_tzname(dt):
- """
- Given a datetime value, find the name of the time zone.
+ """Given a datetime value, find the name of the time zone.
DEPRECATED: This thing returned basically the 1st random zone
that matched the offset.
@@ -810,6 +837,7 @@ def get_tzname(dt):
def current_time(tzinfo=None):
+ """Get current time."""
if tzinfo is not None:
dt = datetime.datetime.now(tzinfo)
else:
@@ -818,13 +846,12 @@ def current_time(tzinfo=None):
def apply_filters(task, filters, skip_ext=None):
- """
- Given a task, checks its targets.
- If any of the targets has a filter that matches,
+ """Apply filters to a task.
+
+ If any of the targets of the given task has a filter that matches,
adds the filter commands to the commands of the task,
and the filter itself to the uptodate of the task.
"""
-
if '.php' in filters.keys():
if task_filters.php_template_injection not in filters['.php']:
filters['.php'].append(task_filters.php_template_injection)
@@ -862,6 +889,7 @@ def apply_filters(task, filters, skip_ext=None):
def get_crumbs(path, is_file=False, index_folder=None):
"""Create proper links for a crumb bar.
+
index_folder is used if you want to use title from index file
instead of folder name as breadcrumb text.
@@ -889,7 +917,6 @@ def get_crumbs(path, is_file=False, index_folder=None):
>>> print('|'.join(crumbs[2]))
#|bar
"""
-
crumbs = path.split(os.sep)
_crumbs = []
if is_file:
@@ -919,25 +946,22 @@ def get_crumbs(path, is_file=False, index_folder=None):
def get_asset_path(path, themes, files_folders={'files': ''}, _themes_dir='themes'):
- """
- .. versionchanged:: 6.1.0
-
- Checks which theme provides the path with the given asset,
- and returns the "real", absolute path to the asset.
+ """Return the "real", absolute path to the asset.
+ By default, it checks which theme provides the asset.
If the asset is not provided by a theme, then it will be checked for
- in the FILES_FOLDERS
+ in the FILES_FOLDERS.
- >>> print(get_asset_path('assets/css/rst.css', ['bootstrap', 'base']))
+ >>> print(get_asset_path('assets/css/rst.css', ['bootstrap3', 'base']))
/.../nikola/data/themes/base/assets/css/rst.css
- >>> print(get_asset_path('assets/css/theme.css', ['bootstrap', 'base']))
- /.../nikola/data/themes/bootstrap/assets/css/theme.css
+ >>> print(get_asset_path('assets/css/theme.css', ['bootstrap3', 'base']))
+ /.../nikola/data/themes/bootstrap3/assets/css/theme.css
- >>> print(get_asset_path('nikola.py', ['bootstrap', 'base'], {'nikola': ''}))
+ >>> print(get_asset_path('nikola.py', ['bootstrap3', 'base'], {'nikola': ''}))
/.../nikola/nikola.py
- >>> print(get_asset_path('nikola/nikola.py', ['bootstrap', 'base'], {'nikola':'nikola'}))
+ >>> print(get_asset_path('nikola/nikola.py', ['bootstrap3', 'base'], {'nikola':'nikola'}))
None
"""
@@ -958,16 +982,20 @@ def get_asset_path(path, themes, files_folders={'files': ''}, _themes_dir='theme
class LocaleBorgUninitializedException(Exception):
+
+ """Exception for unitialized LocaleBorg."""
+
def __init__(self):
+ """Initialize exception."""
super(LocaleBorgUninitializedException, self).__init__("Attempt to use LocaleBorg before initialization")
class LocaleBorg(object):
- """
- Provides locale related services and autoritative current_lang,
- where current_lang is the last lang for which the locale was set.
- current_lang is meant to be set only by LocaleBorg.set_locale
+ """Provide locale related services and autoritative current_lang.
+
+ current_lang is the last lang for which the locale was set
+ and is meant to be set only by LocaleBorg.set_locale.
python's locale code should not be directly called from code outside of
LocaleBorg, they are compatibilty issues with py version and OS support
@@ -1001,7 +1029,8 @@ class LocaleBorg(object):
@classmethod
def initialize(cls, locales, initial_lang):
- """
+ """Initialize LocaleBorg.
+
locales : dict with lang: locale_n
the same keys as in nikola's TRANSLATIONS
locale_n a sanitized locale, meaning
@@ -1025,19 +1054,23 @@ class LocaleBorg(object):
@classmethod
def reset(cls):
- """used in testing to not leak state between tests"""
+ """Reset LocaleBorg.
+
+ Used in testing to prevent leaking state between tests.
+ """
cls.locales = {}
cls.encodings = {}
cls.__shared_state = {'current_lang': None}
cls.initialized = False
def __init__(self):
+ """Initialize."""
if not self.initialized:
raise LocaleBorgUninitializedException()
self.__dict__ = self.__shared_state
def set_locale(self, lang):
- """Sets the locale for language lang, returns ''
+ """Set the locale for language lang, returns an empty string.
in linux the locale encoding is set to utf8,
in windows that cannot be guaranted.
@@ -1053,7 +1086,7 @@ class LocaleBorg(object):
return ''
def get_month_name(self, month_no, lang):
- """returns localized month name in an unicode string"""
+ """Return localized month name in an unicode string."""
if sys.version_info[0] == 3: # Python 3
with calendar.different_locale(self.locales[lang]):
s = calendar.month_name[month_no]
@@ -1072,15 +1105,20 @@ class LocaleBorg(object):
class ExtendedRSS2(rss.RSS2):
+
+ """Extended RSS class."""
+
xsl_stylesheet_href = None
def publish(self, handler):
+ """Publish a feed."""
if self.xsl_stylesheet_href:
handler.processingInstruction("xml-stylesheet", 'type="text/xsl" href="{0}" media="all"'.format(self.xsl_stylesheet_href))
# old-style class in py2
rss.RSS2.publish(self, handler)
def publish_extensions(self, handler):
+ """Publish extensions."""
if self.self_url:
handler.startElement("atom:link", {
'href': self.self_url,
@@ -1092,12 +1130,16 @@ class ExtendedRSS2(rss.RSS2):
class ExtendedItem(rss.RSSItem):
+ """Extended RSS item."""
+
def __init__(self, **kw):
+ """Initialize RSS item."""
self.creator = kw.pop('creator')
# It's an old style class
return rss.RSSItem.__init__(self, **kw)
def publish_extensions(self, handler):
+ """Publish extensions."""
if self.creator:
handler.startElement("dc:creator", {})
handler.characters(self.creator)
@@ -1111,7 +1153,7 @@ explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<(.*?)>$', re.DOTALL)
def split_explicit_title(text):
"""Split role content into title and target, if given.
- From Sphinx's "sphinx/util/nodes.py"
+ From Sphinx's "sphinx/util/nodes.py"
"""
match = explicit_title_re.match(text)
if match:
@@ -1120,7 +1162,7 @@ def split_explicit_title(text):
def first_line(doc):
- """extract first non-blank line from text, to extract docstring title"""
+ """Extract first non-blank line from text, to extract docstring title."""
if doc is not None:
for line in doc.splitlines():
striped = line.strip()
@@ -1145,7 +1187,7 @@ def demote_headers(doc, level=1):
def get_root_dir():
- """Find root directory of nikola installation by looking for conf.py"""
+ """Find root directory of nikola site by looking for conf.py."""
root = os.getcwd()
if sys.version_info[0] == 2:
@@ -1167,9 +1209,7 @@ def get_root_dir():
def get_translation_candidate(config, path, lang):
- """
- Return a possible path where we can find the translated version of some page
- based on the TRANSLATIONS_PATTERN configuration variable.
+ """Return a possible path where we can find the translated version of some page, based on the TRANSLATIONS_PATTERN configuration variable.
>>> config = {'TRANSLATIONS_PATTERN': '{path}.{lang}.{ext}', 'DEFAULT_LANG': 'en', 'TRANSLATIONS': {'es':'1', 'en': 1}}
>>> print(get_translation_candidate(config, '*.rst', 'es'))
@@ -1200,7 +1240,6 @@ def get_translation_candidate(config, path, lang):
cache/posts/fancy.post.html
>>> print(get_translation_candidate(config, 'cache/posts/fancy.post.html', 'es'))
cache/posts/fancy.post.html.es
-
"""
# FIXME: this is rather slow and this function is called A LOT
# Convert the pattern into a regexp
@@ -1287,6 +1326,7 @@ def ask_yesno(query, default=None):
class CommandWrapper(object):
+
"""Converts commands into functions."""
def __init__(self, cmd, commands_object):
@@ -1313,7 +1353,7 @@ class Commands(object):
"""
def __init__(self, main, config, doitargs):
- """Takes a main instance, works as wrapper for commands."""
+ """Take a main instance, work as wrapper for commands."""
self._cmdnames = []
self._main = main
self._config = config
@@ -1372,7 +1412,6 @@ class Commands(object):
def __repr__(self):
"""Return useful and verbose help."""
-
return """\
<Nikola Commands>
@@ -1386,6 +1425,7 @@ Available commands: {0}.""".format(', '.join(self._cmdnames))
def options2docstring(name, options):
+ """Translate options to a docstring."""
result = ['Function wrapper for command %s' % name, 'arguments:']
for opt in options:
result.append('{0} type {1} default {2}'.format(opt.name, opt.type.__name__, opt.default))
@@ -1393,8 +1433,11 @@ def options2docstring(name, options):
class NikolaPygmentsHTML(HtmlFormatter):
- """A Nikola-specific modification of Pygments’ HtmlFormatter."""
+
+ """A Nikola-specific modification of Pygments' HtmlFormatter."""
+
def __init__(self, anchor_ref, classes=None, linenos='table', linenostart=1):
+ """Initialize formatter."""
if classes is None:
classes = ['code', 'literal-block']
self.nclasses = classes
@@ -1403,11 +1446,7 @@ class NikolaPygmentsHTML(HtmlFormatter):
lineanchors=slugify(anchor_ref, force=True), anchorlinenos=True)
def wrap(self, source, outfile):
- """
- Wrap the ``source``, which is a generator yielding
- individual lines, in custom generators.
- """
-
+ """Wrap the ``source``, which is a generator yielding individual lines, in custom generators."""
style = []
if self.prestyles:
style.append(self.prestyles)
@@ -1423,6 +1462,7 @@ class NikolaPygmentsHTML(HtmlFormatter):
def get_displayed_page_number(i, num_pages, site):
+ """Get page number to be displayed for entry `i`."""
if not i:
i = 0
if site.config["INDEXES_STATIC"]:
@@ -1432,6 +1472,7 @@ def get_displayed_page_number(i, num_pages, site):
def adjust_name_for_index_path_list(path_list, i, displayed_i, lang, site, force_addition=False, extension=None):
+ """Retrurn a path list for a given index page."""
index_file = site.config["INDEX_FILE"]
if i or force_addition:
path_list = list(path_list)
@@ -1459,6 +1500,7 @@ def adjust_name_for_index_path_list(path_list, i, displayed_i, lang, site, force
def os_path_split(path):
+ """Split a path."""
result = []
while True:
previous_path = path
@@ -1473,10 +1515,12 @@ def os_path_split(path):
def adjust_name_for_index_path(name, i, displayed_i, lang, site, force_addition=False, extension=None):
+ """Return file name for a given index file."""
return os.path.join(*adjust_name_for_index_path_list(os_path_split(name), i, displayed_i, lang, site, force_addition, extension))
def adjust_name_for_index_link(name, i, displayed_i, lang, site, force_addition=False, extension=None):
+ """Return link for a given index file."""
link = adjust_name_for_index_path_list(name.split('/'), i, displayed_i, lang, site, force_addition, extension)
if not extension == ".atom":
if len(link) > 0 and link[-1] == site.config["INDEX_FILE"] and site.config["STRIP_INDEXES"]:
@@ -1485,6 +1529,7 @@ def adjust_name_for_index_link(name, i, displayed_i, lang, site, force_addition=
def create_redirect(src, dst):
+ """"Create a redirection."""
makedirs(os.path.dirname(src))
with io.open(src, "w+", encoding="utf8") as fd:
fd.write('<!DOCTYPE html>\n<head>\n<meta charset="utf-8">\n'
@@ -1495,6 +1540,9 @@ def create_redirect(src, dst):
class TreeNode(object):
+
+ """A tree node."""
+
indent_levels = None # use for formatting comments as tree
indent_change_before = 0 # use for formatting comments as tree
indent_change_after = 0 # use for formatting comments as tree
@@ -1530,11 +1578,13 @@ class TreeNode(object):
# indent_levels property for that node.)
def __init__(self, name, parent=None):
+ """Initialize node."""
self.name = name
self.parent = parent
self.children = []
def get_path(self):
+ """Get path."""
path = []
curr = self
while curr is not None:
@@ -1543,10 +1593,12 @@ class TreeNode(object):
return reversed(path)
def get_children(self):
+ """Get children of a node."""
return self.children
def flatten_tree_structure(root_list):
+ """Flatten a tree."""
elements = []
def generate(input_list, indent_levels_so_far):
@@ -1582,6 +1634,7 @@ def flatten_tree_structure(root_list):
def parse_escaped_hierarchical_category_name(category_name):
+ """Parse a category name."""
result = []
current = None
index = 0
@@ -1613,6 +1666,7 @@ def parse_escaped_hierarchical_category_name(category_name):
def join_hierarchical_category_path(category_path):
+ """Join a category path."""
def escape(s):
return s.replace('\\', '\\\\').replace('/', '\\/')
@@ -1621,7 +1675,7 @@ def join_hierarchical_category_path(category_path):
# Stolen from textwrap in Python 3.4.3.
def indent(text, prefix, predicate=None):
- """Adds 'prefix' to the beginning of selected lines in 'text'.
+ """Add 'prefix' to the beginning of selected lines in 'text'.
If 'predicate' is provided, 'prefix' will only be added to the lines
where 'predicate(line)' is True. If 'predicate' is not provided,
diff --git a/nikola/winutils.py b/nikola/winutils.py
index 8e29f5b..3ea179b 100644
--- a/nikola/winutils.py
+++ b/nikola/winutils.py
@@ -24,7 +24,7 @@
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"""windows utilities to workaround problems with symlinks in a git clone"""
+"""windows utilities to workaround problems with symlinks in a git clone."""
from __future__ import print_function, unicode_literals
import os
@@ -34,6 +34,7 @@ import io
def is_file_into_dir(filename, dirname):
+ """Check if a file is in directory."""
try:
res = not os.path.relpath(filename, dirname).startswith('.')
except ValueError:
@@ -42,7 +43,7 @@ def is_file_into_dir(filename, dirname):
def fix_all_git_symlinked(topdir):
- """inplace conversion of git symlinks to real content
+ """Convert git symlinks to real content.
Most (all?) of git implementations in windows store a symlink pointing
into the repo as a text file, the text being the relative path to the
diff --git a/requirements-extras.txt b/requirements-extras.txt
index 56f3adb..23501c1 100644
--- a/requirements-extras.txt
+++ b/requirements-extras.txt
@@ -3,7 +3,7 @@ Markdown>=2.4.0
Jinja2>=2.7.2
pyphen>=0.9.1
micawber>=0.3.0
-pygal==1.7.0
+pygal==2.0.1
typogrify>=2.0.4
phpserialize>=1.3
webassets>=0.10.1
diff --git a/requirements-tests.txt b/requirements-tests.txt
index ce6bf8a..b2d8ca8 100644
--- a/requirements-tests.txt
+++ b/requirements-tests.txt
@@ -1,8 +1,8 @@
-r requirements-extras.txt
-mock==1.0.1
+mock==1.3.0
coverage==3.7.1
pytest==2.7.2
-pytest-cov==1.8.1
-freezegun==0.3.4
+pytest-cov==2.0.0
+freezegun==0.3.5
python-coveralls==2.5.0
colorama==0.3.3
diff --git a/requirements.txt b/requirements.txt
index 2334e9c..5d2c7d2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-doit==0.28.0
+doit>=0.28.0
Pygments>=1.6
Pillow>=2.4.0
python-dateutil==2.4.2
@@ -6,7 +6,7 @@ docutils>=0.12
mako>=1.0.0
unidecode>=0.04.16
lxml>=3.3.5
-Yapsy==1.11.223
+Yapsy>=1.11.223
PyRSS2Gen>=1.1
logbook>=0.7.0
blinker>=1.3
diff --git a/scripts/INTERNAL USE ONLY b/scripts/INTERNAL USE ONLY
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/INTERNAL USE ONLY
diff --git a/scripts/getwheelhouse.sh b/scripts/getwheelhouse.sh
index 753fc2b..911ffbd 100755
--- a/scripts/getwheelhouse.sh
+++ b/scripts/getwheelhouse.sh
@@ -3,7 +3,5 @@ for i in $@; do
wget https://github.com/getnikola/wheelhouse/archive/v$i'.zip'
unzip 'v'$i'.zip'
pip install --use-wheel --no-index --find-links=wheelhouse-$i lxml Pillow ipython
- # Install Markdown for Python 2.6.
- pip install --use-wheel --no-index --find-links=wheelhouse-$i Markdown || true
rm -rf wheelhouse-$i 'v'$i'.zip'
done
diff --git a/scripts/jinjify.py b/scripts/jinjify.py
index 30f8029..abd18e9 100755
--- a/scripts/jinjify.py
+++ b/scripts/jinjify.py
@@ -18,7 +18,8 @@ dumb_replacements = [
["og: http://ogp.me/ns# \\", "og: http://ogp.me/ns#"],
["article: http://ogp.me/ns/article# \\", "article: http://ogp.me/ns/article#"],
["fb: http://ogp.me/ns/fb# \\", "fb: http://ogp.me/ns/fb#"],
- ['dir="rtl" \\', 'dir="rtl"']
+ ['dir="rtl" \\', 'dir="rtl"'],
+ ['sorted(translations)', 'translations|sort'],
]
dumber_replacements = [
@@ -70,8 +71,7 @@ def jinjify(in_theme, out_theme):
child = os.path.basename(out_theme.rstrip('/'))
mappings = {
'base-jinja': 'base',
- 'bootstrap-jinja': 'base-jinja',
- 'bootstrap3-jinja': 'bootstrap-jinja',
+ 'bootstrap3-jinja': 'base-jinja',
}
if child in mappings:
@@ -84,7 +84,7 @@ def jinjify(in_theme, out_theme):
outf.write(u"jinja\n")
# Copy assets in bootstrap/bootstrap3
- if child in ('bootstrap-jinja', 'bootstrap3-jinja'):
+ if child == 'bootstrap3-jinja':
shutil.rmtree(os.path.join(out_theme, "assets"))
shutil.copytree(
os.path.join(in_theme, "assets"), os.path.join(out_theme, "assets"),
@@ -220,7 +220,6 @@ if __name__ == "__main__":
print('Performing standard conversions:')
for m, j in (
('nikola/data/themes/base', 'nikola/data/themes/base-jinja'),
- ('nikola/data/themes/bootstrap', 'nikola/data/themes/bootstrap-jinja'),
('nikola/data/themes/bootstrap3', 'nikola/data/themes/bootstrap3-jinja')
):
print(' {0} -> {1}'.format(m, j))
diff --git a/scripts/update-bower.sh b/scripts/update-bower.sh
index d077434..fbf69a0 100755
--- a/scripts/update-bower.sh
+++ b/scripts/update-bower.sh
@@ -27,29 +27,29 @@ git add moment-with-locales.min.js
popd
# Link jQuery to bootstrap theme
-pushd nikola/data/themes/bootstrap/assets/js
+pushd nikola/data/themes/bootstrap3/assets/js
ln -sf ../../../../../../bower_components/jquery/dist/* .
git add .
popd
# Link colorbox into bootstrap theme
-pushd nikola/data/themes/bootstrap/assets/js
+pushd nikola/data/themes/bootstrap3/assets/js
ln -sf ../../../../../../bower_components/jquery-colorbox/jquery.colorbox.js .
git add jquery.colorbox.js
popd
-pushd nikola/data/themes/bootstrap/assets/js/colorbox-i18n
+pushd nikola/data/themes/bootstrap3/assets/js/colorbox-i18n
ln -sf ../../../../../../../bower_components/jquery-colorbox/i18n/* .
git add .
popd
-pushd nikola/data/themes/bootstrap/assets/css/
+pushd nikola/data/themes/bootstrap3/assets/css/
ln -sf ../../../../../../bower_components/jquery-colorbox/example3/colorbox.css .
git add colorbox.css
popd
-pushd nikola/data/themes/bootstrap/assets/css/images/
+pushd nikola/data/themes/bootstrap3/assets/css/images/
ln -sf ../../../../../../../bower_components/jquery-colorbox/example3/images/* .
git add .
popd
diff --git a/setup.py b/setup.py
index 81ec570..6ae145c 100755
--- a/setup.py
+++ b/setup.py
@@ -112,7 +112,7 @@ class nikola_install(install):
setup(name='Nikola',
- version='7.6.0',
+ version='7.6.4',
description='A modular, fast, simple, static website generator',
long_description=open('README.rst').read(),
author='Roberto Alsina and others',
diff --git a/tests/base.py b/tests/base.py
index f0bd484..14af18a 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -30,8 +30,9 @@ from nikola.plugin_categories import (
TemplateSystem,
PageCompiler,
TaskMultiplier,
- RestExtension,
- MarkdownExtension
+ CompilerExtension,
+ MarkdownExtension,
+ RestExtension
)
@@ -213,10 +214,11 @@ class FakeSite(object):
"TemplateSystem": TemplateSystem,
"PageCompiler": PageCompiler,
"TaskMultiplier": TaskMultiplier,
- "RestExtension": RestExtension,
+ "CompilerExtension": CompilerExtension,
"MarkdownExtension": MarkdownExtension,
+ "RestExtension": RestExtension
})
- self.loghandlers = [nikola.utils.STDERR_HANDLER]
+ self.loghandlers = nikola.utils.STDERR_HANDLER # TODO remove on v8
self.plugin_manager.setPluginInfoExtension('plugin')
if sys.version_info[0] == 3:
places = [
@@ -228,6 +230,7 @@ class FakeSite(object):
]
self.plugin_manager.setPluginPlaces(places)
self.plugin_manager.collectPlugins()
+ self.compiler_extensions = self._activate_plugins_of_category("CompilerExtension")
self.timeline = [
FakePost(title='Fake post',
@@ -239,5 +242,18 @@ class FakeSite(object):
self.template_system = self
self.name = 'mako'
+ def _activate_plugins_of_category(self, category):
+ """Activate all the plugins of a given category and return them."""
+ # this code duplicated in nikola/nikola.py
+ plugins = []
+ for plugin_info in self.plugin_manager.getPluginsOfCategory(category):
+ if plugin_info.name in self.config.get('DISABLED_PLUGINS'):
+ self.plugin_manager.removePluginFromCategory(plugin_info, category)
+ else:
+ self.plugin_manager.activatePluginByName(plugin_info.name)
+ plugin_info.plugin_object.set_site(self)
+ plugins.append(plugin_info)
+ return plugins
+
def render_template(self, name, _, context):
return('<img src="IMG.jpg">')
diff --git a/tests/data/1-nolinks.rst b/tests/data/1-nolinks.rst
new file mode 100644
index 0000000..7f168fb
--- /dev/null
+++ b/tests/data/1-nolinks.rst
@@ -0,0 +1,28 @@
+.. title: Welcome to Nikola
+.. slug: welcome-to-nikola
+.. date: 2012-03-30 23:00:00 UTC-03:00
+.. tags: nikola, python, demo, blog
+.. author: Roberto Alsina
+.. link: https://getnikola.com/
+.. description:
+.. category: nikola
+
+.. figure:: http://farm1.staticflickr.com/138/352972944_4f9d568680.jpg
+ :target: http://farm1.staticflickr.com/138/352972944_4f9d568680_z.jpg?zz=1
+ :class: thumbnail
+ :alt: Nikola Tesla Corner by nicwest, on Flickr
+
+If you can see this in a web browser, it means you did something wrong, because
+you should be reading a nice post with links, and this should be used in
+the test suite only.
+
+Next steps:
+
+* Read the manual
+* Visit the Nikola website to learn more
+* See a demo photo gallery
+* See a demo listing
+* See a demo slideshow
+* See a demo of the Bootstrap theme
+
+Send feedback to info@getnikola.com!
diff --git a/tests/test_command_import_wordpress.py b/tests/test_command_import_wordpress.py
index 2c47bc3..c1c7836 100644
--- a/tests/test_command_import_wordpress.py
+++ b/tests/test_command_import_wordpress.py
@@ -2,8 +2,6 @@
from __future__ import unicode_literals, absolute_import
import os
-import sys
-
import unittest
import mock
@@ -172,6 +170,8 @@ class CommandImportWordpressTest(BasicCommandImportWordpress):
def test_populate_context(self):
channel = self.import_command.get_channel_from_file(
self.import_filename)
+ self.import_command.transform_to_html = False
+ self.import_command.use_wordpress_compiler = False
context = self.import_command.populate_context(channel)
for required_key in ('POSTS', 'PAGES', 'COMPILERS'):
@@ -188,12 +188,16 @@ class CommandImportWordpressTest(BasicCommandImportWordpress):
def test_importing_posts_and_attachments(self):
channel = self.import_command.get_channel_from_file(
self.import_filename)
- self.import_command.context = self.import_command.populate_context(
- channel)
self.import_command.base_dir = ''
self.import_command.output_folder = 'new_site'
self.import_command.squash_newlines = True
self.import_command.no_downloads = False
+ self.import_command.export_categories_as_categories = False
+ self.import_command.export_comments = False
+ self.import_command.transform_to_html = False
+ self.import_command.use_wordpress_compiler = False
+ self.import_command.context = self.import_command.populate_context(
+ channel)
# Ensuring clean results
self.import_command.url_map = {}
@@ -201,13 +205,15 @@ class CommandImportWordpressTest(BasicCommandImportWordpress):
write_metadata = mock.MagicMock()
write_content = mock.MagicMock()
+ write_attachments_info = mock.MagicMock()
download_mock = mock.MagicMock()
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_content', write_content):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_metadata', write_metadata):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.download_url_content_to_file', download_mock):
- with mock.patch('nikola.plugins.command.import_wordpress.os.makedirs'):
- self.import_command.import_posts(channel)
+ with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_attachments_info', write_attachments_info):
+ with mock.patch('nikola.plugins.command.import_wordpress.os.makedirs'):
+ self.import_command.import_posts(channel)
self.assertTrue(download_mock.called)
qpath = 'new_site/files/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png'
@@ -218,10 +224,10 @@ class CommandImportWordpressTest(BasicCommandImportWordpress):
self.assertTrue(write_metadata.called)
write_metadata.assert_any_call(
'new_site/stories/kontakt.meta'.replace('/', os.sep), 'Kontakt',
- 'kontakt', '2009-07-16 20:20:32', '', [])
+ 'kontakt', '2009-07-16 20:20:32', '', [], **{'wp-status': 'publish'})
self.assertTrue(write_content.called)
- write_content.assert_any_call('new_site/posts/2007/04/hoert.wp'.replace('/', os.sep),
+ write_content.assert_any_call('new_site/posts/2007/04/hoert.md'.replace('/', os.sep),
"""An image.
<img class="size-full wp-image-16" title="caption test" src="http://some.blog/wp-content/uploads/2009/07/caption_test.jpg" alt="caption test" width="739" height="517" />
@@ -238,15 +244,27 @@ print sys.version
The end.
-""")
+""", True)
+
+ self.assertTrue(write_attachments_info.called)
+ write_attachments_info.assert_any_call('new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.attachments.json'.replace('/', os.sep),
+ {10: {'wordpress_user_name': 'Niko',
+ 'files_meta': [{'width': 300, 'height': 299},
+ {'width': b'150', 'size': 'thumbnail', 'height': b'150'}],
+ 'excerpt': 'Arzt+Pfusch - S.I.C.K.',
+ 'date_utc': '2009-07-16 19:40:37',
+ 'content': 'Das Cover von Arzt+Pfusch - S.I.C.K.',
+ 'files': ['/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png',
+ '/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover-150x150.png'],
+ 'title': 'Arzt+Pfusch - S.I.C.K.'}})
write_content.assert_any_call(
- 'new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.wp'.replace('/', os.sep),
+ 'new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.md'.replace('/', os.sep),
'''<img class="size-full wp-image-10 alignright" title="Arzt+Pfusch - S.I.C.K." src="http://some.blog/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png" alt="Arzt+Pfusch - S.I.C.K." width="210" height="209" />Arzt+Pfusch - S.I.C.K.Gerade bin ich \xfcber das Album <em>S.I.C.K</em> von <a title="Arzt+Pfusch" href="http://www.arztpfusch.com/" target="_blank">Arzt+Pfusch</a> gestolpert, welches Arzt+Pfusch zum Download f\xfcr lau anbieten. Das Album steht unter einer Creative Commons <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/de/">BY-NC-ND</a>-Lizenz.
-Die Ladung <em>noisebmstupidevildustrial</em> gibts als MP3s mit <a href="http://www.archive.org/download/dmp005/dmp005_64kb_mp3.zip">64kbps</a> und <a href="http://www.archive.org/download/dmp005/dmp005_vbr_mp3.zip">VBR</a>, als Ogg Vorbis und als FLAC (letztere <a href="http://www.archive.org/details/dmp005">hier</a>). <a href="http://www.archive.org/download/dmp005/dmp005-artwork.zip">Artwork</a> und <a href="http://www.archive.org/download/dmp005/dmp005-lyrics.txt">Lyrics</a> gibts nochmal einzeln zum Download.''')
+Die Ladung <em>noisebmstupidevildustrial</em> gibts als MP3s mit <a href="http://www.archive.org/download/dmp005/dmp005_64kb_mp3.zip">64kbps</a> und <a href="http://www.archive.org/download/dmp005/dmp005_vbr_mp3.zip">VBR</a>, als Ogg Vorbis und als FLAC (letztere <a href="http://www.archive.org/details/dmp005">hier</a>). <a href="http://www.archive.org/download/dmp005/dmp005-artwork.zip">Artwork</a> und <a href="http://www.archive.org/download/dmp005/dmp005-lyrics.txt">Lyrics</a> gibts nochmal einzeln zum Download.''', True)
write_content.assert_any_call(
- 'new_site/stories/kontakt.wp'.replace('/', os.sep), """<h1>Datenschutz</h1>
+ 'new_site/stories/kontakt.md'.replace('/', os.sep), """<h1>Datenschutz</h1>
Ich erhebe und speichere automatisch in meine Server Log Files Informationen, die dein Browser an mich \xfcbermittelt. Dies sind:
@@ -264,7 +282,7 @@ Ich erhebe und speichere automatisch in meine Server Log Files Informationen, di
</ul>
-Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammenf\xfchrung dieser Daten mit anderen Datenquellen wird nicht vorgenommen, die Daten werden einzig zu statistischen Zwecken erhoben.""")
+Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammenf\xfchrung dieser Daten mit anderen Datenquellen wird nicht vorgenommen, die Daten werden einzig zu statistischen Zwecken erhoben.""", True)
self.assertTrue(len(self.import_command.url_map) > 0)
@@ -306,10 +324,13 @@ Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammen
transform_caption = mock.MagicMock()
transform_newlines = mock.MagicMock()
+ self.import_command.transform_to_html = False
+ self.import_command.use_wordpress_compiler = False
+
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_code', transform_code):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_caption', transform_caption):
with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_multiple_newlines', transform_newlines):
- self.import_command.transform_content("random content")
+ self.import_command.transform_content("random content", "wp", None)
self.assertTrue(transform_code.called)
self.assertTrue(transform_caption.called)
@@ -418,21 +439,17 @@ newlines.
self.assertTrue(self.import_command.name in config_path_with_timestamp)
def test_write_content_does_not_detroy_text(self):
- content = b"""<h1>Installation</h1>
-Follow the instructions <a title="Installing Jenkins" href="https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins">described here</a>.
-
-<h1>Plugins</h1>
-There are many plugins.
-<h2>Violations</h2>
-You can use the <a title="Jenkins Plugin: Violations" href="https://wiki.jenkins-ci.org/display/JENKINS/Violations">Violations</a> plugin."""
+ content = b"""FOO"""
open_mock = mock.mock_open()
with mock.patch('nikola.plugins.basic_import.open', open_mock, create=True):
self.import_command.write_content('some_file', content)
- open_mock.assert_called_once_with('some_file', 'wb+')
- call_context = open_mock()
- call_context.write.assert_called_once_with(
- content.join([b'<html><body>', b'</body></html>']))
+ open_mock.assert_has_calls([
+ mock.call(u'some_file', u'wb+'),
+ mock.call().__enter__(),
+ mock.call().write(b'<html><body><p>FOO</p></body></html>'),
+ mock.call().__exit__(None, None, None)]
+ )
def test_configure_redirections(self):
"""
diff --git a/tests/test_integration.py b/tests/test_integration.py
index 62ccd79..4bfd1d2 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -105,6 +105,9 @@ class DemoBuildTest(EmptyBuildTest):
"""Fill the site with demo content."""
self.init_command.copy_sample_site(self.target_dir)
self.init_command.create_configuration(self.target_dir)
+ src1 = os.path.join(os.path.dirname(__file__), 'data', '1-nolinks.rst')
+ dst1 = os.path.join(self.target_dir, 'posts', '1.rst')
+ shutil.copy(src1, dst1)
# File for Issue #374 (empty post text)
with io.open(os.path.join(self.target_dir, 'posts', 'empty.txt'), "w+", encoding="utf8") as outf:
outf.write(
@@ -526,6 +529,9 @@ class InvariantBuildTest(EmptyBuildTest):
"""Fill the site with demo content."""
self.init_command.copy_sample_site(self.target_dir)
self.init_command.create_configuration(self.target_dir)
+ src1 = os.path.join(os.path.dirname(__file__), 'data', '1-nolinks.rst')
+ dst1 = os.path.join(self.target_dir, 'posts', '1.rst')
+ shutil.copy(src1, dst1)
os.system('rm "{0}/stories/creating-a-theme.rst" "{0}/stories/extending.txt" "{0}/stories/internals.txt" "{0}/stories/manual.rst" "{0}/stories/social_buttons.txt" "{0}/stories/theming.rst" "{0}/stories/upgrading-to-v6.txt"'.format(self.target_dir))
def test_invariance(self):
diff --git a/tests/test_rss_feeds.py b/tests/test_rss_feeds.py
index 992b1b7..f67ed40 100644
--- a/tests/test_rss_feeds.py
+++ b/tests/test_rss_feeds.py
@@ -91,9 +91,9 @@ class RSSFeedTest(unittest.TestCase):
# lxml will complain if the encoding is specified in the
# xml when running with unicode strings.
# We do not include this in our content.
- open_handle = opener_mock()
- file_content = [call[1][0]
- for call in open_handle.mock_calls[1:-1]][0]
+ file_content = [
+ call[1][0]
+ for call in opener_mock.mock_calls[2:-1]][0]
splitted_content = file_content.split('\n')
self.encoding_declaration = splitted_content[0]
content_without_encoding_declaration = splitted_content[1:]
diff --git a/tests/test_slugify.py b/tests/test_slugify.py
new file mode 100644
index 0000000..9dec5a6
--- /dev/null
+++ b/tests/test_slugify.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+u"""Test slugify."""
+
+from __future__ import unicode_literals
+import nikola.utils
+
+
+def test_ascii():
+ """Test an ASCII-only string."""
+ o = nikola.utils.slugify(u'hello')
+ assert o == u'hello'
+ assert isinstance(o, nikola.utils.unicode_str)
+
+
+def test_ascii_dash():
+ """Test an ASCII string, with dashes."""
+ o = nikola.utils.slugify(u'hello-world')
+ assert o == u'hello-world'
+ assert isinstance(o, nikola.utils.unicode_str)
+
+
+def test_ascii_fancy():
+ """Test an ASCII string, with fancy characters."""
+ o = nikola.utils.slugify(u'The quick brown fox jumps over the lazy dog!-123.456')
+ assert o == u'the-quick-brown-fox-jumps-over-the-lazy-dog-123456'
+ assert isinstance(o, nikola.utils.unicode_str)
+
+
+def test_pl():
+ """Test a string with Polish diacritical characters."""
+ o = nikola.utils.slugify(u'zażółćgęśląjaźń')
+ assert o == u'zazolcgeslajazn'
+ assert isinstance(o, nikola.utils.unicode_str)
+
+
+def test_pl_dash():
+ """Test a string with Polish diacritical characters and dashes."""
+ o = nikola.utils.slugify(u'zażółć-gęślą-jaźń')
+ assert o == u'zazolc-gesla-jazn'
+
+
+def test_pl_fancy():
+ """Test a string with Polish diacritical characters and fancy characters."""
+ o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456')
+ assert o == u'zazolc-gesla-jazn-123456'
+ assert isinstance(o, nikola.utils.unicode_str)
+
+
+def test_disarmed():
+ """Test disarmed slugify."""
+ nikola.utils.USE_SLUGIFY = False
+ o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456')
+ assert o == u'Zażółć gęślą jaźń!-123.456'
+ assert isinstance(o, nikola.utils.unicode_str)
+ nikola.utils.USE_SLUGIFY = True
+
+
+def test_disarmed_weird():
+ """Test disarmed slugify with banned characters."""
+ nikola.utils.USE_SLUGIFY = False
+ o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456 "Hello World"?#H<e>l/l\\o:W\'o\rr*l\td|!\n')
+ assert o == u'Zażółć gęślą jaźń!-123.456 -Hello World---H-e-l-l-o-W-o-r-l-d-!-'
+ assert isinstance(o, nikola.utils.unicode_str)
+ nikola.utils.USE_SLUGIFY = True
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 1e2d3b3..9507de2 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -18,16 +18,15 @@ class dummy(object):
class GetMetaTest(unittest.TestCase):
def test_getting_metadata_from_content(self):
- file_metadata = [".. title: Nikola needs more tests!\n",
- ".. slug: write-tests-now\n",
- ".. date: 2012/09/15 19:52:05\n",
- ".. tags:\n",
- ".. link:\n",
- ".. description:\n",
- "Post content\n"]
+ file_metadata = ".. title: Nikola needs more tests!\n"\
+ ".. slug: write-tests-now\n"\
+ ".. date: 2012/09/15 19:52:05\n"\
+ ".. tags:\n"\
+ ".. link:\n"\
+ ".. description:\n"\
+ "Post content\n"
opener_mock = mock.mock_open(read_data=file_metadata)
- opener_mock.return_value.readlines.return_value = file_metadata
post = dummy()
post.source_path = 'file_with_metadata'
@@ -45,16 +44,15 @@ class GetMetaTest(unittest.TestCase):
self.assertTrue(nsm)
def test_get_title_from_rest(self):
- file_metadata = [".. slug: write-tests-now\n",
- ".. date: 2012/09/15 19:52:05\n",
- ".. tags:\n",
- ".. link:\n",
- ".. description:\n",
- "Post Title\n",
- "----------\n"]
+ file_metadata = ".. slug: write-tests-now\n"\
+ ".. date: 2012/09/15 19:52:05\n"\
+ ".. tags:\n"\
+ ".. link:\n"\
+ ".. description:\n\n"\
+ "Post Title\n"\
+ "----------\n"
opener_mock = mock.mock_open(read_data=file_metadata)
- opener_mock.return_value.readlines.return_value = file_metadata
post = dummy()
post.source_path = 'file_with_metadata'
@@ -72,14 +70,13 @@ class GetMetaTest(unittest.TestCase):
self.assertTrue(nsm)
def test_get_title_from_fname(self):
- file_metadata = [".. slug: write-tests-now\n",
- ".. date: 2012/09/15 19:52:05\n",
- ".. tags:\n",
- ".. link:\n",
- ".. description:\n"]
+ file_metadata = ".. slug: write-tests-now\n"\
+ ".. date: 2012/09/15 19:52:05\n"\
+ ".. tags:\n"\
+ ".. link:\n"\
+ ".. description:\n"
opener_mock = mock.mock_open(read_data=file_metadata)
- opener_mock.return_value.readlines.return_value = file_metadata
post = dummy()
post.source_path = 'file_with_metadata'
@@ -97,15 +94,14 @@ class GetMetaTest(unittest.TestCase):
self.assertTrue(nsm)
def test_use_filename_as_slug_fallback(self):
- file_metadata = [".. title: Nikola needs more tests!\n",
- ".. date: 2012/09/15 19:52:05\n",
- ".. tags:\n",
- ".. link:\n",
- ".. description:\n",
- "Post content\n"]
+ file_metadata = ".. title: Nikola needs more tests!\n"\
+ ".. date: 2012/09/15 19:52:05\n"\
+ ".. tags:\n"\
+ ".. link:\n"\
+ ".. description:\n\n"\
+ "Post content\n"
opener_mock = mock.mock_open(read_data=file_metadata)
- opener_mock.return_value.readlines.return_value = file_metadata
post = dummy()
post.source_path = 'Slugify this'
@@ -113,7 +109,6 @@ class GetMetaTest(unittest.TestCase):
with mock.patch('nikola.post.io.open', opener_mock, create=True):
meta, nsm = get_meta(post, 'Slugify this')
-
self.assertEqual('Nikola needs more tests!', meta['title'])
self.assertEqual('slugify-this', meta['slug'])
self.assertEqual('2012/09/15 19:52:05', meta['date'])
@@ -250,7 +245,7 @@ class TranslatableSettingsTest(unittest.TestCase):
except NameError: # Python 3
u = str(S)
- cn = S() # no language specified
+ cn = S() # no language specified
cr = S('xx') # real language specified
cf = S('zz') # fake language specified
@@ -323,5 +318,18 @@ class TranslatableSettingsTest(unittest.TestCase):
self.assertEqual(inp['zz'], cn)
+def test_get_metadata_from_file():
+ # These were doctests and not running :-P
+ from nikola.post import _get_metadata_from_file
+ g = _get_metadata_from_file
+ assert list(g([]).values()) == []
+ assert str(g(["======","FooBar","======"])["title"]) == 'FooBar'
+ assert str(g(["FooBar","======"])["title"]) == 'FooBar'
+ assert str(g(["#FooBar"])["title"]) == 'FooBar'
+ assert str(g([".. title: FooBar"])["title"]) == 'FooBar'
+ assert 'title' not in g(["","",".. title: FooBar"])
+ assert 'title' in g(["",".. title: FooBar"])
+ assert 'title' in g([".. foo: bar","","FooBar", "------"])
+
if __name__ == '__main__':
unittest.main()
diff --git a/translations/nikola.messages/bs.po b/translations/nikola.messages/bs.po
new file mode 100644
index 0000000..4b4e7dd
--- /dev/null
+++ b/translations/nikola.messages/bs.po
@@ -0,0 +1,132 @@
+# Messages in Nikola
+# Copyright (C) 2012-2013
+# This file is distributed under the same license as the Nikola package.
+#
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# Saša Savić <sasa.savic@protonmail.com>, 2015
+msgid ""
+msgstr ""
+"Project-Id-Version: Nikola\n"
+"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
+"POT-Creation-Date: 2013-03-15 12:24-0300\n"
+"PO-Revision-Date: 2015-07-30 18:48+0000\n"
+"Last-Translator: Saša Savić <sasa.savic@protonmail.com>\n"
+"Language-Team: Bosnian (http://www.transifex.com/ralsina/nikola/language/bs/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: bs\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgid "More posts about %s"
+msgstr "Više objava o %s"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "LANGUAGE"
+msgstr "Bosanski"
+
+msgid "Tags"
+msgstr "Oznake"
+
+msgid "Categories"
+msgstr "Kategorije"
+
+msgid "Tags and Categories"
+msgstr "Oznake i kategorije"
+
+msgid "Comments"
+msgstr "Komentari"
+
+msgid "Read more"
+msgstr "Pročitaj više"
+
+msgid "Posts about %s"
+msgstr "Objave o %s"
+
+msgid "Next post"
+msgstr "Naredna objava"
+
+msgid "old posts, page %d"
+msgstr "stare objave, strana %d"
+
+msgid "page %d"
+msgstr "strana %d"
+
+msgid "Source"
+msgstr "Izvor"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "Read in English"
+msgstr "Pročitaj na bosanskom"
+
+msgid "Posts for year %s"
+msgstr "Objave u godini %s"
+
+msgid "Newer posts"
+msgstr "Novije objave"
+
+msgid "Previous post"
+msgstr "Prethodne objave"
+
+msgid "Also available in:"
+msgstr "Takođe dostupan u:"
+
+msgid "Languages:"
+msgstr "Jezici:"
+
+msgid "Original site"
+msgstr "Izvorni sajt"
+
+msgid "Older posts"
+msgstr "Starije objave"
+
+msgid "Archive"
+msgstr "Arhiva"
+
+msgid "Publication date"
+msgstr "Datum objavljivanja"
+
+msgid "Posted:"
+msgstr "Objavljeno:"
+
+msgid "Posts for {month} {year}"
+msgstr "Objave za {month} {year}"
+
+msgid "Posts for {month} {day}, {year}"
+msgstr "Objave za {month} {day}, {year}"
+
+msgid "Nothing found."
+msgstr "Ništa nije pronađeno."
+
+msgid "No posts found."
+msgstr "Nema objava."
+
+msgid "RSS feed"
+msgstr "RSS feed"
+
+msgid "%d min remaining to read"
+msgstr "%d minuta preostalo za čitanje"
+
+msgid "Skip to main content"
+msgstr "Preskoči na glavni sadržaj"
+
+msgid "Subcategories:"
+msgstr "Podkategorije:"
+
+#. Used for active navigation links, for screen readers only
+msgid "(active)"
+msgstr "(aktivno)"
+
+#. Default content for a new post
+msgid "Write your post here."
+msgstr "Vašu objavu napišite ovdje."
+
+#. Default content for a new page
+msgid "Write your page here."
+msgstr "Vašu stranicu napišite ovdje."
diff --git a/translations/nikola.messages/fi.po b/translations/nikola.messages/fi.po
index 6e46e51..13505a8 100644
--- a/translations/nikola.messages/fi.po
+++ b/translations/nikola.messages/fi.po
@@ -9,14 +9,15 @@
# Translators:
# ekari <eero.kari@gmail.com>, 2013
# ekari <eero.kari@gmail.com>, 2013-2014
+# Tuomas Räsänen <tuomasjjrasanen@tjjr.fi>, 2015
msgid ""
msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Finnish (http://www.transifex.com/projects/p/nikola/language/fi/)\n"
+"PO-Revision-Date: 2015-07-13 21:20+0000\n"
+"Last-Translator: Tuomas Räsänen <tuomasjjrasanen@tjjr.fi>\n"
+"Language-Team: Finnish (http://www.transifex.com/p/nikola/language/fi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -73,7 +74,7 @@ msgid "Newer posts"
msgstr "Uudempia postauksia"
msgid "Previous post"
-msgstr "Vanhempia postauksia"
+msgstr "Edellinen postaus"
msgid "Also available in:"
msgstr "Saatavilla myös:"
@@ -109,7 +110,7 @@ msgid "No posts found."
msgstr "Postauksia ei löytynyt."
msgid "RSS feed"
-msgstr "RSS syöte"
+msgstr "RSS-syöte"
msgid "%d min remaining to read"
msgstr "%d minuuttia lukuaikaa"
@@ -118,11 +119,11 @@ msgid "Skip to main content"
msgstr "Hyppää sisältöön"
msgid "Subcategories:"
-msgstr ""
+msgstr "Alakategoriat:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(aktiivinen)"
#. Default content for a new post
msgid "Write your post here."
diff --git a/translations/nikola.messages/hr.po b/translations/nikola.messages/hr.po
index 0135634..b2fdd90 100644
--- a/translations/nikola.messages/hr.po
+++ b/translations/nikola.messages/hr.po
@@ -7,6 +7,7 @@
# Translators:
# Translators:
# Translators:
+# Saša Savić <sasa.savic@protonmail.com>, 2015
# tty, 2013
# tty, 2013-2014
msgid ""
@@ -14,9 +15,9 @@ msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Croatian (http://www.transifex.com/projects/p/nikola/language/hr/)\n"
+"PO-Revision-Date: 2015-07-30 19:03+0000\n"
+"Last-Translator: Saša Savić <sasa.savic@protonmail.com>\n"
+"Language-Team: Croatian (http://www.transifex.com/ralsina/nikola/language/hr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -112,17 +113,17 @@ msgid "RSS feed"
msgstr "RSS kanal"
msgid "%d min remaining to read"
-msgstr ""
+msgstr "%d minuta preostalo za čitanje"
msgid "Skip to main content"
-msgstr ""
+msgstr "Preskoči na glavni sadržaj"
msgid "Subcategories:"
-msgstr ""
+msgstr "Podkategorije:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(aktivno)"
#. Default content for a new post
msgid "Write your post here."
diff --git a/translations/nikola.messages/it.po b/translations/nikola.messages/it.po
index 3d76538..c81d4e9 100644
--- a/translations/nikola.messages/it.po
+++ b/translations/nikola.messages/it.po
@@ -19,7 +19,7 @@ msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:31+0000\n"
+"PO-Revision-Date: 2015-07-04 18:27+0000\n"
"Last-Translator: Nicola Larosa <transifex@teknico.net>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/nikola/language/it/)\n"
"MIME-Version: 1.0\n"
@@ -34,7 +34,7 @@ msgstr "Altri articoli collegati %s"
#. Here your translation should NOT say English but the name of your language
#. instead
msgid "LANGUAGE"
-msgstr "Inglese"
+msgstr "Italiano"
msgid "Tags"
msgstr "Tag"
@@ -43,7 +43,7 @@ msgid "Categories"
msgstr "Categorie"
msgid "Tags and Categories"
-msgstr "Tag e Categorie"
+msgstr "Tag e categorie"
msgid "Comments"
msgstr "Commenti"
diff --git a/translations/nikola.messages/nb.po b/translations/nikola.messages/nb.po
index 57ad442..64dd0de 100644
--- a/translations/nikola.messages/nb.po
+++ b/translations/nikola.messages/nb.po
@@ -7,15 +7,16 @@
# Translators:
# Translators:
# Translators:
+# Daniel Aleksandersen <code@daniel.priv.no>, 2015
# Daniel <i18n@daniel.priv.no>, 2013
msgid ""
msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Norwegian Bokmål (http://www.transifex.com/projects/p/nikola/language/nb/)\n"
+"PO-Revision-Date: 2015-07-16 23:54+0000\n"
+"Last-Translator: Daniel Aleksandersen <code@daniel.priv.no>\n"
+"Language-Team: Norwegian Bokmål (http://www.transifex.com/p/nikola/language/nb/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -40,7 +41,7 @@ msgid "Tags and Categories"
msgstr "Merker og kategorier"
msgid "Comments"
-msgstr ""
+msgstr "Kommentarer"
msgid "Read more"
msgstr "Les mer"
@@ -78,7 +79,7 @@ msgid "Also available in:"
msgstr "Også tilgjengelig på:"
msgid "Languages:"
-msgstr ""
+msgstr "Språk:"
msgid "Original site"
msgstr "Opprinnelig side"
@@ -90,7 +91,7 @@ msgid "Archive"
msgstr "Arkiv"
msgid "Publication date"
-msgstr ""
+msgstr "Publiseringsdato"
msgid "Posted:"
msgstr "Publisert:"
@@ -99,34 +100,34 @@ msgid "Posts for {month} {year}"
msgstr "Innlegg fra {month} {year}"
msgid "Posts for {month} {day}, {year}"
-msgstr ""
+msgstr "Innlegg fra {day}. {month} {year}"
msgid "Nothing found."
-msgstr ""
+msgstr "Fant ingenting."
msgid "No posts found."
-msgstr ""
+msgstr "Fant ingen innlegg."
msgid "RSS feed"
-msgstr ""
+msgstr "RSS-nyhetskanal"
msgid "%d min remaining to read"
-msgstr ""
+msgstr "%d min gjenstår å lese"
msgid "Skip to main content"
-msgstr ""
+msgstr "Hopp til hovedinnholdet"
msgid "Subcategories:"
-msgstr ""
+msgstr "Underkategorier:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(aktiv)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "Skriv innlegget din her."
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "Skriv siden din her."
diff --git a/translations/nikola.messages/pa.po b/translations/nikola.messages/pa.po
new file mode 100644
index 0000000..b7352c9
--- /dev/null
+++ b/translations/nikola.messages/pa.po
@@ -0,0 +1,132 @@
+# Messages in Nikola
+# Copyright (C) 2012-2013
+# This file is distributed under the same license as the Nikola package.
+#
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# jasdeep <jsbhangra@gmail.com>, 2015
+msgid ""
+msgstr ""
+"Project-Id-Version: Nikola\n"
+"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
+"POT-Creation-Date: 2013-03-15 12:24-0300\n"
+"PO-Revision-Date: 2015-08-17 06:37+0000\n"
+"Last-Translator: jasdeep <jsbhangra@gmail.com>\n"
+"Language-Team: Panjabi (Punjabi) (http://www.transifex.com/ralsina/nikola/language/pa/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pa\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "More posts about %s"
+msgstr "%s ਬਾਰੇ ਹੋਰ ਲਿਖਤਾਂ"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "LANGUAGE"
+msgstr "ਅੰਗਰੇਜ਼ੀ"
+
+msgid "Tags"
+msgstr "ਟੈਗ"
+
+msgid "Categories"
+msgstr "ਸ਼੍ਰੇਣੀ"
+
+msgid "Tags and Categories"
+msgstr "ਟੈਗ ਅਤੇ ਸ਼੍ਰੇਣੀਆਂ"
+
+msgid "Comments"
+msgstr "ਟਿੱਪਣੀਆਂ"
+
+msgid "Read more"
+msgstr "ਹੋਰ ਪੜ੍ਹੋ"
+
+msgid "Posts about %s"
+msgstr "%s ਬਾਰੇ ਲਿਖਤਾਂ"
+
+msgid "Next post"
+msgstr "ਅਗਲੀ ਲਿਖਤ"
+
+msgid "old posts, page %d"
+msgstr "ਪੁਰਾਣੀਆਂ ਲਿਖਤਾਂ , ਸਫ਼ਾ %d"
+
+msgid "page %d"
+msgstr "ਸਫ਼ਾ %d"
+
+msgid "Source"
+msgstr "ਮੂਲ"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "Read in English"
+msgstr "ਅੰਗਰੇਜ਼ੀ ਵਿੱਚ ਪੜ੍ਹੋ"
+
+msgid "Posts for year %s"
+msgstr "ਸਾਲ %s ਦੀਆਂ ਲਿਖਤਾਂ"
+
+msgid "Newer posts"
+msgstr "ਨਵੀਆਂ ਲਿਖਤਾਂ"
+
+msgid "Previous post"
+msgstr "ਪਿਛਲੀ ਲਿਖਤ"
+
+msgid "Also available in:"
+msgstr "ਹੋਰ ਉਪਲਬਧ ਬੋਲੀਆਂ:"
+
+msgid "Languages:"
+msgstr "ਬੋਲੀਆਂ:"
+
+msgid "Original site"
+msgstr "ਅਸਲ ਸਾਈਟ"
+
+msgid "Older posts"
+msgstr "ਪੁਰਾਣੀਆਂ ਲਿਖਤਾਂ"
+
+msgid "Archive"
+msgstr "ਆਰਕਾਈਵ"
+
+msgid "Publication date"
+msgstr "ਛਪਾਈ ਦੀ ਤਰੀਕ"
+
+msgid "Posted:"
+msgstr "ਲਿਖਤ ਛਪੀ:"
+
+msgid "Posts for {month} {year}"
+msgstr "{month} {year} ਦੀਆਂ ਲਿਖਤਾਂ"
+
+msgid "Posts for {month} {day}, {year}"
+msgstr "{day} {month} {year} ਦੀਆਂ ਲਿਖਤਾਂ"
+
+msgid "Nothing found."
+msgstr "ਕੁਝ ਨਹੀਂ ਲੱਭਿਆ |"
+
+msgid "No posts found."
+msgstr "ਕੋਈ ਲਿਖਤ ਨਹੀਂ ਲੱਭੀ |"
+
+msgid "RSS feed"
+msgstr "ਆਰ ਐੱਸ ਐੱਸ ਫੀਡ"
+
+msgid "%d min remaining to read"
+msgstr "ਪੜਣ ਲਈ %d ਮਿੰਟ ਬਾਕੀ"
+
+msgid "Skip to main content"
+msgstr "ਮੁੱਖ ਸਮੱਗਰੀ ਵੱਲ ਜਾਓ"
+
+msgid "Subcategories:"
+msgstr "ਉਪਸ਼੍ਰੇਣੀਆਂ:"
+
+#. Used for active navigation links, for screen readers only
+msgid "(active)"
+msgstr "(ਚਲੰਤ)"
+
+#. Default content for a new post
+msgid "Write your post here."
+msgstr "ਆਪਣੀ ਲਿਖਤ ਏਥੇ ਲਿਖੋ |"
+
+#. Default content for a new page
+msgid "Write your page here."
+msgstr "ਆਪਣਾ ਸਫ਼ਾ ਏਥੇ ਲਿਖੋ |"
diff --git a/translations/nikola.messages/pt.po b/translations/nikola.messages/pt.po
index 89f803f..68a9711 100644
--- a/translations/nikola.messages/pt.po
+++ b/translations/nikola.messages/pt.po
@@ -7,14 +7,15 @@
# Translators:
# Translators:
# Translators:
+# jamatos <jamatos@fep.up.pt>, 2015
msgid ""
msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Portuguese (http://www.transifex.com/projects/p/nikola/language/pt/)\n"
+"PO-Revision-Date: 2015-07-15 09:30+0000\n"
+"Last-Translator: jamatos <jamatos@fep.up.pt>\n"
+"Language-Team: Portuguese (http://www.transifex.com/p/nikola/language/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -22,110 +23,110 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "More posts about %s"
-msgstr ""
+msgstr "Mais textos publicados sobre %s"
#. Here your translation should NOT say English but the name of your language
#. instead
msgid "LANGUAGE"
-msgstr ""
+msgstr "Português"
msgid "Tags"
-msgstr ""
+msgstr "Etiqueta"
msgid "Categories"
-msgstr ""
+msgstr "Categorias"
msgid "Tags and Categories"
-msgstr ""
+msgstr "Etiquetas e Categorias"
msgid "Comments"
-msgstr ""
+msgstr "Comentários"
msgid "Read more"
-msgstr ""
+msgstr "Ler mais"
msgid "Posts about %s"
-msgstr ""
+msgstr "Textos publicados sobre %s"
msgid "Next post"
-msgstr ""
+msgstr "Próximo texto publicado"
msgid "old posts, page %d"
-msgstr ""
+msgstr "Textos publicados antigos, página %d"
msgid "page %d"
-msgstr ""
+msgstr "página %d"
msgid "Source"
-msgstr ""
+msgstr "Código"
#. Here your translation should NOT say English but the name of your language
#. instead
msgid "Read in English"
-msgstr ""
+msgstr "Ler em português"
msgid "Posts for year %s"
-msgstr ""
+msgstr "Textos publicados do ano %s"
msgid "Newer posts"
-msgstr ""
+msgstr "Textos publicados mais recentes"
msgid "Previous post"
-msgstr ""
+msgstr "Texto publicado anterior"
msgid "Also available in:"
-msgstr ""
+msgstr "Também disponível em:"
msgid "Languages:"
-msgstr ""
+msgstr "Idiomas:"
msgid "Original site"
-msgstr ""
+msgstr "Sítio original"
msgid "Older posts"
-msgstr ""
+msgstr "Textos publicados mais antigos"
msgid "Archive"
-msgstr ""
+msgstr "Arquivo"
msgid "Publication date"
-msgstr ""
+msgstr "Data de publicação"
msgid "Posted:"
-msgstr ""
+msgstr "Publicado:"
msgid "Posts for {month} {year}"
-msgstr ""
+msgstr "Textos publicados de {month} {year}"
msgid "Posts for {month} {day}, {year}"
-msgstr ""
+msgstr "Textos publicados de {day} {month} {year}"
msgid "Nothing found."
-msgstr ""
+msgstr "Nada encontrado."
msgid "No posts found."
-msgstr ""
+msgstr "Nenhum texto publicado foi encontrado"
msgid "RSS feed"
-msgstr ""
+msgstr "Feed RSS"
msgid "%d min remaining to read"
-msgstr ""
+msgstr "%d minutos restante para leitura"
msgid "Skip to main content"
-msgstr ""
+msgstr "Saltar para o conteúdo principal"
msgid "Subcategories:"
-msgstr ""
+msgstr "Sub-Categorias:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(ativo)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "Escreva o seu texto para publicar aqui."
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "Escreva a sua página aqui."
diff --git a/translations/nikola.messages/sk.po b/translations/nikola.messages/sk.po
index cf10280..c061cea 100644
--- a/translations/nikola.messages/sk.po
+++ b/translations/nikola.messages/sk.po
@@ -8,15 +8,16 @@
# Translators:
# Translators:
# bs_ <info@pwn.sk>, 2014
+# Michal Kaukic <misolietavec@gmail.com>, 2015
# Michal Petrucha <michal.petrucha@ksp.sk>, 2014
msgid ""
msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Slovak (http://www.transifex.com/projects/p/nikola/language/sk/)\n"
+"PO-Revision-Date: 2015-07-14 10:25+0000\n"
+"Last-Translator: Michal Kaukic <misolietavec@gmail.com>\n"
+"Language-Team: Slovak (http://www.transifex.com/p/nikola/language/sk/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -100,7 +101,7 @@ msgid "Posts for {month} {year}"
msgstr "Príspevky za mesiac {month} z roku {year}"
msgid "Posts for {month} {day}, {year}"
-msgstr "Príspevky z dňa {day}. {month} {year}"
+msgstr "Príspevky zo dňa {day}. {month} {year}"
msgid "Nothing found."
msgstr "Nič nenájdené."
@@ -118,16 +119,16 @@ msgid "Skip to main content"
msgstr "Skočiť na hlavný obsah"
msgid "Subcategories:"
-msgstr ""
+msgstr "Podkategórie:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(aktívne)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "Tu napíšte svoj príspevok."
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "Tu napíšte svoju stránku."
diff --git a/translations/nikola.messages/sr.po b/translations/nikola.messages/sr.po
index 6a335a9..ae81540 100644
--- a/translations/nikola.messages/sr.po
+++ b/translations/nikola.messages/sr.po
@@ -8,14 +8,15 @@
# Translators:
# Translators:
# Ivan Radeljic <radeljicivan85@gmail.com>, 2014
+# Saša Savić <sasa.savic@protonmail.com>, 2015
msgid ""
msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Serbian (http://www.transifex.com/projects/p/nikola/language/sr/)\n"
+"PO-Revision-Date: 2015-07-30 17:40+0000\n"
+"Last-Translator: Saša Savić <sasa.savic@protonmail.com>\n"
+"Language-Team: Serbian (http://www.transifex.com/ralsina/nikola/language/sr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -99,7 +100,7 @@ msgid "Posts for {month} {year}"
msgstr "Постови за {month} {year}"
msgid "Posts for {month} {day}, {year}"
-msgstr ""
+msgstr "Објаве за {month} {day}, {year}"
msgid "Nothing found."
msgstr "Није ништа пронађено."
@@ -117,16 +118,16 @@ msgid "Skip to main content"
msgstr "Прескочи на главни садржај"
msgid "Subcategories:"
-msgstr ""
+msgstr "Подкатегорије:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(активно)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "Вашу објаву напишите овдје."
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "Вашу страницу напишите овдје."
diff --git a/translations/nikola.messages/sr@latin.po b/translations/nikola.messages/sr@latin.po
new file mode 100644
index 0000000..240b68b
--- /dev/null
+++ b/translations/nikola.messages/sr@latin.po
@@ -0,0 +1,132 @@
+# Messages in Nikola
+# Copyright (C) 2012-2013
+# This file is distributed under the same license as the Nikola package.
+#
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# Translators:
+# Saša Savić <sasa.savic@protonmail.com>, 2015
+msgid ""
+msgstr ""
+"Project-Id-Version: Nikola\n"
+"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
+"POT-Creation-Date: 2013-03-15 12:24-0300\n"
+"PO-Revision-Date: 2015-07-30 18:51+0000\n"
+"Last-Translator: Saša Savić <sasa.savic@protonmail.com>\n"
+"Language-Team: Serbian (Latin) (http://www.transifex.com/ralsina/nikola/language/sr@latin/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sr@latin\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgid "More posts about %s"
+msgstr "Više objava o %s"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "LANGUAGE"
+msgstr "Bosanski"
+
+msgid "Tags"
+msgstr "Oznake"
+
+msgid "Categories"
+msgstr "Kategorije"
+
+msgid "Tags and Categories"
+msgstr "Oznake i kategorije"
+
+msgid "Comments"
+msgstr "Komentari"
+
+msgid "Read more"
+msgstr "Pročitaj više"
+
+msgid "Posts about %s"
+msgstr "Objave o %s"
+
+msgid "Next post"
+msgstr "Naredna objava"
+
+msgid "old posts, page %d"
+msgstr "stare objave, strana %d"
+
+msgid "page %d"
+msgstr "strana %d"
+
+msgid "Source"
+msgstr "Izvor"
+
+#. Here your translation should NOT say English but the name of your language
+#. instead
+msgid "Read in English"
+msgstr "Pročitaj na bosanskom"
+
+msgid "Posts for year %s"
+msgstr "Objave u godini %s"
+
+msgid "Newer posts"
+msgstr "Novije objave"
+
+msgid "Previous post"
+msgstr "Prethodne objave"
+
+msgid "Also available in:"
+msgstr "Takođe dostupan u:"
+
+msgid "Languages:"
+msgstr "Jezici:"
+
+msgid "Original site"
+msgstr "Izvorni sajt"
+
+msgid "Older posts"
+msgstr "Starije objave"
+
+msgid "Archive"
+msgstr "Arhiva"
+
+msgid "Publication date"
+msgstr "Datum objavljivanja"
+
+msgid "Posted:"
+msgstr "Objavljeno:"
+
+msgid "Posts for {month} {year}"
+msgstr "Objave za {month} {year}"
+
+msgid "Posts for {month} {day}, {year}"
+msgstr "Objave za {month} {day}, {year}"
+
+msgid "Nothing found."
+msgstr "Ništa nije pronađeno."
+
+msgid "No posts found."
+msgstr "Nema objava."
+
+msgid "RSS feed"
+msgstr "RSS feed"
+
+msgid "%d min remaining to read"
+msgstr "%d minuta preostalo za čitanje"
+
+msgid "Skip to main content"
+msgstr "Preskoči na glavni sadržaj"
+
+msgid "Subcategories:"
+msgstr "Podkategorije:"
+
+#. Used for active navigation links, for screen readers only
+msgid "(active)"
+msgstr "(aktivno)"
+
+#. Default content for a new post
+msgid "Write your post here."
+msgstr "Vašu objavu napišite ovdje."
+
+#. Default content for a new page
+msgid "Write your page here."
+msgstr "Vašu stranicu napišite ovdje."
diff --git a/translations/nikola.messages/sv.po b/translations/nikola.messages/sv.po
index 07cc478..1c8d770 100644
--- a/translations/nikola.messages/sv.po
+++ b/translations/nikola.messages/sv.po
@@ -15,9 +15,9 @@ msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
-"Language-Team: Swedish (http://www.transifex.com/projects/p/nikola/language/sv/)\n"
+"PO-Revision-Date: 2015-08-08 08:53+0000\n"
+"Last-Translator: Markus Edemalm <markus@edemalm.se>\n"
+"Language-Team: Swedish (http://www.transifex.com/ralsina/nikola/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -25,7 +25,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "More posts about %s"
-msgstr "Mer inlägg om %s"
+msgstr "Fler inlägg om %s"
#. Here your translation should NOT say English but the name of your language
#. instead
@@ -65,7 +65,7 @@ msgstr "Källa"
#. Here your translation should NOT say English but the name of your language
#. instead
msgid "Read in English"
-msgstr "Läs på Svenska"
+msgstr "Läs på svenska"
msgid "Posts for year %s"
msgstr "Inlägg för år %s"
@@ -83,7 +83,7 @@ msgid "Languages:"
msgstr "Språk:"
msgid "Original site"
-msgstr "Orgnialsida"
+msgstr "Originalsida"
msgid "Older posts"
msgstr "Äldre inlägg"
@@ -95,7 +95,7 @@ msgid "Publication date"
msgstr "Publiceringsdatum"
msgid "Posted:"
-msgstr "Publicerad"
+msgstr "Publicerad:"
msgid "Posts for {month} {year}"
msgstr "Inlägg för {month} {year}"
@@ -104,31 +104,31 @@ msgid "Posts for {month} {day}, {year}"
msgstr "Inlägg för {month} {day}, {year}"
msgid "Nothing found."
-msgstr "Inget hittat"
+msgstr "Inget hittat."
msgid "No posts found."
-msgstr "Inga inlägg hittade"
+msgstr "Inga inlägg hittade."
msgid "RSS feed"
-msgstr "RSS flöde"
+msgstr "RSS-flöde"
msgid "%d min remaining to read"
msgstr "%d minuter kvar att läsa"
msgid "Skip to main content"
-msgstr "hoppa till huvudinehåll"
+msgstr "Hoppa till huvudinnehåll"
msgid "Subcategories:"
msgstr "Underkategorier:"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(aktiv)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "Skriv ditt inlägg här."
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "Skriv din sida här."
diff --git a/translations/nikola.messages/ur.po b/translations/nikola.messages/ur.po
index 3add26e..959d549 100644
--- a/translations/nikola.messages/ur.po
+++ b/translations/nikola.messages/ur.po
@@ -17,8 +17,8 @@ msgstr ""
"Project-Id-Version: Nikola\n"
"Report-Msgid-Bugs-To: ralsina@netmanagers.com.ar\n"
"POT-Creation-Date: 2013-03-15 12:24-0300\n"
-"PO-Revision-Date: 2015-06-24 12:06+0000\n"
-"Last-Translator: Chris Warrick <kwpolska@gmail.com>\n"
+"PO-Revision-Date: 2015-07-03 03:21+0000\n"
+"Last-Translator: Saadat M. <saadat@saadatmand.pk>\n"
"Language-Team: Urdu (http://www.transifex.com/projects/p/nikola/language/ur/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -125,12 +125,12 @@ msgstr "ذیلی زمرے"
#. Used for active navigation links, for screen readers only
msgid "(active)"
-msgstr ""
+msgstr "(فعال)"
#. Default content for a new post
msgid "Write your post here."
-msgstr ""
+msgstr "اپنی تحریر یہاں لکھیں۔"
#. Default content for a new page
msgid "Write your page here."
-msgstr ""
+msgstr "اپنے صفحے کا متن یہاں لکھیں۔"