Feat: import work and verify compilation
This commit is contained in:
parent
1ad81faabe
commit
5b475a2f38
46
Makefile
46
Makefile
@ -2,13 +2,13 @@ PY?=python3
|
||||
PELICAN?=pelican
|
||||
PELICANOPTS=
|
||||
|
||||
YEARSUBFOLDER=enseignements/2019-2020/
|
||||
|
||||
YEARSUBFOLDER=enseignements/DEV/
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
FAKEDIR=../../output/
|
||||
|
||||
FTP_HOST=localhost
|
||||
@ -20,11 +20,17 @@ SSH_CONF=Embrevade
|
||||
#SSH_TARGET_DIR=/var/docker/opytex.org/www/
|
||||
SSH_TARGET_DIR=/home/sshcontent/opytex.org/www/$(YEARSUBFOLDER)
|
||||
|
||||
|
||||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
PELICANOPTS += -D
|
||||
endif
|
||||
|
||||
RELATIVE ?= 0
|
||||
ifeq ($(RELATIVE), 1)
|
||||
PELICANOPTS += --relative-urls
|
||||
endif
|
||||
|
||||
help:
|
||||
@echo 'Makefile for a pelican Web site '
|
||||
@echo ' '
|
||||
@ -34,20 +40,17 @@ help:
|
||||
@echo ' make regenerate regenerate files upon modification '
|
||||
@echo ' make publish generate using production settings '
|
||||
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
||||
@echo ' make devserver [PORT=8000] start/restart develop_server.sh '
|
||||
@echo ' make stopserver stop local server '
|
||||
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
||||
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
||||
@echo ' make ssh_upload upload the web site via SSH '
|
||||
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
||||
@echo ' make dropbox_upload upload the web site via Dropbox '
|
||||
@echo ' make ftp_upload upload the web site via FTP '
|
||||
@echo ' make s3_upload upload the web site via S3 '
|
||||
@echo ' make cf_upload upload the web site via Cloud Files'
|
||||
@echo ' make github upload the web site via gh-pages '
|
||||
@echo ' '
|
||||
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
||||
@echo 'Set the RELATIVE variable to 1 to enable relative urls '
|
||||
@echo ' '
|
||||
|
||||
html:
|
||||
lessc $(BASEDIR)/theme/static/stylesheet/style.less $(BASEDIR)/theme/static/stylesheet/style.min.css -x
|
||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
|
||||
clean:
|
||||
@ -58,28 +61,29 @@ regenerate:
|
||||
|
||||
serve:
|
||||
ifdef PORT
|
||||
cd $(OUTPUTDIR) && $(PY) -m pelican.server $(PORT)
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT)
|
||||
else
|
||||
cd $(OUTPUTDIR) && $(PY) -m pelican.server
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
endif
|
||||
|
||||
serve-global:
|
||||
ifdef SERVER
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b $(SERVER)
|
||||
else
|
||||
$(PELICAN) -l $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT) -b 0.0.0.0
|
||||
endif
|
||||
|
||||
|
||||
devserver:
|
||||
ifdef PORT
|
||||
$(BASEDIR)/develop_server.sh restart $(PORT)
|
||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -p $(PORT)
|
||||
else
|
||||
$(BASEDIR)/develop_server.sh restart
|
||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
endif
|
||||
|
||||
stopserver:
|
||||
kill -9 `cat pelican.pid`
|
||||
kill -9 `cat srv.pid`
|
||||
@echo 'Stopped Pelican and SimpleHTTPServer processes running in background.'
|
||||
|
||||
publish:
|
||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)
|
||||
|
||||
ssh_upload: publish
|
||||
scp -r $(OUTPUTDIR)/* $(SSH_CONF):$(SSH_TARGET_DIR)
|
||||
|
||||
rsync_upload: publish
|
||||
#rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
|
||||
@ -89,4 +93,4 @@ fake_upload: html
|
||||
mkdir -p $(FAKEDIR)$(YEARSUBFOLDER)
|
||||
rsync -P -rvzc --delete $(OUTPUTDIR)/ $(FAKEDIR)$(YEARSUBFOLDER) --cvs-exclude
|
||||
|
||||
.PHONY: html help clean regenerate serve devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github import_ens
|
||||
.PHONY: html help clean regenerate serve serve-global devserver publish rsync_upload fake_upload
|
||||
|
@ -1,6 +0,0 @@
|
||||
Site Opytex
|
||||
###########
|
||||
|
||||
- Soucis avec ImageMagick et la conversion vers pdf (pdf-img plugin)
|
||||
|
||||
https://stackoverflow.com/questions/52998331/imagemagick-security-policy-pdf-blocking-conversion
|
@ -1,103 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# This section should match your Makefile
|
||||
##
|
||||
PY=${PY:-python3}
|
||||
PELICAN=${PELICAN:-pelican}
|
||||
PELICANOPTS=
|
||||
|
||||
BASEDIR=$(pwd)
|
||||
INPUTDIR=$BASEDIR/content
|
||||
OUTPUTDIR=$BASEDIR/output
|
||||
CONFFILE=$BASEDIR/pelicanconf.py
|
||||
|
||||
###
|
||||
# Don't change stuff below here unless you are sure
|
||||
###
|
||||
|
||||
SRV_PID=$BASEDIR/srv.pid
|
||||
PELICAN_PID=$BASEDIR/pelican.pid
|
||||
|
||||
function usage(){
|
||||
echo "usage: $0 (stop) (start) (restart) [port]"
|
||||
echo "This starts Pelican in debug and reload mode and then launches"
|
||||
echo "an HTTP server to help site development. It doesn't read"
|
||||
echo "your Pelican settings, so if you edit any paths in your Makefile"
|
||||
echo "you will need to edit your settings as well."
|
||||
exit 3
|
||||
}
|
||||
|
||||
function alive() {
|
||||
kill -0 $1 >/dev/null 2>&1
|
||||
}
|
||||
|
||||
function shut_down(){
|
||||
PID=$(cat $SRV_PID)
|
||||
if [[ $? -eq 0 ]]; then
|
||||
if alive $PID; then
|
||||
echo "Stopping HTTP server"
|
||||
kill $PID
|
||||
else
|
||||
echo "Stale PID, deleting"
|
||||
fi
|
||||
rm $SRV_PID
|
||||
else
|
||||
echo "HTTP server PIDFile not found"
|
||||
fi
|
||||
|
||||
PID=$(cat $PELICAN_PID)
|
||||
if [[ $? -eq 0 ]]; then
|
||||
if alive $PID; then
|
||||
echo "Killing Pelican"
|
||||
kill $PID
|
||||
else
|
||||
echo "Stale PID, deleting"
|
||||
fi
|
||||
rm $PELICAN_PID
|
||||
else
|
||||
echo "Pelican PIDFile not found"
|
||||
fi
|
||||
}
|
||||
|
||||
function start_up(){
|
||||
local port=$1
|
||||
echo "Starting up Pelican and HTTP server"
|
||||
shift
|
||||
$PELICAN --debug --autoreload -r $INPUTDIR -o $OUTPUTDIR -s $CONFFILE $PELICANOPTS &
|
||||
pelican_pid=$!
|
||||
echo $pelican_pid > $PELICAN_PID
|
||||
cd $OUTPUTDIR
|
||||
$PY -m pelican.server $port &
|
||||
srv_pid=$!
|
||||
echo $srv_pid > $SRV_PID
|
||||
cd $BASEDIR
|
||||
sleep 1
|
||||
if ! alive $pelican_pid ; then
|
||||
echo "Pelican didn't start. Is the Pelican package installed?"
|
||||
return 1
|
||||
elif ! alive $srv_pid ; then
|
||||
echo "The HTTP server didn't start. Is there another service using port" $port "?"
|
||||
return 1
|
||||
fi
|
||||
echo 'Pelican and HTTP server processes now running in background.'
|
||||
}
|
||||
|
||||
###
|
||||
# MAIN
|
||||
###
|
||||
[[ ($# -eq 0) || ($# -gt 2) ]] && usage
|
||||
port=''
|
||||
[[ $# -eq 2 ]] && port=$2
|
||||
|
||||
if [[ $1 == "stop" ]]; then
|
||||
shut_down
|
||||
elif [[ $1 == "restart" ]]; then
|
||||
shut_down
|
||||
start_up $port
|
||||
elif [[ $1 == "start" ]]; then
|
||||
if ! start_up $port; then
|
||||
shut_down
|
||||
fi
|
||||
else
|
||||
usage
|
||||
fi
|
73
fabfile.py
vendored
73
fabfile.py
vendored
@ -1,73 +0,0 @@
|
||||
from fabric.api import *
|
||||
import fabric.contrib.project as project
|
||||
import os
|
||||
import sys
|
||||
import SimpleHTTPServer
|
||||
import SocketServer
|
||||
|
||||
# Local path configuration (can be absolute or relative to fabfile)
|
||||
env.deploy_path = 'output'
|
||||
DEPLOY_PATH = env.deploy_path
|
||||
|
||||
# Remote server configuration
|
||||
production = 'root@localhost:22'
|
||||
dest_path = '/var/www'
|
||||
|
||||
# Rackspace Cloud Files configuration settings
|
||||
env.cloudfiles_username = 'my_rackspace_username'
|
||||
env.cloudfiles_api_key = 'my_rackspace_api_key'
|
||||
env.cloudfiles_container = 'my_cloudfiles_container'
|
||||
|
||||
|
||||
def clean():
|
||||
if os.path.isdir(DEPLOY_PATH):
|
||||
local('rm -rf {deploy_path}'.format(**env))
|
||||
local('mkdir {deploy_path}'.format(**env))
|
||||
|
||||
def build():
|
||||
local('pelican -s pelicanconf.py')
|
||||
|
||||
def rebuild():
|
||||
clean()
|
||||
build()
|
||||
|
||||
def regenerate():
|
||||
local('pelican -r -s pelicanconf.py')
|
||||
|
||||
def serve():
|
||||
os.chdir(env.deploy_path)
|
||||
|
||||
PORT = 8000
|
||||
class AddressReuseTCPServer(SocketServer.TCPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
server = AddressReuseTCPServer(('', PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
|
||||
|
||||
sys.stderr.write('Serving on port {0} ...\n'.format(PORT))
|
||||
server.serve_forever()
|
||||
|
||||
def reserve():
|
||||
build()
|
||||
serve()
|
||||
|
||||
def preview():
|
||||
local('pelican -s publishconf.py')
|
||||
|
||||
def cf_upload():
|
||||
rebuild()
|
||||
local('cd {deploy_path} && '
|
||||
'swift -v -A https://auth.api.rackspacecloud.com/v1.0 '
|
||||
'-U {cloudfiles_username} '
|
||||
'-K {cloudfiles_api_key} '
|
||||
'upload -c {cloudfiles_container} .'.format(**env))
|
||||
|
||||
@hosts(production)
|
||||
def publish():
|
||||
local('pelican -s publishconf.py')
|
||||
project.rsync_project(
|
||||
remote_dir=dest_path,
|
||||
exclude=".DS_Store",
|
||||
local_dir=DEPLOY_PATH.rstrip('/') + '/',
|
||||
delete=True,
|
||||
extra_opts='-c',
|
||||
)
|
5
notes
5
notes
@ -1,5 +0,0 @@
|
||||
# Importer tous les fichier rst
|
||||
rsync -rv --del --exclude 'Archive' --exclude 'tools/skeleton' --exclude 'tools/Other' --include '*/' --include '*.rst' --exclude '*' --prune-empty-dirs /media/documents/Cours/Prof/Enseignements content/Cours/
|
||||
|
||||
# Ajouter une nouvelle année
|
||||
Éditer pelicanconf.py pour ajouter une entrée dans links
|
@ -1 +0,0 @@
|
||||
Subproject commit 5c5f965c984d9cb9324c1c7b251d448992c4bda5
|
100
pelicanconf.py
100
pelicanconf.py
@ -9,8 +9,8 @@ from globalconf import *
|
||||
AUTHOR = 'Benjamin Bertrand'
|
||||
SITENAME = 'OpyTex'
|
||||
SITETITLE = 'OpyTex'
|
||||
SITESUBTITLE = "2019-2020"
|
||||
SITEURL = ''
|
||||
SITESUBTITLE = "DEV"
|
||||
SITEURL = 'localhost:8000/enseignements/DEV/'
|
||||
|
||||
CC_LICENSE_COMMERCIAL = True
|
||||
CC_LICENSE = True
|
||||
@ -21,73 +21,59 @@ TIMEZONE = 'Europe/Paris'
|
||||
|
||||
DEFAULT_LANG = 'fr'
|
||||
|
||||
# theme
|
||||
THEME = "./theme/"
|
||||
USE_GOOGLE_FONTS = False
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
#RELATIVE_URLS = True
|
||||
|
||||
IGNORE_FILES = ['venv', '.git', 'tools']
|
||||
# Pages, articles and static
|
||||
PAGE_PATHS = ['pages']
|
||||
#ARTICLE_PATHS = ['pages/Enseignement', 'Blog']
|
||||
# Files places
|
||||
IGNORE_FILES = ['venv']
|
||||
#PAGE_PATHS = ['pages']
|
||||
ARTICLE_PATHS = ['.']
|
||||
STATIC_PATHS = ['.']
|
||||
|
||||
INDEX_SAVE_AS = 'blog_index.html'
|
||||
|
||||
#
|
||||
USE_FOLDER_AS_CATEGORY = False
|
||||
|
||||
# Plugins
|
||||
PLUGIN_PATHS = ["plugins"]
|
||||
PLUGINS = [
|
||||
'i18n_subsites',
|
||||
"pelican-page-hierarchy",
|
||||
# 'pdf-img',
|
||||
]
|
||||
|
||||
# Mirror source structure
|
||||
PATH_METADATA = '(?P<path_no_ext>.*)\..*'
|
||||
ARTICLE_URL = ARTICLE_SAVE_AS = PAGE_URL = PAGE_SAVE_AS = '{path_no_ext}.html'
|
||||
|
||||
# Readers
|
||||
READERS = {"html": None}
|
||||
|
||||
# Themes
|
||||
THEME = "theme"
|
||||
|
||||
# Everythings in french
|
||||
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
|
||||
# Default theme language.
|
||||
I18N_TEMPLATES_LANG = "en"
|
||||
# Your language.
|
||||
DEFAULT_LANG = "fr"
|
||||
OG_LOCALE = "fr"
|
||||
LOCALE = ("fr", "fr_FR.utf8")
|
||||
|
||||
DISPLAY_PAGES_ON_SIDE = False
|
||||
|
||||
MAIN_MENU = True
|
||||
DISPLAY_CATEGORIES_ON_MENU = False
|
||||
TOCTREE = True
|
||||
|
||||
#SITELOGO = ""
|
||||
LINKS = ()
|
||||
DEFAULT_PAGINATION = 10
|
||||
|
||||
# Feed generation is usually not desired when developing
|
||||
FEED_ALL_ATOM = None
|
||||
CATEGORY_FEED_ATOM = None
|
||||
TRANSLATION_FEED_ATOM = None
|
||||
AUTHOR_FEED_ATOM = None
|
||||
AUTHOR_FEED_RSS = None
|
||||
|
||||
# Blogroll
|
||||
LINKS = (
|
||||
#('2019/2020', "/Enseignements/2019-2020/"),
|
||||
#('2018/2019', "/Enseignements/2018-2019/"),
|
||||
#('2017/2018', "/Enseignements/2017-2018/"),
|
||||
#('2016/2017', "/Enseignements/2016-2017/"),
|
||||
#('2015/2016', "/Enseignements/2015-2016/"),
|
||||
)
|
||||
|
||||
# Social widget
|
||||
#SOCIAL = (('You can add links in your config file', '#'),
|
||||
# )
|
||||
|
||||
DEFAULT_PAGINATION = 20
|
||||
|
||||
# Date
|
||||
SHOW_DATE_MODIFIED = True
|
||||
ARTICLE_ORDER_BY = "modified"
|
||||
|
||||
DISPLAY_ARTICLE_INFO_ON_INDEX = True
|
||||
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
RELATIVE_URLS = True
|
||||
|
||||
BOOTSTRAP_THEME = "flatly"
|
||||
PLUGIN_PATHS = ['./plugins', './pelican-plugins']
|
||||
|
||||
PLUGINS = [#'hierarchy',
|
||||
'tag_cloud',
|
||||
"list_files",
|
||||
"render_math",
|
||||
"always_modified",
|
||||
"pdf-img",
|
||||
]
|
||||
|
||||
READERS = {"html": None}
|
||||
|
||||
# hierarchy plugin config
|
||||
# ARTICLE_URL = 'Enseignements/{slug}/'
|
||||
# ARTICLE_SAVE_AS = 'Enseignements/{slug}/index.html'
|
||||
# #SLUGIFY_SOURCE = 'basename'
|
||||
# ARTICLE_NAVIGATION = True
|
||||
|
||||
TAGS_URL = "tags.html"
|
||||
DISPLAY_TAGS_INLINE = True
|
||||
DISPLAY_CATEGORIES_ON_SIDEBAR = True
|
||||
|
@ -1,75 +0,0 @@
|
||||
Page Hierarchy
|
||||
==============
|
||||
*Author: Ahmad Khayyat (<akhayyat@gmail.com>)*
|
||||
|
||||
A [Pelican][1] plugin that creates a URL hierarchy for pages that
|
||||
matches the filesystem hierarchy of their sources.
|
||||
|
||||
For example, to have the following filesystem structure of page
|
||||
sources result in the URLs listed next to each file,
|
||||
|
||||
```text
|
||||
└── content/pages/ # PAGE_DIR
|
||||
├── about.md # URL: pages/about/
|
||||
├── projects.md # URL: pages/projects/
|
||||
├── projects/ # (directory)
|
||||
│ ├── p1.md # URL: pages/projects/p1/
|
||||
│ ├── p2.md # URL: pages/projects/p2/
|
||||
│ └── p2/ # (directory)
|
||||
│ └── features.md # URL: pages/projects/p2/features/
|
||||
└── contact.md # URL: pages/contact/
|
||||
```
|
||||
|
||||
you can use this plugin with the following Pelican settings:
|
||||
|
||||
```python
|
||||
# pelicanconf.py
|
||||
PAGE_URL = '{slug}/'
|
||||
PAGE_SAVE_AS = '{slug}/index.html'
|
||||
SLUGIFY_SOURCE = 'basename'
|
||||
```
|
||||
|
||||
When generating the `url` and `save_as` attributes, the plugin
|
||||
prefixes the page's `slug` by its relative path. Although the initial
|
||||
`slug` is generated from the page's `title` by default, it can be
|
||||
generated from the source file basename by setting the
|
||||
`SLUGIFY_SOURCE` setting to `'basename'`, as shown in the settings
|
||||
snippet above. The `slug` can also be set using [`PATH_METADATA`][2].
|
||||
|
||||
This plugin is compatible with [Pelican translations][3].
|
||||
|
||||
Parent and Children Pages
|
||||
-------------------------
|
||||
This plugin also adds three attributes to each page object:
|
||||
|
||||
- `parent`: the immediate parent page. `None` if the page is
|
||||
top-level. If a translated page has no parent, the default-language
|
||||
parent is used.
|
||||
|
||||
- `parents`: a list of all ancestor pages, starting from the top-level
|
||||
ancestor.
|
||||
|
||||
- `children`: a list of all immediate child pages, in no specific
|
||||
order.
|
||||
|
||||
These attributes can be used to generate breadcrumbs or nested
|
||||
navigation menus. For example, this is a template excerpt for
|
||||
breadcrumbs:
|
||||
|
||||
```html
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="{{ SITEURL }}/" title="{{ SITENAME }}">
|
||||
<i class="fa fa-home fa-lg"></i>
|
||||
</a></li>
|
||||
{% for parent in page.parents %}
|
||||
<li><a href="{{ SITEURL }}/{{ parent.url }}">{{ parent.title }}</a></li>
|
||||
{% endfor %}
|
||||
<li class="active">{{ page.title }}</li>
|
||||
</ul>
|
||||
|
||||
```
|
||||
|
||||
|
||||
[1]: http://getpelican.com/
|
||||
[2]: http://docs.getpelican.com/en/latest/settings.html#path-metadata
|
||||
[3]: http://docs.getpelican.com/en/latest/settings.html#translations
|
@ -1,2 +0,0 @@
|
||||
#from .page_hierarchy import *
|
||||
from .article_hierarchy import *
|
@ -1,88 +0,0 @@
|
||||
from pelican import signals, contents
|
||||
import os.path
|
||||
from copy import copy
|
||||
from itertools import chain
|
||||
|
||||
'''
|
||||
This plugin creates a URL hierarchy for articles that matches the
|
||||
directory hierarchy of their sources.
|
||||
'''
|
||||
|
||||
class UnexpectedException(Exception): pass
|
||||
|
||||
def get_path(article, settings):
|
||||
''' Return the dirname relative to ARTICLE_PATHS prefix. '''
|
||||
path = os.path.split(article.get_relative_source_path())[0] + '/'
|
||||
path = path.replace( os.path.sep, '/' )
|
||||
# Try to lstrip the longest prefix first
|
||||
for prefix in sorted(settings['ARTICLE_PATHS'], key=len, reverse=True):
|
||||
if not prefix.endswith('/'): prefix += '/'
|
||||
if path.startswith(prefix):
|
||||
return path[len(prefix):-1]
|
||||
raise UnexpectedException('Article outside of ARTICLE_PATHS ?!?')
|
||||
|
||||
def in_default_lang(article):
|
||||
# article.in_default_lang property is undocumented (=unstable) interface
|
||||
return article.lang == article.settings['DEFAULT_LANG']
|
||||
|
||||
def override_metadata(content_object):
|
||||
if type(content_object) is not contents.Article:
|
||||
return
|
||||
article = content_object
|
||||
path = get_path(article, article.settings)
|
||||
|
||||
def _override_value(article, key):
|
||||
metadata = copy(article.metadata)
|
||||
# We override the slug to include the path up to the filename
|
||||
#metadata['slug'] = os.path.join(path, article.slug)
|
||||
metadata['slug'] = path
|
||||
# We have to account for non-default language and format either,
|
||||
# e.g., ARTICLE_SAVE_AS or ARTICLE_LANG_SAVE_AS
|
||||
#infix = '' if in_default_lang(article) else 'LANG_'
|
||||
infix = ''
|
||||
return article.settings['ARTICLE_' + infix + key.upper()].format(**metadata)
|
||||
|
||||
for key in ('save_as', 'url'):
|
||||
if not hasattr(article, 'override_' + key):
|
||||
setattr(article, 'override_' + key, _override_value(article, key))
|
||||
|
||||
def set_relationships(generator):
|
||||
def _all_articles():
|
||||
return chain(generator.articles, generator.translations)
|
||||
|
||||
# initialize parents and children lists
|
||||
for article in _all_articles():
|
||||
article.parent = None
|
||||
article.parents = []
|
||||
article.children = []
|
||||
|
||||
# set immediate parents and children
|
||||
for article in _all_articles():
|
||||
# Parent of /a/b/ is /a/, parent of /a/b.html is /a/
|
||||
parent_url = os.path.dirname(article.url[:-1])
|
||||
if parent_url: parent_url += '/'
|
||||
for article2 in _all_articles():
|
||||
if article2.url == parent_url and article2 != article:
|
||||
article.parent = article2
|
||||
article2.children.append(article)
|
||||
# If no parent found, try the parent of the default language article
|
||||
#if not article.parent and not in_default_lang(article):
|
||||
if not article.parent:
|
||||
for article2 in generator.articles:
|
||||
if (article.slug == article2.slug and
|
||||
os.path.dirname(article.source_path) ==
|
||||
os.path.dirname(article2.source_path)):
|
||||
# Only set the parent but not the children, obviously
|
||||
article.parent = article2.parent
|
||||
|
||||
# set all parents (ancestors)
|
||||
for article in _all_articles():
|
||||
p = article
|
||||
while p.parent:
|
||||
article.parents.insert(0, p.parent)
|
||||
p = p.parent
|
||||
|
||||
|
||||
def register():
|
||||
signals.content_object_init.connect(override_metadata)
|
||||
signals.article_generator_finalized.connect(set_relationships)
|
@ -1,86 +0,0 @@
|
||||
from pelican import signals, contents
|
||||
import os.path
|
||||
from copy import copy
|
||||
from itertools import chain
|
||||
|
||||
'''
|
||||
This plugin creates a URL hierarchy for pages that matches the
|
||||
directory hierarchy of their sources.
|
||||
'''
|
||||
|
||||
class UnexpectedException(Exception): pass
|
||||
|
||||
def get_path(page, settings):
|
||||
''' Return the dirname relative to PAGE_PATHS prefix. '''
|
||||
path = os.path.split(page.get_relative_source_path())[0] + '/'
|
||||
path = path.replace( os.path.sep, '/' )
|
||||
# Try to lstrip the longest prefix first
|
||||
for prefix in sorted(settings['PAGE_PATHS'], key=len, reverse=True):
|
||||
if not prefix.endswith('/'): prefix += '/'
|
||||
if path.startswith(prefix):
|
||||
return path[len(prefix):-1]
|
||||
raise UnexpectedException('Page outside of PAGE_PATHS ?!?')
|
||||
|
||||
def in_default_lang(page):
|
||||
# page.in_default_lang property is undocumented (=unstable) interface
|
||||
return page.lang == page.settings['DEFAULT_LANG']
|
||||
|
||||
def override_metadata(content_object):
|
||||
if type(content_object) is not contents.Page:
|
||||
return
|
||||
page = content_object
|
||||
path = get_path(page, page.settings)
|
||||
|
||||
def _override_value(page, key):
|
||||
metadata = copy(page.metadata)
|
||||
# We override the slug to include the path up to the filename
|
||||
#metadata['slug'] = os.path.join(path, page.slug)
|
||||
metadata['slug'] = path
|
||||
# We have to account for non-default language and format either,
|
||||
# e.g., PAGE_SAVE_AS or PAGE_LANG_SAVE_AS
|
||||
infix = '' if in_default_lang(page) else 'LANG_'
|
||||
return page.settings['PAGE_' + infix + key.upper()].format(**metadata)
|
||||
|
||||
for key in ('save_as', 'url'):
|
||||
if not hasattr(page, 'override_' + key):
|
||||
setattr(page, 'override_' + key, _override_value(page, key))
|
||||
|
||||
def set_relationships(generator):
|
||||
def _all_pages():
|
||||
return chain(generator.pages, generator.translations)
|
||||
|
||||
# initialize parents and children lists
|
||||
for page in _all_pages():
|
||||
page.parent = None
|
||||
page.parents = []
|
||||
page.children = []
|
||||
|
||||
# set immediate parents and children
|
||||
for page in _all_pages():
|
||||
# Parent of /a/b/ is /a/, parent of /a/b.html is /a/
|
||||
parent_url = os.path.dirname(page.url[:-1])
|
||||
if parent_url: parent_url += '/'
|
||||
for page2 in _all_pages():
|
||||
if page2.url == parent_url and page2 != page:
|
||||
page.parent = page2
|
||||
page2.children.append(page)
|
||||
# If no parent found, try the parent of the default language page
|
||||
if not page.parent and not in_default_lang(page):
|
||||
for page2 in generator.pages:
|
||||
if (page.slug == page2.slug and
|
||||
os.path.dirname(page.source_path) ==
|
||||
os.path.dirname(page2.source_path)):
|
||||
# Only set the parent but not the children, obviously
|
||||
page.parent = page2.parent
|
||||
|
||||
# set all parents (ancestors)
|
||||
for page in _all_pages():
|
||||
p = page
|
||||
while p.parent:
|
||||
page.parents.insert(0, p.parent)
|
||||
p = p.parent
|
||||
|
||||
|
||||
def register():
|
||||
signals.content_object_init.connect(override_metadata)
|
||||
signals.page_generator_finalized.connect(set_relationships)
|
165
plugins/i18n_subsites/README.rst
Normal file
165
plugins/i18n_subsites/README.rst
Normal file
@ -0,0 +1,165 @@
|
||||
=======================
|
||||
I18N Sub-sites Plugin
|
||||
=======================
|
||||
|
||||
This plugin extends the translations functionality by creating
|
||||
internationalized sub-sites for the default site.
|
||||
|
||||
This plugin is designed for Pelican 3.4 and later.
|
||||
|
||||
What it does
|
||||
============
|
||||
|
||||
1. When the content of the main site is being generated, the settings
|
||||
are saved and the generation stops when content is ready to be
|
||||
written. While reading source files and generating content objects,
|
||||
the output queue is modified in certain ways:
|
||||
|
||||
- translations that will appear as native in a different (sub-)site
|
||||
will be removed
|
||||
- untranslated articles will be transformed to drafts if
|
||||
``I18N_UNTRANSLATED_ARTICLES`` is ``'hide'`` (default), removed if
|
||||
``'remove'`` or kept as they are if ``'keep'``.
|
||||
- untranslated pages will be transformed into hidden pages if
|
||||
``I18N_UNTRANSLATED_PAGES`` is ``'hide'`` (default), removed if
|
||||
``'remove'`` or kept as they are if ``'keep'``.''
|
||||
- additional content manipulation similar to articles and pages can
|
||||
be specified for custom generators in the ``I18N_GENERATOR_INFO``
|
||||
setting.
|
||||
|
||||
2. For each language specified in the ``I18N_SUBSITES`` dictionary the
|
||||
settings overrides are applied to the settings from the main site
|
||||
and a new sub-site is generated in the same way as with the main
|
||||
site until content is ready to be written.
|
||||
3. When all (sub-)sites are waiting for content writing, all removed
|
||||
contents, translations and static files are interlinked across the
|
||||
(sub-)sites.
|
||||
4. Finally, all the output is written.
|
||||
|
||||
Setting it up
|
||||
=============
|
||||
|
||||
For each extra used language code, a language-specific settings overrides
|
||||
dictionary must be given (but can be empty) in the ``I18N_SUBSITES`` dictionary
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PLUGINS = ['i18n_subsites', ...]
|
||||
|
||||
# mapping: language_code -> settings_overrides_dict
|
||||
I18N_SUBSITES = {
|
||||
'cz': {
|
||||
'SITENAME': 'Hezkej blog',
|
||||
}
|
||||
}
|
||||
|
||||
You must also have the following in your pelican configuration
|
||||
|
||||
.. code-block:: python
|
||||
JINJA_ENVIRONMENT = {
|
||||
'extensions': ['jinja2.ext.i18n'],
|
||||
}
|
||||
|
||||
|
||||
|
||||
Default and special overrides
|
||||
-----------------------------
|
||||
The settings overrides may contain arbitrary settings, however, there
|
||||
are some that are handled in a special way:
|
||||
|
||||
``SITEURL``
|
||||
Any overrides to this setting should ensure that there is some level
|
||||
of hierarchy between all (sub-)sites, because Pelican makes all URLs
|
||||
relative to ``SITEURL`` and the plugin can only cross-link between
|
||||
the sites using this hierarchy. For instance, with the main site
|
||||
``http://example.com`` a sub-site ``http://example.com/de`` will
|
||||
work, but ``http://de.example.com`` will not. If not overridden, the
|
||||
language code (the language identifier used in the ``lang``
|
||||
metadata) is appended to the main ``SITEURL`` for each sub-site.
|
||||
``OUTPUT_PATH``, ``CACHE_PATH``
|
||||
If not overridden, the language code is appended as with ``SITEURL``.
|
||||
Separate cache paths are required as parser results depend on the locale.
|
||||
``STATIC_PATHS``, ``THEME_STATIC_PATHS``
|
||||
If not overridden, they are set to ``[]`` and all links to static
|
||||
files are cross-linked to the main site.
|
||||
``THEME``, ``THEME_STATIC_DIR``
|
||||
If overridden, the logic with ``THEME_STATIC_PATHS`` does not apply.
|
||||
``DEFAULT_LANG``
|
||||
This should not be overridden as the plugin changes it to the
|
||||
language code of each sub-site to change what is perceived as translations.
|
||||
|
||||
Localizing templates
|
||||
--------------------
|
||||
|
||||
Most importantly, this plugin can use localized templates for each
|
||||
sub-site. There are two approaches to having the templates localized:
|
||||
|
||||
- You can set a different ``THEME`` override for each language in
|
||||
``I18N_SUBSITES``, e.g. by making a copy of a theme ``my_theme`` to
|
||||
``my_theme_lang`` and then editing the templates in the new
|
||||
localized theme. This approach means you don't have to deal with
|
||||
gettext ``*.po`` files, but it is harder to maintain over time.
|
||||
- You use only one theme and localize the templates using the
|
||||
`jinja2.ext.i18n Jinja2 extension
|
||||
<http://jinja.pocoo.org/docs/templates/#i18n>`_. For a kickstart
|
||||
read this `guide <./localizing_using_jinja2.rst>`_.
|
||||
|
||||
Additional context variables
|
||||
............................
|
||||
|
||||
It may be convenient to add language buttons to your theme in addition
|
||||
to the translation links of articles and pages. These buttons could,
|
||||
for example, point to the ``SITEURL`` of each (sub-)site. For this
|
||||
reason the plugin adds these variables to the template context:
|
||||
|
||||
``main_lang``
|
||||
The language of the main site — the original ``DEFAULT_LANG``
|
||||
``main_siteurl``
|
||||
The ``SITEURL`` of the main site — the original ``SITEURL``
|
||||
``lang_siteurls``
|
||||
An ordered dictionary, mapping all used languages to their
|
||||
``SITEURL``. The ``main_lang`` is the first key with ``main_siteurl``
|
||||
as the value. This dictionary is useful for implementing global
|
||||
language buttons that show the language of the currently viewed
|
||||
(sub-)site too.
|
||||
``extra_siteurls``
|
||||
An ordered dictionary, subset of ``lang_siteurls``, the current
|
||||
``DEFAULT_LANG`` of the rendered (sub-)site is not included, so for
|
||||
each (sub-)site ``set(extra_siteurls) == set(lang_siteurls) -
|
||||
set([DEFAULT_LANG])``. This dictionary is useful for implementing
|
||||
global language buttons that do not show the current language.
|
||||
``relpath_to_site``
|
||||
A function that returns a relative path from the first (sub-)site to
|
||||
the second (sub-)site where the (sub-)sites are identified by the
|
||||
language codes given as two arguments.
|
||||
|
||||
If you don't like the default ordering of the ordered dictionaries,
|
||||
use a Jinja2 filter to alter the ordering.
|
||||
|
||||
All the siteurls above are always absolute even in the case of
|
||||
``RELATIVE_URLS == True`` (it would be to complicated to replicate the
|
||||
Pelican internals for local siteurls), so you may rather use something
|
||||
like ``{{ SITEURL }}/{{ relpath_to_site(DEFAULT_LANG, main_lang }}``
|
||||
to link to the main site.
|
||||
|
||||
This short `howto <./implementing_language_buttons.rst>`_ shows two
|
||||
example implementations of language buttons.
|
||||
|
||||
Usage notes
|
||||
===========
|
||||
- It is **mandatory** to specify ``lang`` metadata for each article
|
||||
and page as ``DEFAULT_LANG`` is later changed for each sub-site, so
|
||||
content without ``lang`` metadata would be rendered in every
|
||||
(sub-)site.
|
||||
- As with the original translations functionality, ``slug`` metadata
|
||||
is used to group translations. It is therefore often convenient to
|
||||
compensate for this by overriding the content URL (which defaults to
|
||||
slug) using the ``url`` and ``save_as`` metadata. You could also
|
||||
give articles e.g. ``name`` metadata and use it in ``ARTICLE_URL =
|
||||
'{name}.html'``.
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
- A demo and a test site is in the ``gh-pages`` branch and can be seen
|
||||
at http://smartass101.github.io/pelican-plugins/
|
1
plugins/i18n_subsites/__init__.py
Normal file
1
plugins/i18n_subsites/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .i18n_subsites import *
|
462
plugins/i18n_subsites/i18n_subsites.py
Normal file
462
plugins/i18n_subsites/i18n_subsites.py
Normal file
@ -0,0 +1,462 @@
|
||||
"""i18n_subsites plugin creates i18n-ized subsites of the default site
|
||||
|
||||
This plugin is designed for Pelican 3.4 and later
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import six
|
||||
import logging
|
||||
import posixpath
|
||||
|
||||
from copy import copy
|
||||
from itertools import chain
|
||||
from operator import attrgetter
|
||||
try:
|
||||
from collections.abc import OrderedDict
|
||||
except ImportError:
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
import gettext
|
||||
import locale
|
||||
|
||||
from pelican import signals
|
||||
from pelican.generators import ArticlesGenerator, PagesGenerator
|
||||
from pelican.settings import configure_settings
|
||||
try:
|
||||
from pelican.contents import Draft
|
||||
except ImportError:
|
||||
from pelican.contents import Article as Draft
|
||||
|
||||
|
||||
# Global vars
|
||||
_MAIN_SETTINGS = None # settings dict of the main Pelican instance
|
||||
_MAIN_LANG = None # lang of the main Pelican instance
|
||||
_MAIN_SITEURL = None # siteurl of the main Pelican instance
|
||||
_MAIN_STATIC_FILES = None # list of Static instances the main Pelican instance
|
||||
_SUBSITE_QUEUE = {} # map: lang -> settings overrides
|
||||
_SITE_DB = OrderedDict() # OrderedDict: lang -> siteurl
|
||||
_SITES_RELPATH_DB = {} # map: (lang, base_lang) -> relpath
|
||||
# map: generator -> list of removed contents that need interlinking
|
||||
_GENERATOR_DB = {}
|
||||
_NATIVE_CONTENT_URL_DB = {} # map: source_path -> content in its native lang
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temporary_locale(temp_locale=None):
|
||||
'''Enable code to run in a context with a temporary locale
|
||||
|
||||
Resets the locale back when exiting context.
|
||||
Can set a temporary locale if provided
|
||||
'''
|
||||
orig_locale = locale.setlocale(locale.LC_ALL)
|
||||
if temp_locale is not None:
|
||||
locale.setlocale(locale.LC_ALL, temp_locale)
|
||||
yield
|
||||
locale.setlocale(locale.LC_ALL, orig_locale)
|
||||
|
||||
|
||||
def initialize_dbs(settings):
|
||||
'''Initialize internal DBs using the Pelican settings dict
|
||||
|
||||
This clears the DBs for e.g. autoreload mode to work
|
||||
'''
|
||||
global _MAIN_SETTINGS, _MAIN_SITEURL, _MAIN_LANG, _SUBSITE_QUEUE
|
||||
_MAIN_SETTINGS = settings
|
||||
_MAIN_LANG = settings['DEFAULT_LANG']
|
||||
_MAIN_SITEURL = settings['SITEURL']
|
||||
_SUBSITE_QUEUE = settings.get('I18N_SUBSITES', {}).copy()
|
||||
prepare_site_db_and_overrides()
|
||||
# clear databases in case of autoreload mode
|
||||
_SITES_RELPATH_DB.clear()
|
||||
_NATIVE_CONTENT_URL_DB.clear()
|
||||
_GENERATOR_DB.clear()
|
||||
|
||||
|
||||
def prepare_site_db_and_overrides():
|
||||
'''Prepare overrides and create _SITE_DB
|
||||
|
||||
_SITE_DB.keys() need to be ready for filter_translations
|
||||
'''
|
||||
_SITE_DB.clear()
|
||||
_SITE_DB[_MAIN_LANG] = _MAIN_SITEURL
|
||||
# make sure it works for both root-relative and absolute
|
||||
main_siteurl = '/' if _MAIN_SITEURL == '' else _MAIN_SITEURL
|
||||
for lang, overrides in _SUBSITE_QUEUE.items():
|
||||
if 'SITEURL' not in overrides:
|
||||
overrides['SITEURL'] = posixpath.join(main_siteurl, lang)
|
||||
_SITE_DB[lang] = overrides['SITEURL']
|
||||
# default subsite hierarchy
|
||||
if 'OUTPUT_PATH' not in overrides:
|
||||
overrides['OUTPUT_PATH'] = os.path.join(
|
||||
_MAIN_SETTINGS['OUTPUT_PATH'], lang)
|
||||
if 'CACHE_PATH' not in overrides:
|
||||
overrides['CACHE_PATH'] = os.path.join(
|
||||
_MAIN_SETTINGS['CACHE_PATH'], lang)
|
||||
if 'STATIC_PATHS' not in overrides:
|
||||
overrides['STATIC_PATHS'] = []
|
||||
if ('THEME' not in overrides and 'THEME_STATIC_DIR' not in overrides and
|
||||
'THEME_STATIC_PATHS' not in overrides):
|
||||
relpath = relpath_to_site(lang, _MAIN_LANG)
|
||||
overrides['THEME_STATIC_DIR'] = posixpath.join(
|
||||
relpath, _MAIN_SETTINGS['THEME_STATIC_DIR'])
|
||||
overrides['THEME_STATIC_PATHS'] = []
|
||||
# to change what is perceived as translations
|
||||
overrides['DEFAULT_LANG'] = lang
|
||||
|
||||
|
||||
def subscribe_filter_to_signals(settings):
|
||||
'''Subscribe content filter to requested signals'''
|
||||
for sig in settings.get('I18N_FILTER_SIGNALS', []):
|
||||
sig.connect(filter_contents_translations)
|
||||
|
||||
|
||||
def initialize_plugin(pelican_obj):
|
||||
'''Initialize plugin variables and Pelican settings'''
|
||||
if _MAIN_SETTINGS is None:
|
||||
initialize_dbs(pelican_obj.settings)
|
||||
subscribe_filter_to_signals(pelican_obj.settings)
|
||||
|
||||
|
||||
def get_site_path(url):
|
||||
'''Get the path component of an url, excludes siteurl
|
||||
|
||||
also normalizes '' to '/' for relpath to work,
|
||||
otherwise it could be interpreted as a relative filesystem path
|
||||
'''
|
||||
path = urlparse(url).path
|
||||
if path == '':
|
||||
path = '/'
|
||||
return path
|
||||
|
||||
|
||||
def relpath_to_site(lang, target_lang):
|
||||
'''Get relative path from siteurl of lang to siteurl of base_lang
|
||||
|
||||
the output is cached in _SITES_RELPATH_DB
|
||||
'''
|
||||
path = _SITES_RELPATH_DB.get((lang, target_lang), None)
|
||||
if path is None:
|
||||
siteurl = _SITE_DB.get(lang, _MAIN_SITEURL)
|
||||
target_siteurl = _SITE_DB.get(target_lang, _MAIN_SITEURL)
|
||||
path = posixpath.relpath(get_site_path(target_siteurl),
|
||||
get_site_path(siteurl))
|
||||
_SITES_RELPATH_DB[(lang, target_lang)] = path
|
||||
return path
|
||||
|
||||
|
||||
def save_generator(generator):
|
||||
'''Save the generator for later use
|
||||
|
||||
initialize the removed content list
|
||||
'''
|
||||
_GENERATOR_DB[generator] = []
|
||||
|
||||
|
||||
def article2draft(article):
|
||||
'''Transform an Article to Draft'''
|
||||
draft = Draft(article._content, article.metadata, article.settings,
|
||||
article.source_path, article._context)
|
||||
draft.status = 'draft'
|
||||
return draft
|
||||
|
||||
|
||||
def page2hidden_page(page):
|
||||
'''Transform a Page to a hidden Page'''
|
||||
page.status = 'hidden'
|
||||
return page
|
||||
|
||||
|
||||
class GeneratorInspector(object):
|
||||
'''Inspector of generator instances'''
|
||||
|
||||
generators_info = {
|
||||
ArticlesGenerator: {
|
||||
'translations_lists': ['translations', 'drafts_translations'],
|
||||
'contents_lists': [('articles', 'drafts')],
|
||||
'hiding_func': article2draft,
|
||||
'policy': 'I18N_UNTRANSLATED_ARTICLES',
|
||||
},
|
||||
PagesGenerator: {
|
||||
'translations_lists': ['translations', 'hidden_translations'],
|
||||
'contents_lists': [('pages', 'hidden_pages')],
|
||||
'hiding_func': page2hidden_page,
|
||||
'policy': 'I18N_UNTRANSLATED_PAGES',
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, generator):
|
||||
'''Identify the best known class of the generator instance
|
||||
|
||||
The class '''
|
||||
self.generator = generator
|
||||
self.generators_info.update(generator.settings.get(
|
||||
'I18N_GENERATORS_INFO', {}))
|
||||
for cls in generator.__class__.__mro__:
|
||||
if cls in self.generators_info:
|
||||
self.info = self.generators_info[cls]
|
||||
break
|
||||
else:
|
||||
self.info = {}
|
||||
|
||||
def translations_lists(self):
|
||||
'''Iterator over lists of content translations'''
|
||||
return (getattr(self.generator, name) for name in
|
||||
self.info.get('translations_lists', []))
|
||||
|
||||
def contents_list_pairs(self):
|
||||
'''Iterator over pairs of normal and hidden contents'''
|
||||
return (tuple(getattr(self.generator, name) for name in names)
|
||||
for names in self.info.get('contents_lists', []))
|
||||
|
||||
def hiding_function(self):
|
||||
'''Function for transforming content to a hidden version'''
|
||||
hiding_func = self.info.get('hiding_func', lambda x: x)
|
||||
return hiding_func
|
||||
|
||||
def untranslated_policy(self, default):
|
||||
'''Get the policy for untranslated content'''
|
||||
return self.generator.settings.get(self.info.get('policy', None),
|
||||
default)
|
||||
|
||||
def all_contents(self):
|
||||
'''Iterator over all contents'''
|
||||
translations_iterator = chain(*self.translations_lists())
|
||||
return chain(translations_iterator,
|
||||
*(pair[i] for pair in self.contents_list_pairs()
|
||||
for i in (0, 1)))
|
||||
|
||||
|
||||
def filter_contents_translations(generator):
|
||||
'''Filter the content and translations lists of a generator
|
||||
|
||||
Filters out
|
||||
1) translations which will be generated in a different site
|
||||
2) content that is not in the language of the currently
|
||||
generated site but in that of a different site, content in a
|
||||
language which has no site is generated always. The filtering
|
||||
method bay be modified by the respective untranslated policy
|
||||
'''
|
||||
inspector = GeneratorInspector(generator)
|
||||
current_lang = generator.settings['DEFAULT_LANG']
|
||||
langs_with_sites = _SITE_DB.keys()
|
||||
removed_contents = _GENERATOR_DB[generator]
|
||||
|
||||
for translations in inspector.translations_lists():
|
||||
for translation in translations[:]: # copy to be able to remove
|
||||
if translation.lang in langs_with_sites:
|
||||
translations.remove(translation)
|
||||
removed_contents.append(translation)
|
||||
|
||||
hiding_func = inspector.hiding_function()
|
||||
untrans_policy = inspector.untranslated_policy(default='hide')
|
||||
for (contents, other_contents) in inspector.contents_list_pairs():
|
||||
for content in other_contents: # save any hidden native content first
|
||||
if content.lang == current_lang: # in native lang
|
||||
# save the native URL attr formatted in the current locale
|
||||
_NATIVE_CONTENT_URL_DB[content.source_path] = content.url
|
||||
for content in contents[:]: # copy for removing in loop
|
||||
if content.lang == current_lang: # in native lang
|
||||
# save the native URL attr formatted in the current locale
|
||||
_NATIVE_CONTENT_URL_DB[content.source_path] = content.url
|
||||
elif content.lang in langs_with_sites and untrans_policy != 'keep':
|
||||
contents.remove(content)
|
||||
if untrans_policy == 'hide':
|
||||
other_contents.append(hiding_func(content))
|
||||
elif untrans_policy == 'remove':
|
||||
removed_contents.append(content)
|
||||
|
||||
|
||||
def install_templates_translations(generator):
|
||||
'''Install gettext translations in the jinja2.Environment
|
||||
|
||||
Only if the 'jinja2.ext.i18n' jinja2 extension is enabled
|
||||
the translations for the current DEFAULT_LANG are installed.
|
||||
'''
|
||||
if 'JINJA_ENVIRONMENT' in generator.settings: # pelican 3.7+
|
||||
jinja_extensions = generator.settings['JINJA_ENVIRONMENT'].get(
|
||||
'extensions', [])
|
||||
else:
|
||||
jinja_extensions = generator.settings['JINJA_EXTENSIONS']
|
||||
|
||||
if 'jinja2.ext.i18n' in jinja_extensions:
|
||||
domain = generator.settings.get('I18N_GETTEXT_DOMAIN', 'messages')
|
||||
localedir = generator.settings.get('I18N_GETTEXT_LOCALEDIR')
|
||||
if localedir is None:
|
||||
localedir = os.path.join(generator.theme, 'translations')
|
||||
current_lang = generator.settings['DEFAULT_LANG']
|
||||
if current_lang == generator.settings.get('I18N_TEMPLATES_LANG',
|
||||
_MAIN_LANG):
|
||||
translations = gettext.NullTranslations()
|
||||
else:
|
||||
langs = [current_lang]
|
||||
try:
|
||||
translations = gettext.translation(domain, localedir, langs)
|
||||
except (IOError, OSError):
|
||||
_LOGGER.error((
|
||||
"Cannot find translations for language '{}' in '{}' with "
|
||||
"domain '{}'. Installing NullTranslations.").format(
|
||||
langs[0], localedir, domain))
|
||||
translations = gettext.NullTranslations()
|
||||
newstyle = generator.settings.get('I18N_GETTEXT_NEWSTYLE', True)
|
||||
generator.env.install_gettext_translations(translations, newstyle)
|
||||
|
||||
|
||||
def add_variables_to_context(generator):
|
||||
'''Adds useful iterable variables to template context'''
|
||||
context = generator.context # minimize attr lookup
|
||||
context['relpath_to_site'] = relpath_to_site
|
||||
context['main_siteurl'] = _MAIN_SITEURL
|
||||
context['main_lang'] = _MAIN_LANG
|
||||
context['lang_siteurls'] = _SITE_DB
|
||||
current_lang = generator.settings['DEFAULT_LANG']
|
||||
extra_siteurls = _SITE_DB.copy()
|
||||
extra_siteurls.pop(current_lang)
|
||||
context['extra_siteurls'] = extra_siteurls
|
||||
|
||||
|
||||
def interlink_translations(content):
|
||||
'''Link content to translations in their main language
|
||||
|
||||
so the URL (including localized month names) of the different subsites
|
||||
will be honored
|
||||
'''
|
||||
lang = content.lang
|
||||
# sort translations by lang
|
||||
content.translations.sort(key=attrgetter('lang'))
|
||||
for translation in content.translations:
|
||||
relpath = relpath_to_site(lang, translation.lang)
|
||||
url = _NATIVE_CONTENT_URL_DB[translation.source_path]
|
||||
translation.override_url = posixpath.join(relpath, url)
|
||||
|
||||
|
||||
def interlink_translated_content(generator):
|
||||
'''Make translations link to the native locations
|
||||
|
||||
for generators that may contain translated content
|
||||
'''
|
||||
inspector = GeneratorInspector(generator)
|
||||
for content in inspector.all_contents():
|
||||
interlink_translations(content)
|
||||
|
||||
|
||||
def interlink_removed_content(generator):
|
||||
'''For all contents removed from generation queue update interlinks
|
||||
|
||||
link to the native location
|
||||
'''
|
||||
current_lang = generator.settings['DEFAULT_LANG']
|
||||
for content in _GENERATOR_DB[generator]:
|
||||
url = _NATIVE_CONTENT_URL_DB[content.source_path]
|
||||
relpath = relpath_to_site(current_lang, content.lang)
|
||||
content.override_url = posixpath.join(relpath, url)
|
||||
|
||||
|
||||
def interlink_static_files(generator):
|
||||
'''Add links to static files in the main site if necessary'''
|
||||
if generator.settings['STATIC_PATHS'] != []:
|
||||
return # customized STATIC_PATHS
|
||||
try: # minimize attr lookup
|
||||
static_content = generator.context['static_content']
|
||||
except KeyError:
|
||||
static_content = generator.context['filenames']
|
||||
relpath = relpath_to_site(generator.settings['DEFAULT_LANG'], _MAIN_LANG)
|
||||
for staticfile in _MAIN_STATIC_FILES:
|
||||
if staticfile.get_relative_source_path() not in static_content:
|
||||
staticfile = copy(staticfile) # prevent override in main site
|
||||
staticfile.override_url = posixpath.join(relpath, staticfile.url)
|
||||
try:
|
||||
generator.add_source_path(staticfile, static=True)
|
||||
except TypeError:
|
||||
generator.add_source_path(staticfile)
|
||||
|
||||
|
||||
def save_main_static_files(static_generator):
|
||||
'''Save the static files generated for the main site'''
|
||||
global _MAIN_STATIC_FILES
|
||||
# test just for current lang as settings change in autoreload mode
|
||||
if static_generator.settings['DEFAULT_LANG'] == _MAIN_LANG:
|
||||
_MAIN_STATIC_FILES = static_generator.staticfiles
|
||||
|
||||
|
||||
def update_generators():
|
||||
'''Update the context of all generators
|
||||
|
||||
Ads useful variables and translations into the template context
|
||||
and interlink translations
|
||||
'''
|
||||
for generator in _GENERATOR_DB.keys():
|
||||
install_templates_translations(generator)
|
||||
add_variables_to_context(generator)
|
||||
interlink_static_files(generator)
|
||||
interlink_removed_content(generator)
|
||||
interlink_translated_content(generator)
|
||||
|
||||
|
||||
def get_pelican_cls(settings):
|
||||
'''Get the Pelican class requested in settings'''
|
||||
cls = settings['PELICAN_CLASS']
|
||||
if isinstance(cls, six.string_types):
|
||||
module, cls_name = cls.rsplit('.', 1)
|
||||
module = __import__(module)
|
||||
cls = getattr(module, cls_name)
|
||||
return cls
|
||||
|
||||
|
||||
def create_next_subsite(pelican_obj):
|
||||
'''Create the next subsite using the lang-specific config
|
||||
|
||||
If there are no more subsites in the generation queue, update all
|
||||
the generators (interlink translations and removed content, add
|
||||
variables and translations to template context). Otherwise get the
|
||||
language and overrides for next the subsite in the queue and apply
|
||||
overrides. Then generate the subsite using a PELICAN_CLASS
|
||||
instance and its run method. Finally, restore the previous locale.
|
||||
'''
|
||||
global _MAIN_SETTINGS
|
||||
if len(_SUBSITE_QUEUE) == 0:
|
||||
_LOGGER.debug(
|
||||
'i18n: Updating cross-site links and context of all generators.')
|
||||
update_generators()
|
||||
_MAIN_SETTINGS = None # to initialize next time
|
||||
else:
|
||||
with temporary_locale():
|
||||
settings = _MAIN_SETTINGS.copy()
|
||||
lang, overrides = _SUBSITE_QUEUE.popitem()
|
||||
settings.update(overrides)
|
||||
settings = configure_settings(settings) # to set LOCALE, etc.
|
||||
cls = get_pelican_cls(settings)
|
||||
|
||||
new_pelican_obj = cls(settings)
|
||||
_LOGGER.debug(("Generating i18n subsite for language '{}' "
|
||||
"using class {}").format(lang, cls))
|
||||
new_pelican_obj.run()
|
||||
|
||||
|
||||
# map: signal name -> function name
|
||||
_SIGNAL_HANDLERS_DB = {
|
||||
'get_generators': initialize_plugin,
|
||||
'article_generator_pretaxonomy': filter_contents_translations,
|
||||
'page_generator_finalized': filter_contents_translations,
|
||||
'get_writer': create_next_subsite,
|
||||
'static_generator_finalized': save_main_static_files,
|
||||
'generator_init': save_generator,
|
||||
}
|
||||
|
||||
|
||||
def register():
|
||||
'''Register the plugin only if required signals are available'''
|
||||
for sig_name in _SIGNAL_HANDLERS_DB.keys():
|
||||
if not hasattr(signals, sig_name):
|
||||
_LOGGER.error((
|
||||
'The i18n_subsites plugin requires the {} '
|
||||
'signal available for sure in Pelican 3.4.0 and later, '
|
||||
'plugin will not be used.').format(sig_name))
|
||||
return
|
||||
|
||||
for sig_name, handler in _SIGNAL_HANDLERS_DB.items():
|
||||
sig = getattr(signals, sig_name)
|
||||
sig.connect(handler)
|
128
plugins/i18n_subsites/implementing_language_buttons.rst
Normal file
128
plugins/i18n_subsites/implementing_language_buttons.rst
Normal file
@ -0,0 +1,128 @@
|
||||
-----------------------------
|
||||
Implementing language buttons
|
||||
-----------------------------
|
||||
|
||||
Each article with translations has translations links, but that's the
|
||||
only way to switch between language subsites.
|
||||
|
||||
For this reason it is convenient to add language buttons to the top
|
||||
menu bar to make it simple to switch between the language subsites on
|
||||
all pages.
|
||||
|
||||
Example designs
|
||||
---------------
|
||||
|
||||
Language buttons showing other available languages
|
||||
..................................................
|
||||
|
||||
The ``extra_siteurls`` dictionary is a mapping of all other (not the
|
||||
``DEFAULT_LANG`` of the current (sub-)site) languages to the
|
||||
``SITEURL`` of the respective (sub-)sites
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!-- SNIP -->
|
||||
<nav><ul>
|
||||
{% if extra_siteurls %}
|
||||
{% for lang, url in extra_siteurls.items() %}
|
||||
<li><a href="{{ url }}/">{{ lang }}</a></li>
|
||||
{% endfor %}
|
||||
<!-- separator -->
|
||||
<li style="background-color: white; padding: 5px;"> </li>
|
||||
{% endif %}
|
||||
{% for title, link in MENUITEMS %}
|
||||
<!-- SNIP -->
|
||||
|
||||
Notice the slash ``/`` after ``{{ url }}``, this makes sure it works
|
||||
with local development when ``SITEURL == ''``.
|
||||
|
||||
Language buttons showing all available languages, current is active
|
||||
...................................................................
|
||||
|
||||
The ``lang_subsites`` dictionary is a mapping of all languages to the
|
||||
``SITEURL`` of the respective (sub-)sites. This template sets the
|
||||
language of the current (sub-)site as active.
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!-- SNIP -->
|
||||
<nav><ul>
|
||||
{% if lang_siteurls %}
|
||||
{% for lang, url in lang_siteurls.items() %}
|
||||
<li{% if lang == DEFAULT_LANG %} class="active"{% endif %}><a href="{{ url }}/">{{ lang }}</a></li>
|
||||
{% endfor %}
|
||||
<!-- separator -->
|
||||
<li style="background-color: white; padding: 5px;"> </li>
|
||||
{% endif %}
|
||||
{% for title, link in MENUITEMS %}
|
||||
<!-- SNIP -->
|
||||
|
||||
|
||||
Tips and tricks
|
||||
---------------
|
||||
|
||||
Showing more than language codes
|
||||
................................
|
||||
|
||||
If you want the language buttons to show e.g. the names of the
|
||||
languages or flags [#flags]_, not just the language codes, you can use
|
||||
a jinja filter to translate the language codes
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
languages_lookup = {
|
||||
'en': 'English',
|
||||
'cz': 'Čeština',
|
||||
}
|
||||
|
||||
def lookup_lang_name(lang_code):
|
||||
return languages_lookup[lang_code]
|
||||
|
||||
JINJA_FILTERS = {
|
||||
...
|
||||
'lookup_lang_name': lookup_lang_name,
|
||||
}
|
||||
|
||||
And then the link content becomes
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!-- SNIP -->
|
||||
{% for lang, siteurl in lang_siteurls.items() %}
|
||||
<li{% if lang == DEFAULT_LANG %} class="active"{% endif %}><a href="{{ siteurl }}/">{{ lang | lookup_lang_name }}</a></li>
|
||||
{% endfor %}
|
||||
<!-- SNIP -->
|
||||
|
||||
|
||||
Changing the order of language buttons
|
||||
......................................
|
||||
|
||||
Because ``lang_siteurls`` and ``extra_siteurls`` are instances of
|
||||
``OrderedDict`` with ``main_lang`` being always the first key, you can
|
||||
change the order through a jinja filter.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def my_ordered_items(ordered_dict):
|
||||
items = list(ordered_dict.items())
|
||||
# swap first and last using tuple unpacking
|
||||
items[0], items[-1] = items[-1], items[0]
|
||||
return items
|
||||
|
||||
JINJA_FILTERS = {
|
||||
...
|
||||
'my_ordered_items': my_ordered_items,
|
||||
}
|
||||
|
||||
And then the ``for`` loop line in the template becomes
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
<!-- SNIP -->
|
||||
{% for lang, siteurl in lang_siteurls | my_ordered_items %}
|
||||
<!-- SNIP -->
|
||||
|
||||
|
||||
.. [#flags] Although it may look nice, `w3 discourages it
|
||||
<http://www.w3.org/TR/i18n-html-tech-lang/#ri20040808.173208643>`_.
|
202
plugins/i18n_subsites/localizing_using_jinja2.rst
Normal file
202
plugins/i18n_subsites/localizing_using_jinja2.rst
Normal file
@ -0,0 +1,202 @@
|
||||
-----------------------------
|
||||
Localizing themes with Jinja2
|
||||
-----------------------------
|
||||
|
||||
1. Localize templates
|
||||
---------------------
|
||||
|
||||
To enable the |ext| extension in your templates, you must add it to
|
||||
``JINJA_ENVIRONMENT`` in your Pelican configuration
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
JINJA_ENVIRONMENT = {
|
||||
'extensions': ['jinja2.ext.i18n', ...]
|
||||
}
|
||||
|
||||
Then follow the `Jinja2 templating documentation for the I18N plugin
|
||||
<http://jinja.pocoo.org/docs/templates/#i18n>`_ to make your templates
|
||||
localizable. This usually means surrounding strings with the ``{%
|
||||
trans %}`` directive or using ``gettext()`` in expressions
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% trans %}translatable content{% endtrans %}
|
||||
{{ gettext('a translatable string') }}
|
||||
|
||||
For pluralization support, etc. consult the documentation.
|
||||
|
||||
To enable `newstyle gettext calls
|
||||
<http://jinja.pocoo.org/docs/extensions/#newstyle-gettext>`_ the
|
||||
``I18N_GETTEXT_NEWSTYLE`` config variable must be set to ``True``
|
||||
(default).
|
||||
|
||||
.. |ext| replace:: ``jinja2.ext.i18n``
|
||||
|
||||
2. Specify translations location
|
||||
--------------------------------
|
||||
|
||||
The |ext| extension uses the `Python gettext library
|
||||
<http://docs.python.org/library/gettext.html>`_ for translating
|
||||
strings.
|
||||
|
||||
In your Pelican config you can give the path in which to look for
|
||||
translations in the ``I18N_GETTEXT_LOCALEDIR`` variable. If not given,
|
||||
it is assumed to be the ``translations`` subfolder in the top folder
|
||||
of the theme specified by ``THEME``.
|
||||
|
||||
The domain of the translations (the name of each translation file is
|
||||
``domain.mo``) is controlled by the ``I18N_GETTEXT_DOMAIN`` config
|
||||
variable (defaults to ``messages``).
|
||||
|
||||
Example
|
||||
.......
|
||||
|
||||
With the following in your Pelican settings file
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
I18N_GETTEXT_LOCALEDIR = 'some/path/'
|
||||
I18N_GETTEXT_DOMAIN = 'my_domain'
|
||||
|
||||
the translation for language 'cz' will be expected to be in
|
||||
``some/path/cz/LC_MESSAGES/my_domain.mo``
|
||||
|
||||
|
||||
3. Extract translatable strings and translate them
|
||||
--------------------------------------------------
|
||||
|
||||
There are many ways to extract translatable strings and create
|
||||
``gettext`` compatible translations. You can create the ``*.po`` and
|
||||
``*.mo`` message catalog files yourself, or you can use some helper
|
||||
tool as described in `the Python gettext library tutorial
|
||||
<http://docs.python.org/library/gettext.html#internationalizing-your-programs-and-modules>`_.
|
||||
|
||||
You of course don't need to provide a translation for the language in
|
||||
which the templates are written which is assumed to be the original
|
||||
``DEFAULT_LANG``. This can be overridden in the
|
||||
``I18N_TEMPLATES_LANG`` variable.
|
||||
|
||||
Recommended tool: babel
|
||||
.......................
|
||||
|
||||
`Babel <http://babel.pocoo.org/>`_ makes it easy to extract
|
||||
translatable strings from the localized Jinja2 templates and assists
|
||||
with creating translations as documented in this `Jinja2-Babel
|
||||
tutorial
|
||||
<http://pythonhosted.org/Flask-Babel/#translating-applications>`_
|
||||
[#flask]_ on which the following is based.
|
||||
|
||||
1. Add babel mapping
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Let's assume that you are localizing a theme in ``themes/my_theme/``
|
||||
and that you use the default settings, i.e. the default domain
|
||||
``messages`` and will put the translations in the ``translations``
|
||||
subdirectory of the theme directory as
|
||||
``themes/my_theme/translations/``.
|
||||
|
||||
It is up to you where to store babel mappings and translation files
|
||||
templates (``*.pot``), but a convenient place is to put them in
|
||||
``themes/my_theme/`` and work in that directory. From now on let's
|
||||
assume that it will be our current working directory (CWD).
|
||||
|
||||
To tell babel to extract translatable strings from the templates
|
||||
create a mapping file ``babel.cfg`` with the following line
|
||||
|
||||
.. code-block:: cfg
|
||||
|
||||
[jinja2: templates/**.html]
|
||||
|
||||
|
||||
2. Extract translatable strings from templates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Run the following command to create a ``messages.pot`` message catalog
|
||||
template file from extracted translatable strings
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pybabel extract --mapping babel.cfg --output messages.pot ./
|
||||
|
||||
|
||||
3. Initialize message catalogs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to translate the template to language ``lang``, run the
|
||||
following command to create a message catalog
|
||||
``translations/lang/LC_MESSAGES/messages.po`` using the template
|
||||
``messages.pot``
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pybabel init --input-file messages.pot --output-dir translations/ --locale lang --domain messages
|
||||
|
||||
babel expects ``lang`` to be a valid locale identifier, so if e.g. you
|
||||
are translating for language ``cz`` but the corresponding locale is
|
||||
``cs``, you have to use the locale identifier. Nevertheless, the
|
||||
gettext infrastructure should later correctly find the locale for a
|
||||
given language.
|
||||
|
||||
4. Fill the message catalogs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The message catalog files format is quite intuitive, it is fully
|
||||
documented in the `GNU gettext manual
|
||||
<http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files>`_. Essentially,
|
||||
you fill in the ``msgstr`` strings
|
||||
|
||||
|
||||
.. code-block:: po
|
||||
|
||||
msgid "just a simple string"
|
||||
msgstr "jenom jednoduchý řetězec"
|
||||
|
||||
msgid ""
|
||||
"some multiline string"
|
||||
"looks like this"
|
||||
msgstr ""
|
||||
"nějaký více řádkový řetězec"
|
||||
"vypadá takto"
|
||||
|
||||
You might also want to remove ``#,fuzzy`` flags once the translation
|
||||
is complete and reviewed to show that it can be compiled.
|
||||
|
||||
5. Compile the message catalogs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The message catalogs must be compiled into binary format using this
|
||||
command
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pybabel compile --directory translations/ --domain messages
|
||||
|
||||
This command might complain about "fuzzy" translations, which means
|
||||
you should review the translations and once done, remove the fuzzy
|
||||
flag line.
|
||||
|
||||
(6.) Update the catalogs when templates change
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you add any translatable patterns into your templates, you have to
|
||||
update your message catalogs too. First you extract a new message
|
||||
catalog template as described in the 2. step. Then you run the
|
||||
following command [#pybabel_error]_
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pybabel update --input-file messages.pot --output-dir translations/ --domain messages
|
||||
|
||||
This will merge the new patterns with the old ones. Once you review
|
||||
and fill them, you have to recompile them as described in the 5. step.
|
||||
|
||||
.. [#flask] Although the tutorial is focused on Flask-based web
|
||||
applications, the linked translation tutorial is not
|
||||
Flask-specific.
|
||||
.. [#pybabel_error] If you get an error ``TypeError: must be str, not
|
||||
bytes`` with Python 3.3, it is likely you are
|
||||
suffering from this `bug
|
||||
<https://github.com/mitsuhiko/flask-babel/issues/43>`_.
|
||||
Until the fix is released, you can use babel with
|
||||
Python 2.7.
|
@ -0,0 +1,2 @@
|
||||
[jinja2: templates/**.html]
|
||||
|
23
plugins/i18n_subsites/test_data/localized_theme/messages.pot
Normal file
23
plugins/i18n_subsites/test_data/localized_theme/messages.pot
Normal file
@ -0,0 +1,23 @@
|
||||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-07-13 12:25+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
|
||||
#: templates/base.html:3
|
||||
msgid "Welcome to our"
|
||||
msgstr ""
|
||||
|
@ -0,0 +1,7 @@
|
||||
{% extends "!simple/base.html" %}
|
||||
|
||||
{% block title %}{% trans %}Welcome to our{% endtrans %} {{ SITENAME }}{% endblock %}
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/style.css" />
|
||||
{% endblock %}
|
Binary file not shown.
@ -0,0 +1,23 @@
|
||||
# German translations for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-07-13 12:25+0200\n"
|
||||
"PO-Revision-Date: 2014-07-13 12:26+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: de <LL@li.org>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
|
||||
#: templates/base.html:3
|
||||
msgid "Welcome to our"
|
||||
msgstr "Willkommen Sie zur unserer"
|
||||
|
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testing site - An untranslated article</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testing site Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/theme/style.css" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/">Testing site <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/pages/untranslated-page.html">Untranslated page</a></li>
|
||||
<li class="active"><a href="http://example.com/test/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/an-untranslated-article.html" rel="bookmark"
|
||||
title="Permalink to An untranslated article">An untranslated article</a></h2>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-07-14T00:00:00+00:00">
|
||||
Mon 14 July 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/author/the-tester.html">The Tester</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testovací stránka - An untranslated article</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testovací stránka Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/cz/../theme/style.css" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/cz/">Testovací stránka <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li class="active"><a href="http://example.com/test/cz/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/cz/an-untranslated-article-en.html" rel="bookmark"
|
||||
title="Permalink to An untranslated article">An untranslated article</a></h2>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-07-14T00:00:00+00:00">
|
||||
Mon 14 July 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/cz/author/test-testovic.html">Test Testovič</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/cz/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
10
plugins/i18n_subsites/test_data/output/cz/feeds_all.atom.xml
Normal file
10
plugins/i18n_subsites/test_data/output/cz/feeds_all.atom.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"><title>Testovací stránka</title><link href="http://example.com/test/cz/" rel="alternate"></link><link href="http://example.com/test/feeds_all.atom.xml" rel="self"></link><id>http://example.com/test/cz/</id><updated>2014-09-15T00:00:00+00:00</updated><entry><title>Přeložený článek</title><link href="http://example.com/test/cz/translated-article.html" rel="alternate"></link><published>2014-09-15T00:00:00+00:00</published><updated>2014-09-15T00:00:00+00:00</updated><author><name>Test Testovič</name></author><id>tag:example.com,2014-09-15:/test/cz/translated-article.html</id><content type="html"><p>Jednoduchý článek s překlady.
|
||||
Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p>
|
||||
</content></entry><entry><title>Ein übersetzter Artikel</title><link href="http://example.com/test/de/translated-article.html" rel="alternate"></link><published>2014-09-14T00:00:00+00:00</published><updated>2014-09-14T00:00:00+00:00</updated><author><name>Test Testovič</name></author><id>tag:example.com,2014-09-14:/test/de/translated-article.html</id><content type="html"><p>Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p>
|
||||
</content></entry><entry><title>A translated article</title><link href="http://example.com/test/translated-article.html" rel="alternate"></link><published>2014-09-13T00:00:00+00:00</published><updated>2014-09-13T00:00:00+00:00</updated><author><name>Test Testovič</name></author><id>tag:example.com,2014-09-13:/test/translated-article.html</id><content type="html"><p>A simple article with a translation.
|
||||
Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p>
|
||||
</content></entry><entry><title>An untranslated article</title><link href="http://example.com/test/cz/an-untranslated-article-en.html" rel="alternate"></link><published>2014-07-14T00:00:00+00:00</published><updated>2014-07-14T00:00:00+00:00</updated><author><name>Test Testovič</name></author><id>tag:example.com,2014-07-14:/test/cz/an-untranslated-article-en.html</id><content type="html"><p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
</content></entry></feed>
|
55
plugins/i18n_subsites/test_data/output/cz/index.html
Normal file
55
plugins/i18n_subsites/test_data/output/cz/index.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="cz">
|
||||
<head>
|
||||
<title>Welcome to our Testovací stránka</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testovací stránka Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/cz/../theme/style.css" />
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/cz/">Testovací stránka <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/cz/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content">
|
||||
<h2>All articles</h2>
|
||||
|
||||
<ol id="post-list">
|
||||
<li><article class="hentry">
|
||||
<header> <h2 class="entry-title"><a href="http://example.com/test/cz/translated-article.html" rel="bookmark" title="Permalink to Přeložený článek">Přeložený článek</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-15T00:00:00+00:00"> Mon 15 September 2014 </time>
|
||||
<address class="vcard author">By
|
||||
<a class="url fn" href="http://example.com/test/cz/author/test-testovic.html">Test Testovič</a>
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> <p>Jednoduchý článek s překlady.
|
||||
Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
<li><article class="hentry">
|
||||
<header> <h2 class="entry-title"><a href="http://example.com/test/cz/an-untranslated-article-en.html" rel="bookmark" title="Permalink to An untranslated article">An untranslated article</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-07-14T00:00:00+00:00"> Mon 14 July 2014 </time>
|
||||
<address class="vcard author">By
|
||||
<a class="url fn" href="http://example.com/test/cz/author/test-testovic.html">Test Testovič</a>
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> <p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
</ol><!-- /#posts-list -->
|
||||
</section><!-- /#content -->
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
39
plugins/i18n_subsites/test_data/output/cz/pages/404.html
Normal file
39
plugins/i18n_subsites/test_data/output/cz/pages/404.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="cz">
|
||||
<head>
|
||||
<title>Testovací stránka - 404 stránka</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testovací stránka Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/cz/../theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="de" href="http://example.com/test/cz/../de/pages/404.html">
|
||||
<link rel="alternate" hreflang="en" href="http://example.com/test/cz/../pages/404.html">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/cz/">Testovací stránka <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/cz/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<h1>404 stránka</h1>
|
||||
Translations:
|
||||
<a href="http://example.com/test/cz/../de/pages/404.html" hreflang="de">de</a>
|
||||
<a href="http://example.com/test/cz/../pages/404.html" hreflang="en">en</a>
|
||||
|
||||
|
||||
<p>Jednoduchá 404 stránka.</p>
|
||||
|
||||
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="cz">
|
||||
<head>
|
||||
<title>Testovací stránka - Přeložený článek</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testovací stránka Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/cz/../theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="de" href="http://example.com/test/cz/../de/translated-article.html">
|
||||
<link rel="alternate" hreflang="en" href="http://example.com/test/cz/../translated-article.html">
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/cz/">Testovací stránka <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li class="active"><a href="http://example.com/test/cz/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/cz/translated-article.html" rel="bookmark"
|
||||
title="Permalink to Přeložený článek">Přeložený článek</a></h2>
|
||||
Translations:
|
||||
<a href="http://example.com/test/cz/../de/translated-article.html" hreflang="de">de</a>
|
||||
<a href="http://example.com/test/cz/../translated-article.html" hreflang="en">en</a>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-15T00:00:00+00:00">
|
||||
Mon 15 September 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/cz/author/test-testovic.html">Test Testovič</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/cz/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>Jednoduchý článek s překlady.
|
||||
Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testseite - An untranslated article</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testseite Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/de/../theme/style.css" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/de/">Testseite <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li class="active"><a href="http://example.com/test/de/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/de/drafts/an-untranslated-article-en.html" rel="bookmark"
|
||||
title="Permalink to An untranslated article">An untranslated article</a></h2>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-07-14T00:00:00+00:00">
|
||||
Mo 14 Juli 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/de/author/der-tester.html">Der Tester</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/de/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/de/pages/untranslated-page-en.html">untranslated page</a></p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"><title>Testseite</title><link href="http://example.com/test/de/" rel="alternate"></link><link href="http://example.com/test/feeds_all.atom.xml" rel="self"></link><id>http://example.com/test/de/</id><updated>2014-09-15T00:00:00+00:00</updated><entry><title>Přeložený článek</title><link href="http://example.com/test/cz/translated-article.html" rel="alternate"></link><published>2014-09-15T00:00:00+00:00</published><updated>2014-09-15T00:00:00+00:00</updated><author><name>Der Tester</name></author><id>tag:example.com,2014-09-15:/test/cz/translated-article.html</id><content type="html"><p>Jednoduchý článek s překlady.
|
||||
Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p>
|
||||
</content></entry><entry><title>Ein übersetzter Artikel</title><link href="http://example.com/test/de/translated-article.html" rel="alternate"></link><published>2014-09-14T00:00:00+00:00</published><updated>2014-09-14T00:00:00+00:00</updated><author><name>Der Tester</name></author><id>tag:example.com,2014-09-14:/test/de/translated-article.html</id><content type="html"><p>Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p>
|
||||
</content></entry><entry><title>A translated article</title><link href="http://example.com/test/translated-article.html" rel="alternate"></link><published>2014-09-13T00:00:00+00:00</published><updated>2014-09-13T00:00:00+00:00</updated><author><name>Der Tester</name></author><id>tag:example.com,2014-09-13:/test/translated-article.html</id><content type="html"><p>A simple article with a translation.
|
||||
Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p>
|
||||
</content></entry></feed>
|
43
plugins/i18n_subsites/test_data/output/de/index.html
Normal file
43
plugins/i18n_subsites/test_data/output/de/index.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Willkommen Sie zur unserer Testseite</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testseite Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/de/../theme/style.css" />
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/de/">Testseite <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/de/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content">
|
||||
<h2>All articles</h2>
|
||||
|
||||
<ol id="post-list">
|
||||
<li><article class="hentry">
|
||||
<header> <h2 class="entry-title"><a href="http://example.com/test/de/translated-article.html" rel="bookmark" title="Permalink to Ein übersetzter Artikel">Ein übersetzter Artikel</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-14T00:00:00+00:00"> So 14 September 2014 </time>
|
||||
<address class="vcard author">By
|
||||
<a class="url fn" href="http://example.com/test/de/author/der-tester.html">Der Tester</a>
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> <p>Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
</ol><!-- /#posts-list -->
|
||||
</section><!-- /#content -->
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
39
plugins/i18n_subsites/test_data/output/de/pages/404.html
Normal file
39
plugins/i18n_subsites/test_data/output/de/pages/404.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Testseite - Eine 404 Seite</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testseite Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/de/../theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="cz" href="http://example.com/test/de/../cz/pages/404.html">
|
||||
<link rel="alternate" hreflang="en" href="http://example.com/test/de/../pages/404.html">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/de/">Testseite <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/de/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<h1>Eine 404 Seite</h1>
|
||||
Translations:
|
||||
<a href="http://example.com/test/de/../cz/pages/404.html" hreflang="cz">cz</a>
|
||||
<a href="http://example.com/test/de/../pages/404.html" hreflang="en">en</a>
|
||||
|
||||
|
||||
<p>Eine einfache 404 Seite.</p>
|
||||
|
||||
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testseite - Untranslated page</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testseite Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/de/../theme/style.css" />
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/de/">Testseite <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/de/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<h1>Untranslated page</h1>
|
||||
|
||||
|
||||
<p>This page has no translation.</p>
|
||||
|
||||
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Testseite - Ein übersetzter Artikel</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testseite Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/de/../theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="cz" href="http://example.com/test/de/../cz/translated-article.html">
|
||||
<link rel="alternate" hreflang="en" href="http://example.com/test/de/../translated-article.html">
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/de/">Testseite <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li class="active"><a href="http://example.com/test/de/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/de/translated-article.html" rel="bookmark"
|
||||
title="Permalink to Ein übersetzter Artikel">Ein übersetzter Artikel</a></h2>
|
||||
Translations:
|
||||
<a href="http://example.com/test/de/../cz/translated-article.html" hreflang="cz">cz</a>
|
||||
<a href="http://example.com/test/de/../translated-article.html" hreflang="en">en</a>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-14T00:00:00+00:00">
|
||||
So 14 September 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/de/author/der-tester.html">Der Tester</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/de/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
10
plugins/i18n_subsites/test_data/output/feeds_all.atom.xml
Normal file
10
plugins/i18n_subsites/test_data/output/feeds_all.atom.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"><title>Testing site</title><link href="http://example.com/test/" rel="alternate"></link><link href="http://example.com/test/feeds_all.atom.xml" rel="self"></link><id>http://example.com/test/</id><updated>2014-09-15T00:00:00+00:00</updated><entry><title>Přeložený článek</title><link href="http://example.com/test/cz/translated-article.html" rel="alternate"></link><published>2014-09-15T00:00:00+00:00</published><updated>2014-09-15T00:00:00+00:00</updated><author><name>The Tester</name></author><id>tag:example.com,2014-09-15:/test/cz/translated-article.html</id><content type="html"><p>Jednoduchý článek s překlady.
|
||||
Zde je odkaz na <a class="reference external" href="http://example.com/test/images/img.png">nějaký obrázek</a>.</p>
|
||||
</content></entry><entry><title>Ein übersetzter Artikel</title><link href="http://example.com/test/de/translated-article.html" rel="alternate"></link><published>2014-09-14T00:00:00+00:00</published><updated>2014-09-14T00:00:00+00:00</updated><author><name>The Tester</name></author><id>tag:example.com,2014-09-14:/test/de/translated-article.html</id><content type="html"><p>Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur <a class="reference external" href="http://example.com/test/images/img.png">einigem Bild</a>.</p>
|
||||
</content></entry><entry><title>A translated article</title><link href="http://example.com/test/translated-article.html" rel="alternate"></link><published>2014-09-13T00:00:00+00:00</published><updated>2014-09-13T00:00:00+00:00</updated><author><name>The Tester</name></author><id>tag:example.com,2014-09-13:/test/translated-article.html</id><content type="html"><p>A simple article with a translation.
|
||||
Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p>
|
||||
</content></entry><entry><title>An untranslated article</title><link href="http://example.com/test/an-untranslated-article.html" rel="alternate"></link><published>2014-07-14T00:00:00+00:00</published><updated>2014-07-14T00:00:00+00:00</updated><author><name>The Tester</name></author><id>tag:example.com,2014-07-14:/test/an-untranslated-article.html</id><content type="html"><p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
</content></entry></feed>
|
56
plugins/i18n_subsites/test_data/output/index.html
Normal file
56
plugins/i18n_subsites/test_data/output/index.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Welcome to our Testing site</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testing site Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/theme/style.css" />
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/">Testing site <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/pages/untranslated-page.html">Untranslated page</a></li>
|
||||
<li><a href="http://example.com/test/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content">
|
||||
<h2>All articles</h2>
|
||||
|
||||
<ol id="post-list">
|
||||
<li><article class="hentry">
|
||||
<header> <h2 class="entry-title"><a href="http://example.com/test/translated-article.html" rel="bookmark" title="Permalink to A translated article">A translated article</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-13T00:00:00+00:00"> Sat 13 September 2014 </time>
|
||||
<address class="vcard author">By
|
||||
<a class="url fn" href="http://example.com/test/author/the-tester.html">The Tester</a>
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> <p>A simple article with a translation.
|
||||
Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
<li><article class="hentry">
|
||||
<header> <h2 class="entry-title"><a href="http://example.com/test/an-untranslated-article.html" rel="bookmark" title="Permalink to An untranslated article">An untranslated article</a></h2> </header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-07-14T00:00:00+00:00"> Mon 14 July 2014 </time>
|
||||
<address class="vcard author">By
|
||||
<a class="url fn" href="http://example.com/test/author/the-tester.html">The Tester</a>
|
||||
</address>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content"> <p>An article without a translation.
|
||||
Here is a link to an <a class="reference external" href="http://example.com/test/pages/untranslated-page.html">untranslated page</a></p>
|
||||
</div><!-- /.entry-content -->
|
||||
</article></li>
|
||||
</ol><!-- /#posts-list -->
|
||||
</section><!-- /#content -->
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
40
plugins/i18n_subsites/test_data/output/pages/404.html
Normal file
40
plugins/i18n_subsites/test_data/output/pages/404.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testing site - A 404 page</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testing site Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="cz" href="http://example.com/test/cz/pages/404.html">
|
||||
<link rel="alternate" hreflang="de" href="http://example.com/test/de/pages/404.html">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/">Testing site <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/pages/untranslated-page.html">Untranslated page</a></li>
|
||||
<li><a href="http://example.com/test/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<h1>A 404 page</h1>
|
||||
Translations:
|
||||
<a href="http://example.com/test/cz/pages/404.html" hreflang="cz">cz</a>
|
||||
<a href="http://example.com/test/de/pages/404.html" hreflang="de">de</a>
|
||||
|
||||
|
||||
<p>A simple 404 page.</p>
|
||||
|
||||
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testing site - Untranslated page</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testing site Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/theme/style.css" />
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/">Testing site <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li class="active"><a href="http://example.com/test/pages/untranslated-page.html">Untranslated page</a></li>
|
||||
<li><a href="http://example.com/test/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<h1>Untranslated page</h1>
|
||||
|
||||
|
||||
<p>This page has no translation.</p>
|
||||
|
||||
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Testing site - A translated article</title>
|
||||
<meta charset="utf-8" />
|
||||
<link href="http://example.com/test/feeds_all.atom.xml" type="application/atom+xml" rel="alternate" title="Testing site Full Atom Feed" />
|
||||
|
||||
<link rel="stylesheet" href="http://example.com/test/theme/style.css" />
|
||||
|
||||
|
||||
<link rel="alternate" hreflang="cz" href="http://example.com/test/cz/translated-article.html">
|
||||
<link rel="alternate" hreflang="de" href="http://example.com/test/de/translated-article.html">
|
||||
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body id="index" class="home">
|
||||
<header id="banner" class="body">
|
||||
<h1><a href="http://example.com/test/">Testing site <strong></strong></a></h1>
|
||||
</header><!-- /#banner -->
|
||||
<nav id="menu"><ul>
|
||||
<li><a href="http://example.com/test/pages/untranslated-page.html">Untranslated page</a></li>
|
||||
<li class="active"><a href="http://example.com/test/category/misc.html">misc</a></li>
|
||||
</ul></nav><!-- /#menu -->
|
||||
<section id="content" class="body">
|
||||
<header>
|
||||
<h2 class="entry-title">
|
||||
<a href="http://example.com/test/translated-article.html" rel="bookmark"
|
||||
title="Permalink to A translated article">A translated article</a></h2>
|
||||
Translations:
|
||||
<a href="http://example.com/test/cz/translated-article.html" hreflang="cz">cz</a>
|
||||
<a href="http://example.com/test/de/translated-article.html" hreflang="de">de</a>
|
||||
|
||||
</header>
|
||||
<footer class="post-info">
|
||||
<time class="published" datetime="2014-09-13T00:00:00+00:00">
|
||||
Sat 13 September 2014
|
||||
</time>
|
||||
<address class="vcard author">
|
||||
By <a class="url fn" href="http://example.com/test/author/the-tester.html">The Tester</a>
|
||||
</address>
|
||||
<div class="category">
|
||||
Category: <a href="http://example.com/test/category/misc.html">misc</a>
|
||||
</div>
|
||||
</footer><!-- /.post-info -->
|
||||
<div class="entry-content">
|
||||
<p>A simple article with a translation.
|
||||
Here is a link to <a class="reference external" href="http://example.com/test/images/img.png">some image</a>.</p>
|
||||
|
||||
</div><!-- /.entry-content -->
|
||||
</section>
|
||||
<footer id="contentinfo" class="body">
|
||||
<address id="about" class="vcard body">
|
||||
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
|
||||
which takes great advantage of <a href="http://python.org">Python</a>.
|
||||
</address><!-- /#about -->
|
||||
</footer><!-- /#contentinfo -->
|
||||
</body>
|
||||
</html>
|
53
plugins/i18n_subsites/test_data/pelicanconf.py
Normal file
53
plugins/i18n_subsites/test_data/pelicanconf.py
Normal file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*- #
|
||||
from __future__ import unicode_literals
|
||||
|
||||
AUTHOR = 'The Tester'
|
||||
SITENAME = 'Testing site'
|
||||
SITEURL = 'http://example.com/test'
|
||||
|
||||
# to make the test suite portable
|
||||
TIMEZONE = 'UTC'
|
||||
|
||||
DEFAULT_LANG = 'en'
|
||||
LOCALE = 'en_US.UTF-8'
|
||||
|
||||
# Generate only one feed
|
||||
FEED_ALL_ATOM = 'feeds_all.atom.xml'
|
||||
CATEGORY_FEED_ATOM = None
|
||||
TRANSLATION_FEED_ATOM = None
|
||||
AUTHOR_FEED_ATOM = None
|
||||
AUTHOR_FEED_RSS = None
|
||||
|
||||
# Disable unnecessary pages
|
||||
CATEGORY_SAVE_AS = ''
|
||||
TAG_SAVE_AS = ''
|
||||
AUTHOR_SAVE_AS = ''
|
||||
ARCHIVES_SAVE_AS = ''
|
||||
AUTHORS_SAVE_AS = ''
|
||||
CATEGORIES_SAVE_AS = ''
|
||||
TAGS_SAVE_AS = ''
|
||||
|
||||
PLUGIN_PATHS = ['../../']
|
||||
PLUGINS = ['i18n_subsites']
|
||||
|
||||
THEME = 'localized_theme'
|
||||
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
|
||||
|
||||
from blinker import signal
|
||||
tmpsig = signal('tmpsig')
|
||||
I18N_FILTER_SIGNALS = [tmpsig]
|
||||
|
||||
I18N_SUBSITES = {
|
||||
'de': {
|
||||
'SITENAME': 'Testseite',
|
||||
'AUTHOR': 'Der Tester',
|
||||
'LOCALE': 'de_DE.UTF-8',
|
||||
},
|
||||
'cz': {
|
||||
'SITENAME': 'Testovací stránka',
|
||||
'AUTHOR': 'Test Testovič',
|
||||
'I18N_UNTRANSLATED_PAGES': 'remove',
|
||||
'I18N_UNTRANSLATED_ARTICLES': 'keep',
|
||||
},
|
||||
}
|
139
plugins/i18n_subsites/test_i18n_subsites.py
Normal file
139
plugins/i18n_subsites/test_i18n_subsites.py
Normal file
@ -0,0 +1,139 @@
|
||||
'''Unit tests for the i18n_subsites plugin'''
|
||||
|
||||
import os
|
||||
import locale
|
||||
import unittest
|
||||
import subprocess
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
|
||||
from . import i18n_subsites as i18ns
|
||||
from pelican import Pelican
|
||||
from pelican.tests.support import get_settings
|
||||
from pelican.settings import read_settings
|
||||
|
||||
|
||||
class TestTemporaryLocale(unittest.TestCase):
|
||||
'''Test the temporary locale context manager'''
|
||||
|
||||
def test_locale_restored(self):
|
||||
'''Test that the locale is restored after exiting context'''
|
||||
orig_locale = locale.setlocale(locale.LC_ALL)
|
||||
with i18ns.temporary_locale():
|
||||
locale.setlocale(locale.LC_ALL, 'C')
|
||||
self.assertEqual(locale.setlocale(locale.LC_ALL), 'C')
|
||||
self.assertEqual(locale.setlocale(locale.LC_ALL), orig_locale)
|
||||
|
||||
def test_temp_locale_set(self):
|
||||
'''Test that the temporary locale is set'''
|
||||
with i18ns.temporary_locale('C'):
|
||||
self.assertEqual(locale.setlocale(locale.LC_ALL), 'C')
|
||||
|
||||
|
||||
class TestSettingsManipulation(unittest.TestCase):
|
||||
'''Test operations on settings dict'''
|
||||
|
||||
def setUp(self):
|
||||
'''Prepare default settings'''
|
||||
self.settings = get_settings()
|
||||
|
||||
def test_get_pelican_cls_class(self):
|
||||
'''Test that we get class given as an object'''
|
||||
self.settings['PELICAN_CLASS'] = object
|
||||
cls = i18ns.get_pelican_cls(self.settings)
|
||||
self.assertIs(cls, object)
|
||||
|
||||
def test_get_pelican_cls_str(self):
|
||||
'''Test that we get correct class given by string'''
|
||||
cls = i18ns.get_pelican_cls(self.settings)
|
||||
self.assertIs(cls, Pelican)
|
||||
|
||||
|
||||
class TestSitesRelpath(unittest.TestCase):
|
||||
'''Test relative path between sites generation'''
|
||||
|
||||
def setUp(self):
|
||||
'''Generate some sample siteurls'''
|
||||
self.siteurl = 'http://example.com'
|
||||
i18ns._SITE_DB['en'] = self.siteurl
|
||||
i18ns._SITE_DB['de'] = self.siteurl + '/de'
|
||||
|
||||
def tearDown(self):
|
||||
'''Remove sites from db'''
|
||||
i18ns._SITE_DB.clear()
|
||||
|
||||
def test_get_site_path(self):
|
||||
'''Test getting the path within a site'''
|
||||
self.assertEqual(i18ns.get_site_path(self.siteurl), '/')
|
||||
self.assertEqual(i18ns.get_site_path(self.siteurl + '/de'), '/de')
|
||||
|
||||
def test_relpath_to_site(self):
|
||||
'''Test getting relative paths between sites'''
|
||||
self.assertEqual(i18ns.relpath_to_site('en', 'de'), 'de')
|
||||
self.assertEqual(i18ns.relpath_to_site('de', 'en'), '..')
|
||||
|
||||
|
||||
class TestRegistration(unittest.TestCase):
|
||||
'''Test plugin registration'''
|
||||
|
||||
def test_return_on_missing_signal(self):
|
||||
'''Test return on missing required signal'''
|
||||
i18ns._SIGNAL_HANDLERS_DB['tmp_sig'] = None
|
||||
i18ns.register()
|
||||
self.assertNotIn(id(i18ns.save_generator),
|
||||
i18ns.signals.generator_init.receivers)
|
||||
|
||||
def test_registration(self):
|
||||
'''Test registration of all signal handlers'''
|
||||
i18ns.register()
|
||||
for sig_name, handler in i18ns._SIGNAL_HANDLERS_DB.items():
|
||||
sig = getattr(i18ns.signals, sig_name)
|
||||
self.assertIn(id(handler), sig.receivers)
|
||||
# clean up
|
||||
sig.disconnect(handler)
|
||||
|
||||
|
||||
class TestFullRun(unittest.TestCase):
|
||||
'''Test running Pelican with the Plugin'''
|
||||
|
||||
def setUp(self):
|
||||
'''Create temporary output and cache folders'''
|
||||
self.temp_path = mkdtemp(prefix='pelicantests.')
|
||||
self.temp_cache = mkdtemp(prefix='pelican_cache.')
|
||||
|
||||
def tearDown(self):
|
||||
'''Remove output and cache folders'''
|
||||
rmtree(self.temp_path)
|
||||
rmtree(self.temp_cache)
|
||||
|
||||
def test_sites_generation(self):
|
||||
'''Test generation of sites with the plugin
|
||||
|
||||
Compare with recorded output via ``git diff``.
|
||||
To generate output for comparison run the command
|
||||
``pelican -o test_data/output -s test_data/pelicanconf.py \
|
||||
test_data/content``
|
||||
Remember to remove the output/ folder before that.
|
||||
'''
|
||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||
base_path = os.path.join(base_path, 'test_data')
|
||||
content_path = os.path.join(base_path, 'content')
|
||||
output_path = os.path.join(base_path, 'output')
|
||||
settings_path = os.path.join(base_path, 'pelicanconf.py')
|
||||
settings = read_settings(path=settings_path, override={
|
||||
'PATH': content_path,
|
||||
'OUTPUT_PATH': self.temp_path,
|
||||
'CACHE_PATH': self.temp_cache,
|
||||
'PLUGINS': [i18ns],
|
||||
}
|
||||
)
|
||||
pelican = Pelican(settings)
|
||||
pelican.run()
|
||||
|
||||
# compare output
|
||||
out, err = subprocess.Popen(
|
||||
['git', 'diff', '--no-ext-diff', '--exit-code', '-w', output_path,
|
||||
self.temp_path], env={'PAGER': ''},
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
|
||||
self.assertFalse(out, 'non-empty `diff` stdout:\n{}'.format(out))
|
||||
self.assertFalse(err, 'non-empty `diff` stderr:\n{}'.format(out))
|
@ -1 +0,0 @@
|
||||
from .list_files import *
|
@ -1,40 +0,0 @@
|
||||
from pelican import signals, contents
|
||||
from os import listdir, getcwd
|
||||
from os.path import isfile, join, sep, split
|
||||
from copy import copy
|
||||
from itertools import chain
|
||||
|
||||
'''
|
||||
This plugin creates a URL hierarchy for articles that matches the
|
||||
directory hierarchy of their sources.
|
||||
'''
|
||||
|
||||
def lsfiles(path):
|
||||
return [f for f in listdir(path) if isfile(join(path, f))]
|
||||
|
||||
def save_files(content_object):
|
||||
if type(content_object) is not contents.Article:
|
||||
return
|
||||
article = content_object
|
||||
path = split(article.get_relative_source_path())[0] + '/'
|
||||
path = path.replace(sep, '/' )
|
||||
abs_path = getcwd() + "/content/" + path
|
||||
|
||||
files = {i:(path+i) for i in lsfiles(abs_path)}
|
||||
try:
|
||||
fig_files = lsfiles(abs_path+"/fig")
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
else:
|
||||
fig_files = {i:(path+"fig/"+i) for i in fig_files}
|
||||
files.update(fig_files)
|
||||
|
||||
article.link_files = []
|
||||
|
||||
for i in files.items():
|
||||
article.link_files.append(i)
|
||||
|
||||
article.link_files.sort()
|
||||
|
||||
def register():
|
||||
signals.content_object_init.connect(save_files)
|
@ -11,7 +11,7 @@ sys.path.append(os.curdir)
|
||||
from pelicanconf import *
|
||||
|
||||
# If your site is available via HTTPS, make sure SITEURL begins with https://
|
||||
SITEURL = 'https://opytex.org/enseignements/2019-2020/'
|
||||
SITEURL = 'n'
|
||||
RELATIVE_URLS = False
|
||||
|
||||
FEED_ALL_ATOM = 'feeds/all.atom.xml'
|
||||
|
@ -1,11 +0,0 @@
|
||||
blinker==1.4
|
||||
docutils==0.13.1
|
||||
feedgenerator==1.9
|
||||
Jinja2==2.9.6
|
||||
MarkupSafe==1.0
|
||||
pelican==3.7.1
|
||||
Pygments==2.2.0
|
||||
python-dateutil==2.6.0
|
||||
pytz==2017.2
|
||||
six==1.10.0
|
||||
Unidecode==0.4.20
|
110
tasks.py
Normal file
110
tasks.py
Normal file
@ -0,0 +1,110 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
from invoke import task
|
||||
from invoke.util import cd
|
||||
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
|
||||
from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
|
||||
|
||||
SETTINGS_FILE_BASE = 'pelicanconf.py'
|
||||
SETTINGS = {}
|
||||
SETTINGS.update(DEFAULT_CONFIG)
|
||||
LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
|
||||
SETTINGS.update(LOCAL_SETTINGS)
|
||||
|
||||
CONFIG = {
|
||||
'settings_base': SETTINGS_FILE_BASE,
|
||||
'settings_publish': 'publishconf.py',
|
||||
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
|
||||
'deploy_path': SETTINGS['OUTPUT_PATH'],
|
||||
# Port for `serve`
|
||||
'port': 8000,
|
||||
}
|
||||
|
||||
@task
|
||||
def clean(c):
|
||||
"""Remove generated files"""
|
||||
if os.path.isdir(CONFIG['deploy_path']):
|
||||
shutil.rmtree(CONFIG['deploy_path'])
|
||||
os.makedirs(CONFIG['deploy_path'])
|
||||
|
||||
@task
|
||||
def build(c):
|
||||
"""Build local version of site"""
|
||||
c.run('pelican -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def rebuild(c):
|
||||
"""`build` with the delete switch"""
|
||||
c.run('pelican -d -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def regenerate(c):
|
||||
"""Automatically regenerate site upon file modification"""
|
||||
c.run('pelican -r -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def serve(c):
|
||||
"""Serve site at http://localhost:$PORT/ (default port is 8000)"""
|
||||
|
||||
class AddressReuseTCPServer(RootedHTTPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
server = AddressReuseTCPServer(
|
||||
CONFIG['deploy_path'],
|
||||
('', CONFIG['port']),
|
||||
ComplexHTTPRequestHandler)
|
||||
|
||||
sys.stderr.write('Serving on port {port} ...\n'.format(**CONFIG))
|
||||
server.serve_forever()
|
||||
|
||||
@task
|
||||
def reserve(c):
|
||||
"""`build`, then `serve`"""
|
||||
build(c)
|
||||
serve(c)
|
||||
|
||||
@task
|
||||
def preview(c):
|
||||
"""Build production version of site"""
|
||||
c.run('pelican -s {settings_publish}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
def livereload(c):
|
||||
"""Automatically reload browser tab upon file modification."""
|
||||
from livereload import Server
|
||||
build(c)
|
||||
server = Server()
|
||||
# Watch the base settings file
|
||||
server.watch(CONFIG['settings_base'], lambda: build(c))
|
||||
# Watch content source files
|
||||
content_file_extensions = ['.md', '.rst']
|
||||
for extension in content_file_extensions:
|
||||
content_blob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
|
||||
server.watch(content_blob, lambda: build(c))
|
||||
# Watch the theme's templates and static assets
|
||||
theme_path = SETTINGS['THEME']
|
||||
server.watch('{}/templates/*.html'.format(theme_path), lambda: build(c))
|
||||
static_file_extensions = ['.css', '.js']
|
||||
for extension in static_file_extensions:
|
||||
static_file = '{0}/static/**/*{1}'.format(theme_path, extension)
|
||||
server.watch(static_file, lambda: build(c))
|
||||
# Serve output path on configured port
|
||||
server.serve(port=CONFIG['port'], root=CONFIG['deploy_path'])
|
||||
|
||||
|
||||
@task
|
||||
def publish(c):
|
||||
"""Publish to production via rsync"""
|
||||
c.run('pelican -s {settings_publish}'.format(**CONFIG))
|
||||
c.run(
|
||||
'rsync --delete --exclude ".DS_Store" -pthrvz -c '
|
||||
'-e "ssh -p {ssh_port}" '
|
||||
'{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
|
||||
CONFIG['deploy_path'].rstrip('/') + '/',
|
||||
**CONFIG))
|
||||
|
59
theme/.gitignore
vendored
59
theme/.gitignore
vendored
@ -1,59 +0,0 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
tests/output
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
venv
|
||||
|
||||
# NPM
|
||||
node_modules
|
@ -1,13 +0,0 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
install:
|
||||
- pip install pelican markdown
|
||||
before_script:
|
||||
- git clone https://github.com/getpelican/pelican-plugins plugins
|
||||
script: pelican -s tests/pelicanconf.py
|
||||
notifications:
|
||||
email: false
|
@ -2,11 +2,9 @@
|
||||
|
||||
The minimalist [Pelican](http://blog.getpelican.com/) theme.
|
||||
|
||||
## Notes
|
||||
## Note
|
||||
|
||||
- **DO NOT** send any questions to my personal email, they are **IGNORED**. If you have questions open an issue.
|
||||
- This theme is not under development anymore, it's stable and has a lot of features. This means that new requests (not bug fixes) will be discussed and have lower priorities.
|
||||
- If you want a version of this theme to Jekyll or Hugo open an issue and let's discuss it.
|
||||
DON'T send any questions, issues or anything related to Flex to my personal email. They will be IGNORED by now. Your question maybe also is someone else's question. They SHOULD be public, so others can know how to fix configuration problems.
|
||||
|
||||
## Features
|
||||
|
||||
@ -26,7 +24,7 @@ The minimalist [Pelican](http://blog.getpelican.com/) theme.
|
||||
- [AddThis](http://www.addthis.com/) Share Buttons and Related Posts
|
||||
- [Disqus](https://disqus.com/)
|
||||
- [Gauges Analytics](http://get.gaug.es/)
|
||||
- [Google AdSense](https://www.google.com.br/adsense/start/) (new in 2.1.0)
|
||||
- [Google AdSense](https://www.google.com.br/adsense/start/) (new in 2.1)
|
||||
- [Google Analytics](https://www.google.com/analytics/web/)
|
||||
- [Google Tag Manager](https://www.google.com/tagmanager/)
|
||||
- [Piwik Analytics](http://piwik.org/)
|
||||
@ -34,18 +32,28 @@ The minimalist [Pelican](http://blog.getpelican.com/) theme.
|
||||
|
||||
## Plugins Support
|
||||
|
||||
- [Github Corners](https://github.com/tholman/github-corners) (new in 2.2.0)
|
||||
- [Github Corners](https://github.com/tholman/github-corners) (new in 2.2)
|
||||
- [I18N Sub-sites](https://github.com/getpelican/pelican-plugins/tree/master/i18n_subsites) (new in 2.0)
|
||||
- [Minute read](https://github.com/getpelican/pelican-plugins/tree/master/post_stats) (new in 2.0)
|
||||
- [Related Posts](https://github.com/getpelican/pelican-plugins/tree/master/related_posts)
|
||||
- [Representative image](https://github.com/getpelican/pelican-plugins/tree/master/representative_image) (new in 2.2.0)
|
||||
- [Neighbors](https://github.com/getpelican/pelican-plugins/tree/master/neighbors) (new in 2.2.0)
|
||||
- [Representative image](https://github.com/getpelican/pelican-plugins/tree/master/representative_image) (new in 2.2)
|
||||
- [Neighbors](https://github.com/getpelican/pelican-plugins/tree/master/neighbors) (new in 2.2)
|
||||
|
||||
## Install
|
||||
|
||||
The best way to install is over [pelican-themes](https://github.com/getpelican/pelican-themes).
|
||||
The recommend way to install is over [pelican-themes](https://github.com/getpelican/pelican-themes).
|
||||
|
||||
The alternative way is to clone this repository. The `master` branch is stable and is safe to checkout, but I would recommend you to checkout a tag branch.
|
||||
The `master` branch is the development branch. If you're happy with fresh new things and maybe broken things you can clone the `master`, but I would recommend to you to clone a tag branch.
|
||||
|
||||
## Documentation
|
||||
|
||||
[Go to Wiki](https://github.com/alexandrevicenzi/Flex/wiki)
|
||||
|
||||
## Contributing
|
||||
|
||||
Always open an issue before sending a PR. Talk about the problem/feature that you want to fix. If it's really a good thing you can submit your PR. If you send an PR without talking about before what it is, you may work for nothing.
|
||||
|
||||
As always, if you want something that only make sense to you, just fork Flex and start a new theme.
|
||||
|
||||
## Donate
|
||||
|
||||
@ -53,34 +61,19 @@ Are you using this theme? Support bug fixes and new features.
|
||||
|
||||
[Click here](https://www.alexandrevicenzi.com/donate) to donate.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation covers most of the settings available and how to use this theme.
|
||||
If something is missing or broken you can open a PR or fix the documentation by yourself.
|
||||
|
||||
[Flex Wiki](https://github.com/alexandrevicenzi/Flex/wiki)
|
||||
|
||||
## Live example
|
||||
|
||||
You can see how this theme looks like at [http://flex.alxd.me/blog/](http://flex.alxd.me/blog/).
|
||||
|
||||
The code is available in this project under `docs` folder.
|
||||
The code is available in this project inside `docs` folder.
|
||||
|
||||
## Contributing
|
||||
|
||||
**ALWAYS** open an issue before sending a PR.
|
||||
Discuss the problem/feature that you want to code.
|
||||
After discussing, send a PR with your changes.
|
||||
|
||||
As always, if you want something that only makes sense to you, fork Flex and create a new theme.
|
||||
|
||||
## Translations
|
||||
## Translate
|
||||
|
||||
Translate this theme to new languages at [Transifex](https://www.transifex.com/alexandrevicenzi/flex-pelican/).
|
||||
|
||||
![Translations](https://github.com/alexandrevicenzi/Flex/blob/master/translations/translation_chart.png)
|
||||
|
||||
Read more about [Translation Support](https://github.com/alexandrevicenzi/Flex/wiki/Translations) in the Wiki.
|
||||
Read more about [Translation Support](https://github.com/alexandrevicenzi/Flex/wiki/Translations).
|
||||
|
||||
## License
|
||||
|
||||
|
1
theme/node_modules/.bin/atob
generated
vendored
Symbolic link
1
theme/node_modules/.bin/atob
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../atob/bin/atob.js
|
1
theme/node_modules/.bin/color-support
generated
vendored
Symbolic link
1
theme/node_modules/.bin/color-support
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../color-support/bin.js
|
1
theme/node_modules/.bin/gulp
generated
vendored
Symbolic link
1
theme/node_modules/.bin/gulp
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../gulp/bin/gulp.js
|
1
theme/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
1
theme/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../mkdirp/bin/cmd.js
|
1
theme/node_modules/.bin/semver
generated
vendored
Symbolic link
1
theme/node_modules/.bin/semver
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../semver/bin/semver
|
1
theme/node_modules/.bin/strip-bom
generated
vendored
Symbolic link
1
theme/node_modules/.bin/strip-bom
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../strip-bom/cli.js
|
1
theme/node_modules/.bin/user-home
generated
vendored
Symbolic link
1
theme/node_modules/.bin/user-home
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../user-home/cli.js
|
1
theme/node_modules/.bin/which
generated
vendored
Symbolic link
1
theme/node_modules/.bin/which
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../which/bin/which
|
21
theme/node_modules/ansi-gray/LICENSE
generated
vendored
Normal file
21
theme/node_modules/ansi-gray/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <%= year() %>, Jon Schlinkert.
|
||||
|
||||
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.
|
14
theme/node_modules/ansi-gray/index.js
generated
vendored
Normal file
14
theme/node_modules/ansi-gray/index.js
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*!
|
||||
* ansi-gray <https://github.com/jonschlinkert/ansi-gray>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var wrap = require('ansi-wrap');
|
||||
|
||||
module.exports = function gray(message) {
|
||||
return wrap(90, 39, message);
|
||||
};
|
86
theme/node_modules/ansi-gray/package.json
generated
vendored
Normal file
86
theme/node_modules/ansi-gray/package.json
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
{
|
||||
"_from": "ansi-gray@^0.1.1",
|
||||
"_id": "ansi-gray@0.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
|
||||
"_location": "/ansi-gray",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ansi-gray@^0.1.1",
|
||||
"name": "ansi-gray",
|
||||
"escapedName": "ansi-gray",
|
||||
"rawSpec": "^0.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/fancy-log"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
|
||||
"_shasum": "2962cf54ec9792c48510a3deb524436861ef7251",
|
||||
"_spec": "ansi-gray@^0.1.1",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/fancy-log",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/ansi-gray/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"ansi-wrap": "0.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "The color gray, in ansi.",
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/ansi-gray",
|
||||
"keywords": [
|
||||
"gray",
|
||||
"256",
|
||||
"ansi",
|
||||
"cli",
|
||||
"color",
|
||||
"colors",
|
||||
"colour",
|
||||
"command",
|
||||
"command-line",
|
||||
"console",
|
||||
"format",
|
||||
"formatting",
|
||||
"iterm",
|
||||
"log",
|
||||
"logging",
|
||||
"rgb",
|
||||
"shell",
|
||||
"string",
|
||||
"style",
|
||||
"styles",
|
||||
"styling",
|
||||
"terminal",
|
||||
"text",
|
||||
"tty",
|
||||
"xterm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "ansi-gray",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/ansi-gray.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "0.1.1"
|
||||
}
|
74
theme/node_modules/ansi-gray/readme.md
generated
vendored
Normal file
74
theme/node_modules/ansi-gray/readme.md
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
# ansi-gray [![NPM version](https://badge.fury.io/js/ansi-gray.svg)](http://badge.fury.io/js/ansi-gray)
|
||||
|
||||
> The color gray, in ansi.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i ansi-gray --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var gray = require('ansi-gray');
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
* [ansi-reset](https://github.com/jonschlinkert/ansi-reset)
|
||||
* [ansi-bold](https://github.com/jonschlinkert/ansi-bold)
|
||||
* [ansi-dim](https://github.com/jonschlinkert/ansi-dim)
|
||||
* [ansi-italic](https://github.com/jonschlinkert/ansi-italic)
|
||||
* [ansi-underline](https://github.com/jonschlinkert/ansi-underline)
|
||||
* [ansi-inverse](https://github.com/jonschlinkert/ansi-inverse)
|
||||
* [ansi-hidden](https://github.com/jonschlinkert/ansi-hidden)
|
||||
* [ansi-strikethrough](https://github.com/jonschlinkert/ansi-strikethrough)
|
||||
* [ansi-black](https://github.com/jonschlinkert/ansi-black)
|
||||
* [ansi-red](https://github.com/jonschlinkert/ansi-red)
|
||||
* [ansi-green](https://github.com/jonschlinkert/ansi-green)
|
||||
* [ansi-yellow](https://github.com/jonschlinkert/ansi-yellow)
|
||||
* [ansi-blue](https://github.com/jonschlinkert/ansi-blue)
|
||||
* [ansi-magenta](https://github.com/jonschlinkert/ansi-magenta)
|
||||
* [ansi-cyan](https://github.com/jonschlinkert/ansi-cyan)
|
||||
* [ansi-white](https://github.com/jonschlinkert/ansi-white)
|
||||
* [ansi-gray](https://github.com/jonschlinkert/ansi-gray)
|
||||
* [ansi-grey](https://github.com/jonschlinkert/ansi-grey)
|
||||
* [ansi-bgblack](https://github.com/jonschlinkert/ansi-bgblack)
|
||||
* [ansi-bgred](https://github.com/jonschlinkert/ansi-bgred)
|
||||
* [ansi-bggreen](https://github.com/jonschlinkert/ansi-bggreen)
|
||||
* [ansi-bgyellow](https://github.com/jonschlinkert/ansi-bgyellow)
|
||||
* [ansi-bgblue](https://github.com/jonschlinkert/ansi-bgblue)
|
||||
* [ansi-bgmagenta](https://github.com/jonschlinkert/ansi-bgmagenta)
|
||||
* [ansi-bgcyan](https://github.com/jonschlinkert/ansi-bgcyan)
|
||||
* [ansi-bgwhite](https://github.com/jonschlinkert/ansi-bgwhite)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/ansi-gray/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 21, 2015._
|
4
theme/node_modules/ansi-regex/index.js
generated
vendored
Normal file
4
theme/node_modules/ansi-regex/index.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]/g;
|
||||
};
|
21
theme/node_modules/ansi-regex/license
generated
vendored
Normal file
21
theme/node_modules/ansi-regex/license
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
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.
|
109
theme/node_modules/ansi-regex/package.json
generated
vendored
Normal file
109
theme/node_modules/ansi-regex/package.json
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
{
|
||||
"_from": "ansi-regex@^2.0.0",
|
||||
"_id": "ansi-regex@2.1.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"_location": "/ansi-regex",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ansi-regex@^2.0.0",
|
||||
"name": "ansi-regex",
|
||||
"escapedName": "ansi-regex",
|
||||
"rawSpec": "^2.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/has-ansi",
|
||||
"/strip-ansi"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"_shasum": "c3b33ab5ee360d86e0e628f0468ae7ef27d654df",
|
||||
"_spec": "ansi-regex@^2.0.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/has-ansi",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/chalk/ansi-regex/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Regular expression for matching ANSI escape codes",
|
||||
"devDependencies": {
|
||||
"ava": "0.17.0",
|
||||
"xo": "0.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/chalk/ansi-regex#readme",
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"command-line",
|
||||
"text",
|
||||
"regex",
|
||||
"regexp",
|
||||
"re",
|
||||
"match",
|
||||
"test",
|
||||
"find",
|
||||
"pattern"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
{
|
||||
"name": "Joshua Appelman",
|
||||
"email": "jappelman@xebia.com",
|
||||
"url": "jbnicolai.com"
|
||||
},
|
||||
{
|
||||
"name": "JD Ballard",
|
||||
"email": "i.am.qix@gmail.com",
|
||||
"url": "github.com/qix-"
|
||||
}
|
||||
],
|
||||
"name": "ansi-regex",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/chalk/ansi-regex.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava --verbose",
|
||||
"view-supported": "node fixtures/view-codes.js"
|
||||
},
|
||||
"version": "2.1.1",
|
||||
"xo": {
|
||||
"rules": {
|
||||
"guard-for-in": 0,
|
||||
"no-loop-func": 0
|
||||
}
|
||||
}
|
||||
}
|
39
theme/node_modules/ansi-regex/readme.md
generated
vendored
Normal file
39
theme/node_modules/ansi-regex/readme.md
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
|
||||
|
||||
> Regular expression for matching [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-regex
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const ansiRegex = require('ansi-regex');
|
||||
|
||||
ansiRegex().test('\u001b[4mcake\u001b[0m');
|
||||
//=> true
|
||||
|
||||
ansiRegex().test('cake');
|
||||
//=> false
|
||||
|
||||
'\u001b[4mcake\u001b[0m'.match(ansiRegex());
|
||||
//=> ['\u001b[4m', '\u001b[0m']
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why do you test for codes not in the ECMA 48 standard?
|
||||
|
||||
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. If I recall correctly, we test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
|
||||
|
||||
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
65
theme/node_modules/ansi-styles/index.js
generated
vendored
Normal file
65
theme/node_modules/ansi-styles/index.js
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
function assembleStyles () {
|
||||
var styles = {
|
||||
modifiers: {
|
||||
reset: [0, 0],
|
||||
bold: [1, 22], // 21 isn't widely supported and 22 does the same thing
|
||||
dim: [2, 22],
|
||||
italic: [3, 23],
|
||||
underline: [4, 24],
|
||||
inverse: [7, 27],
|
||||
hidden: [8, 28],
|
||||
strikethrough: [9, 29]
|
||||
},
|
||||
colors: {
|
||||
black: [30, 39],
|
||||
red: [31, 39],
|
||||
green: [32, 39],
|
||||
yellow: [33, 39],
|
||||
blue: [34, 39],
|
||||
magenta: [35, 39],
|
||||
cyan: [36, 39],
|
||||
white: [37, 39],
|
||||
gray: [90, 39]
|
||||
},
|
||||
bgColors: {
|
||||
bgBlack: [40, 49],
|
||||
bgRed: [41, 49],
|
||||
bgGreen: [42, 49],
|
||||
bgYellow: [43, 49],
|
||||
bgBlue: [44, 49],
|
||||
bgMagenta: [45, 49],
|
||||
bgCyan: [46, 49],
|
||||
bgWhite: [47, 49]
|
||||
}
|
||||
};
|
||||
|
||||
// fix humans
|
||||
styles.colors.grey = styles.colors.gray;
|
||||
|
||||
Object.keys(styles).forEach(function (groupName) {
|
||||
var group = styles[groupName];
|
||||
|
||||
Object.keys(group).forEach(function (styleName) {
|
||||
var style = group[styleName];
|
||||
|
||||
styles[styleName] = group[styleName] = {
|
||||
open: '\u001b[' + style[0] + 'm',
|
||||
close: '\u001b[' + style[1] + 'm'
|
||||
};
|
||||
});
|
||||
|
||||
Object.defineProperty(styles, groupName, {
|
||||
value: group,
|
||||
enumerable: false
|
||||
});
|
||||
});
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
Object.defineProperty(module, 'exports', {
|
||||
enumerable: true,
|
||||
get: assembleStyles
|
||||
});
|
21
theme/node_modules/ansi-styles/license
generated
vendored
Normal file
21
theme/node_modules/ansi-styles/license
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
||||
|
||||
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.
|
90
theme/node_modules/ansi-styles/package.json
generated
vendored
Normal file
90
theme/node_modules/ansi-styles/package.json
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
{
|
||||
"_from": "ansi-styles@^2.2.1",
|
||||
"_id": "ansi-styles@2.2.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"_location": "/ansi-styles",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ansi-styles@^2.2.1",
|
||||
"name": "ansi-styles",
|
||||
"escapedName": "ansi-styles",
|
||||
"rawSpec": "^2.2.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.2.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/chalk"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"_shasum": "b432dd3358b634cf75e1e4664368240533c1ddbe",
|
||||
"_spec": "ansi-styles@^2.2.1",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/chalk",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/chalk/ansi-styles/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "ANSI escape codes for styling strings in the terminal",
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/chalk/ansi-styles#readme",
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"styles",
|
||||
"color",
|
||||
"colour",
|
||||
"colors",
|
||||
"terminal",
|
||||
"console",
|
||||
"cli",
|
||||
"string",
|
||||
"tty",
|
||||
"escape",
|
||||
"formatting",
|
||||
"rgb",
|
||||
"256",
|
||||
"shell",
|
||||
"xterm",
|
||||
"log",
|
||||
"logging",
|
||||
"command-line",
|
||||
"text"
|
||||
],
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
{
|
||||
"name": "Joshua Appelman",
|
||||
"email": "jappelman@xebia.com",
|
||||
"url": "jbnicolai.com"
|
||||
}
|
||||
],
|
||||
"name": "ansi-styles",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/chalk/ansi-styles.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "2.2.1"
|
||||
}
|
86
theme/node_modules/ansi-styles/readme.md
generated
vendored
Normal file
86
theme/node_modules/ansi-styles/readme.md
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles)
|
||||
|
||||
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
|
||||
|
||||
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
|
||||
|
||||
![](screenshot.png)
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install --save ansi-styles
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var ansi = require('ansi-styles');
|
||||
|
||||
console.log(ansi.green.open + 'Hello world!' + ansi.green.close);
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
Each style has an `open` and `close` property.
|
||||
|
||||
|
||||
## Styles
|
||||
|
||||
### Modifiers
|
||||
|
||||
- `reset`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- `italic` *(not widely supported)*
|
||||
- `underline`
|
||||
- `inverse`
|
||||
- `hidden`
|
||||
- `strikethrough` *(not widely supported)*
|
||||
|
||||
### Colors
|
||||
|
||||
- `black`
|
||||
- `red`
|
||||
- `green`
|
||||
- `yellow`
|
||||
- `blue`
|
||||
- `magenta`
|
||||
- `cyan`
|
||||
- `white`
|
||||
- `gray`
|
||||
|
||||
### Background colors
|
||||
|
||||
- `bgBlack`
|
||||
- `bgRed`
|
||||
- `bgGreen`
|
||||
- `bgYellow`
|
||||
- `bgBlue`
|
||||
- `bgMagenta`
|
||||
- `bgCyan`
|
||||
- `bgWhite`
|
||||
|
||||
|
||||
## Advanced usage
|
||||
|
||||
By default you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
|
||||
|
||||
- `ansi.modifiers`
|
||||
- `ansi.colors`
|
||||
- `ansi.bgColors`
|
||||
|
||||
|
||||
###### Example
|
||||
|
||||
```js
|
||||
console.log(ansi.colors.green.open);
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
21
theme/node_modules/ansi-wrap/LICENSE
generated
vendored
Normal file
21
theme/node_modules/ansi-wrap/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015, Jon Schlinkert.
|
||||
|
||||
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.
|
89
theme/node_modules/ansi-wrap/README.md
generated
vendored
Normal file
89
theme/node_modules/ansi-wrap/README.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
# ansi-wrap [![NPM version](https://badge.fury.io/js/ansi-wrap.svg)](http://badge.fury.io/js/ansi-wrap)
|
||||
|
||||
> Create ansi colors by passing the open and close codes.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i ansi-wrap --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var wrap = require('ansi-wrap');
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
Pass codes for [ansi magenta background](https://github.com/jonschlinkert/ansi-bgmagenta):
|
||||
|
||||
```js
|
||||
console.log(wrap(45, 49, 'This is a message...'));
|
||||
//=> '\u001b[45mfoo\u001b[49m'
|
||||
```
|
||||
|
||||
Which prints out...
|
||||
|
||||
[![screen shot 2015-05-21 at 8 28 32 pm](https://cloud.githubusercontent.com/assets/383994/7761769/12488afa-fff8-11e4-9cc1-71a8a6ec14a4.png)](https://www.npmjs.com/)
|
||||
|
||||
## Related projects
|
||||
|
||||
This is used in these projects:
|
||||
|
||||
* [ansi-reset](https://github.com/jonschlinkert/ansi-reset)
|
||||
* [ansi-bold](https://github.com/jonschlinkert/ansi-bold)
|
||||
* [ansi-dim](https://github.com/jonschlinkert/ansi-dim)
|
||||
* [ansi-italic](https://github.com/jonschlinkert/ansi-italic)
|
||||
* [ansi-underline](https://github.com/jonschlinkert/ansi-underline)
|
||||
* [ansi-inverse](https://github.com/jonschlinkert/ansi-inverse)
|
||||
* [ansi-hidden](https://github.com/jonschlinkert/ansi-hidden)
|
||||
* [ansi-strikethrough](https://github.com/jonschlinkert/ansi-strikethrough)
|
||||
* [ansi-black](https://github.com/jonschlinkert/ansi-black)
|
||||
* [ansi-red](https://github.com/jonschlinkert/ansi-red)
|
||||
* [ansi-green](https://github.com/jonschlinkert/ansi-green)
|
||||
* [ansi-yellow](https://github.com/jonschlinkert/ansi-yellow)
|
||||
* [ansi-blue](https://github.com/jonschlinkert/ansi-blue)
|
||||
* [ansi-magenta](https://github.com/jonschlinkert/ansi-magenta)
|
||||
* [ansi-cyan](https://github.com/jonschlinkert/ansi-cyan)
|
||||
* [ansi-white](https://github.com/jonschlinkert/ansi-white)
|
||||
* [ansi-gray](https://github.com/jonschlinkert/ansi-gray)
|
||||
* [ansi-grey](https://github.com/jonschlinkert/ansi-grey)
|
||||
* [ansi-bgblack](https://github.com/jonschlinkert/ansi-bgblack)
|
||||
* [ansi-bgred](https://github.com/jonschlinkert/ansi-bgred)
|
||||
* [ansi-bggreen](https://github.com/jonschlinkert/ansi-bggreen)
|
||||
* [ansi-bgyellow](https://github.com/jonschlinkert/ansi-bgyellow)
|
||||
* [ansi-bgblue](https://github.com/jonschlinkert/ansi-bgblue)
|
||||
* [ansi-bgmagenta](https://github.com/jonschlinkert/ansi-bgmagenta)
|
||||
* [ansi-bgcyan](https://github.com/jonschlinkert/ansi-bgcyan)
|
||||
* [ansi-bgwhite](https://github.com/jonschlinkert/ansi-bgwhite)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/ansi-wrap/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 21, 2015._
|
5
theme/node_modules/ansi-wrap/index.js
generated
vendored
Normal file
5
theme/node_modules/ansi-wrap/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function(a, b, msg) {
|
||||
return '\u001b['+ a + 'm' + msg + '\u001b[' + b + 'm';
|
||||
};
|
59
theme/node_modules/ansi-wrap/package.json
generated
vendored
Normal file
59
theme/node_modules/ansi-wrap/package.json
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"_from": "ansi-wrap@0.1.0",
|
||||
"_id": "ansi-wrap@0.1.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
|
||||
"_location": "/ansi-wrap",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "ansi-wrap@0.1.0",
|
||||
"name": "ansi-wrap",
|
||||
"escapedName": "ansi-wrap",
|
||||
"rawSpec": "0.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "0.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/ansi-gray"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
|
||||
"_shasum": "a82250ddb0015e9a27ca82e82ea603bbfa45efaf",
|
||||
"_spec": "ansi-wrap@0.1.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/ansi-gray",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/ansi-wrap/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Create ansi colors by passing the open and close codes.",
|
||||
"devDependencies": {},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/ansi-wrap",
|
||||
"keywords": [],
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/ansi-wrap/blob/master/LICENSE"
|
||||
},
|
||||
"main": "index.js",
|
||||
"name": "ansi-wrap",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/ansi-wrap.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "0.1.0"
|
||||
}
|
4
theme/node_modules/archy/.travis.yml
generated
vendored
Normal file
4
theme/node_modules/archy/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
18
theme/node_modules/archy/LICENSE
generated
vendored
Normal file
18
theme/node_modules/archy/LICENSE
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
This software is released under the MIT license:
|
||||
|
||||
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.
|
24
theme/node_modules/archy/examples/beep.js
generated
vendored
Normal file
24
theme/node_modules/archy/examples/beep.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
var archy = require('../');
|
||||
var s = archy({
|
||||
label : 'beep',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny' ]
|
||||
},
|
||||
'human'
|
||||
]
|
||||
},
|
||||
'party\ntime!'
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
console.log(s);
|
25
theme/node_modules/archy/examples/multi_line.js
generated
vendored
Normal file
25
theme/node_modules/archy/examples/multi_line.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
var archy = require('../');
|
||||
|
||||
var s = archy({
|
||||
label : 'beep\none\ntwo',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O\nwheee',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny\nmeat' ]
|
||||
},
|
||||
'creature'
|
||||
]
|
||||
},
|
||||
'party\ntime!'
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
console.log(s);
|
35
theme/node_modules/archy/index.js
generated
vendored
Normal file
35
theme/node_modules/archy/index.js
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
module.exports = function archy (obj, prefix, opts) {
|
||||
if (prefix === undefined) prefix = '';
|
||||
if (!opts) opts = {};
|
||||
var chr = function (s) {
|
||||
var chars = {
|
||||
'│' : '|',
|
||||
'└' : '`',
|
||||
'├' : '+',
|
||||
'─' : '-',
|
||||
'┬' : '-'
|
||||
};
|
||||
return opts.unicode === false ? chars[s] : s;
|
||||
};
|
||||
|
||||
if (typeof obj === 'string') obj = { label : obj };
|
||||
|
||||
var nodes = obj.nodes || [];
|
||||
var lines = (obj.label || '').split('\n');
|
||||
var splitter = '\n' + prefix + (nodes.length ? chr('│') : ' ') + ' ';
|
||||
|
||||
return prefix
|
||||
+ lines.join(splitter) + '\n'
|
||||
+ nodes.map(function (node, ix) {
|
||||
var last = ix === nodes.length - 1;
|
||||
var more = node.nodes && node.nodes.length;
|
||||
var prefix_ = prefix + (last ? ' ' : chr('│')) + ' ';
|
||||
|
||||
return prefix
|
||||
+ (last ? chr('└') : chr('├')) + chr('─')
|
||||
+ (more ? chr('┬') : chr('─')) + ' '
|
||||
+ archy(node, prefix_, opts).slice(prefix.length + 2)
|
||||
;
|
||||
}).join('')
|
||||
;
|
||||
};
|
83
theme/node_modules/archy/package.json
generated
vendored
Normal file
83
theme/node_modules/archy/package.json
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
{
|
||||
"_from": "archy@^1.0.0",
|
||||
"_id": "archy@1.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
|
||||
"_location": "/archy",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "archy@^1.0.0",
|
||||
"name": "archy",
|
||||
"escapedName": "archy",
|
||||
"rawSpec": "^1.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^1.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/gulp"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
|
||||
"_shasum": "f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40",
|
||||
"_spec": "archy@^1.0.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/gulp",
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/substack/node-archy/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "render nested hierarchies `npm ls` style with unicode pipes",
|
||||
"devDependencies": {
|
||||
"tap": "~0.3.3",
|
||||
"tape": "~0.1.1"
|
||||
},
|
||||
"homepage": "https://github.com/substack/node-archy#readme",
|
||||
"keywords": [
|
||||
"hierarchy",
|
||||
"npm ls",
|
||||
"unicode",
|
||||
"pretty",
|
||||
"print"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "archy",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/substack/node-archy.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test"
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": {
|
||||
"iexplore": [
|
||||
"6.0",
|
||||
"7.0",
|
||||
"8.0",
|
||||
"9.0"
|
||||
],
|
||||
"chrome": [
|
||||
"20.0"
|
||||
],
|
||||
"firefox": [
|
||||
"10.0",
|
||||
"15.0"
|
||||
],
|
||||
"safari": [
|
||||
"5.1"
|
||||
],
|
||||
"opera": [
|
||||
"12.0"
|
||||
]
|
||||
}
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
88
theme/node_modules/archy/readme.markdown
generated
vendored
Normal file
88
theme/node_modules/archy/readme.markdown
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
# archy
|
||||
|
||||
Render nested hierarchies `npm ls` style with unicode pipes.
|
||||
|
||||
[![browser support](http://ci.testling.com/substack/node-archy.png)](http://ci.testling.com/substack/node-archy)
|
||||
|
||||
[![build status](https://secure.travis-ci.org/substack/node-archy.png)](http://travis-ci.org/substack/node-archy)
|
||||
|
||||
# example
|
||||
|
||||
``` js
|
||||
var archy = require('archy');
|
||||
var s = archy({
|
||||
label : 'beep',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny' ]
|
||||
},
|
||||
'human'
|
||||
]
|
||||
},
|
||||
'party\ntime!'
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
console.log(s);
|
||||
```
|
||||
|
||||
output
|
||||
|
||||
```
|
||||
beep
|
||||
├── ity
|
||||
└─┬ boop
|
||||
├─┬ o_O
|
||||
│ ├─┬ oh
|
||||
│ │ ├── hello
|
||||
│ │ └── puny
|
||||
│ └── human
|
||||
└── party
|
||||
time!
|
||||
```
|
||||
|
||||
# methods
|
||||
|
||||
var archy = require('archy')
|
||||
|
||||
## archy(obj, prefix='', opts={})
|
||||
|
||||
Return a string representation of `obj` with unicode pipe characters like how
|
||||
`npm ls` looks.
|
||||
|
||||
`obj` should be a tree of nested objects with `'label'` and `'nodes'` fields.
|
||||
`'label'` is a string of text to display at a node level and `'nodes'` is an
|
||||
array of the descendents of the current node.
|
||||
|
||||
If a node is a string, that string will be used as the `'label'` and an empty
|
||||
array of `'nodes'` will be used.
|
||||
|
||||
`prefix` gets prepended to all the lines and is used by the algorithm to
|
||||
recursively update.
|
||||
|
||||
If `'label'` has newlines they will be indented at the present indentation level
|
||||
with the current prefix.
|
||||
|
||||
To disable unicode results in favor of all-ansi output set `opts.unicode` to
|
||||
`false`.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install archy
|
||||
```
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
40
theme/node_modules/archy/test/beep.js
generated
vendored
Normal file
40
theme/node_modules/archy/test/beep.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
var test = require('tape');
|
||||
var archy = require('../');
|
||||
|
||||
test('beep', function (t) {
|
||||
var s = archy({
|
||||
label : 'beep',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny' ]
|
||||
},
|
||||
'human'
|
||||
]
|
||||
},
|
||||
'party!'
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(s, [
|
||||
'beep',
|
||||
'├── ity',
|
||||
'└─┬ boop',
|
||||
' ├─┬ o_O',
|
||||
' │ ├─┬ oh',
|
||||
' │ │ ├── hello',
|
||||
' │ │ └── puny',
|
||||
' │ └── human',
|
||||
' └── party!',
|
||||
''
|
||||
].join('\n'));
|
||||
t.end();
|
||||
});
|
45
theme/node_modules/archy/test/multi_line.js
generated
vendored
Normal file
45
theme/node_modules/archy/test/multi_line.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
var test = require('tape');
|
||||
var archy = require('../');
|
||||
|
||||
test('multi-line', function (t) {
|
||||
var s = archy({
|
||||
label : 'beep\none\ntwo',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O\nwheee',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny\nmeat' ]
|
||||
},
|
||||
'creature'
|
||||
]
|
||||
},
|
||||
'party\ntime!'
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
t.equal(s, [
|
||||
'beep',
|
||||
'│ one',
|
||||
'│ two',
|
||||
'├── ity',
|
||||
'└─┬ boop',
|
||||
' ├─┬ o_O',
|
||||
' │ │ wheee',
|
||||
' │ ├─┬ oh',
|
||||
' │ │ ├── hello',
|
||||
' │ │ └── puny',
|
||||
' │ │ meat',
|
||||
' │ └── creature',
|
||||
' └── party',
|
||||
' time!',
|
||||
''
|
||||
].join('\n'));
|
||||
t.end();
|
||||
});
|
40
theme/node_modules/archy/test/non_unicode.js
generated
vendored
Normal file
40
theme/node_modules/archy/test/non_unicode.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
var test = require('tape');
|
||||
var archy = require('../');
|
||||
|
||||
test('beep', function (t) {
|
||||
var s = archy({
|
||||
label : 'beep',
|
||||
nodes : [
|
||||
'ity',
|
||||
{
|
||||
label : 'boop',
|
||||
nodes : [
|
||||
{
|
||||
label : 'o_O',
|
||||
nodes : [
|
||||
{
|
||||
label : 'oh',
|
||||
nodes : [ 'hello', 'puny' ]
|
||||
},
|
||||
'human'
|
||||
]
|
||||
},
|
||||
'party!'
|
||||
]
|
||||
}
|
||||
]
|
||||
}, '', { unicode : false });
|
||||
t.equal(s, [
|
||||
'beep',
|
||||
'+-- ity',
|
||||
'`-- boop',
|
||||
' +-- o_O',
|
||||
' | +-- oh',
|
||||
' | | +-- hello',
|
||||
' | | `-- puny',
|
||||
' | `-- human',
|
||||
' `-- party!',
|
||||
''
|
||||
].join('\n'));
|
||||
t.end();
|
||||
});
|
21
theme/node_modules/arr-diff/LICENSE
generated
vendored
Executable file
21
theme/node_modules/arr-diff/LICENSE
generated
vendored
Executable file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert
|
||||
|
||||
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.
|
130
theme/node_modules/arr-diff/README.md
generated
vendored
Normal file
130
theme/node_modules/arr-diff/README.md
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
# arr-diff [![NPM version](https://img.shields.io/npm/v/arr-diff.svg?style=flat)](https://www.npmjs.com/package/arr-diff) [![NPM monthly downloads](https://img.shields.io/npm/dm/arr-diff.svg?style=flat)](https://npmjs.org/package/arr-diff) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/arr-diff.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/arr-diff)
|
||||
|
||||
> Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save arr-diff
|
||||
```
|
||||
|
||||
Install with [yarn](https://yarnpkg.com):
|
||||
|
||||
```sh
|
||||
$ yarn add arr-diff
|
||||
```
|
||||
|
||||
Install with [bower](https://bower.io/)
|
||||
|
||||
```sh
|
||||
$ bower install arr-diff --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Returns the difference between the first array and additional arrays.
|
||||
|
||||
```js
|
||||
var diff = require('arr-diff');
|
||||
|
||||
var a = ['a', 'b', 'c', 'd'];
|
||||
var b = ['b', 'c'];
|
||||
|
||||
console.log(diff(a, b))
|
||||
//=> ['a', 'd']
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
This library versus [array-differ](https://github.com/sindresorhus/array-differ), on April 14, 2017:
|
||||
|
||||
```
|
||||
Benchmarking: (4 of 4)
|
||||
· long-dupes
|
||||
· long
|
||||
· med
|
||||
· short
|
||||
|
||||
# benchmark/fixtures/long-dupes.js (100804 bytes)
|
||||
arr-diff-3.0.0 x 822 ops/sec ±0.67% (86 runs sampled)
|
||||
arr-diff-4.0.0 x 2,141 ops/sec ±0.42% (89 runs sampled)
|
||||
array-differ x 708 ops/sec ±0.70% (89 runs sampled)
|
||||
|
||||
fastest is arr-diff-4.0.0
|
||||
|
||||
# benchmark/fixtures/long.js (94529 bytes)
|
||||
arr-diff-3.0.0 x 882 ops/sec ±0.60% (87 runs sampled)
|
||||
arr-diff-4.0.0 x 2,329 ops/sec ±0.97% (83 runs sampled)
|
||||
array-differ x 769 ops/sec ±0.61% (90 runs sampled)
|
||||
|
||||
fastest is arr-diff-4.0.0
|
||||
|
||||
# benchmark/fixtures/med.js (708 bytes)
|
||||
arr-diff-3.0.0 x 856,150 ops/sec ±0.42% (89 runs sampled)
|
||||
arr-diff-4.0.0 x 4,665,249 ops/sec ±1.06% (89 runs sampled)
|
||||
array-differ x 653,888 ops/sec ±1.02% (86 runs sampled)
|
||||
|
||||
fastest is arr-diff-4.0.0
|
||||
|
||||
# benchmark/fixtures/short.js (60 bytes)
|
||||
arr-diff-3.0.0 x 3,078,467 ops/sec ±0.77% (93 runs sampled)
|
||||
arr-diff-4.0.0 x 9,213,296 ops/sec ±0.65% (89 runs sampled)
|
||||
array-differ x 1,337,051 ops/sec ±0.91% (92 runs sampled)
|
||||
|
||||
fastest is arr-diff-4.0.0
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
### Related projects
|
||||
|
||||
* [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten "Recursively flatten an array or arrays. This is the fastest implementation of array flatten.")
|
||||
* [array-filter](https://www.npmjs.com/package/array-filter): Array#filter for older browsers. | [homepage](https://github.com/juliangruber/array-filter "Array#filter for older browsers.")
|
||||
* [array-intersection](https://www.npmjs.com/package/array-intersection): Return an array with the unique values present in _all_ given arrays using strict equality… [more](https://github.com/jonschlinkert/array-intersection) | [homepage](https://github.com/jonschlinkert/array-intersection "Return an array with the unique values present in _all_ given arrays using strict equality for comparisons.")
|
||||
|
||||
### Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 33 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 2 | [paulmillr](https://github.com/paulmillr) |
|
||||
|
||||
### Building docs
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
### Running tests
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.5.0, on April 14, 2017._
|
47
theme/node_modules/arr-diff/index.js
generated
vendored
Normal file
47
theme/node_modules/arr-diff/index.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* arr-diff <https://github.com/jonschlinkert/arr-diff>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function diff(arr/*, arrays*/) {
|
||||
var len = arguments.length;
|
||||
var idx = 0;
|
||||
while (++idx < len) {
|
||||
arr = diffArray(arr, arguments[idx]);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
function diffArray(one, two) {
|
||||
if (!Array.isArray(two)) {
|
||||
return one.slice();
|
||||
}
|
||||
|
||||
var tlen = two.length
|
||||
var olen = one.length;
|
||||
var idx = -1;
|
||||
var arr = [];
|
||||
|
||||
while (++idx < olen) {
|
||||
var ele = one[idx];
|
||||
|
||||
var hasEle = false;
|
||||
for (var i = 0; i < tlen; i++) {
|
||||
var val = two[i];
|
||||
|
||||
if (ele === val) {
|
||||
hasEle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasEle === false) {
|
||||
arr.push(ele);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
109
theme/node_modules/arr-diff/package.json
generated
vendored
Normal file
109
theme/node_modules/arr-diff/package.json
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
{
|
||||
"_from": "arr-diff@^4.0.0",
|
||||
"_id": "arr-diff@4.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
|
||||
"_location": "/arr-diff",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "arr-diff@^4.0.0",
|
||||
"name": "arr-diff",
|
||||
"escapedName": "arr-diff",
|
||||
"rawSpec": "^4.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^4.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/micromatch",
|
||||
"/nanomatch"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
"_shasum": "d6461074febfec71e7e15235761a329a5dc7c520",
|
||||
"_spec": "arr-diff@^4.0.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/micromatch",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/arr-diff/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jon Schlinkert",
|
||||
"email": "jon.schlinkert@sellside.com",
|
||||
"url": "http://twitter.com/jonschlinkert"
|
||||
},
|
||||
{
|
||||
"name": "Paul Miller",
|
||||
"email": "paul+gh@paulmillr.com",
|
||||
"url": "paulmillr.com"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.",
|
||||
"devDependencies": {
|
||||
"ansi-bold": "^0.1.1",
|
||||
"arr-flatten": "^1.0.1",
|
||||
"array-differ": "^1.0.0",
|
||||
"benchmarked": "^0.2.4",
|
||||
"gulp-format-md": "^0.1.9",
|
||||
"minimist": "^1.2.0",
|
||||
"mocha": "^2.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/arr-diff",
|
||||
"keywords": [
|
||||
"arr",
|
||||
"array",
|
||||
"array differ",
|
||||
"array-differ",
|
||||
"diff",
|
||||
"differ",
|
||||
"difference"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "arr-diff",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/arr-diff.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"related": {
|
||||
"list": [
|
||||
"arr-flatten",
|
||||
"array-filter",
|
||||
"array-intersection"
|
||||
]
|
||||
},
|
||||
"reflinks": [
|
||||
"array-differ",
|
||||
"verb"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"version": "4.0.0"
|
||||
}
|
21
theme/node_modules/arr-flatten/LICENSE
generated
vendored
Executable file
21
theme/node_modules/arr-flatten/LICENSE
generated
vendored
Executable file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
|
||||
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.
|
86
theme/node_modules/arr-flatten/README.md
generated
vendored
Executable file
86
theme/node_modules/arr-flatten/README.md
generated
vendored
Executable file
@ -0,0 +1,86 @@
|
||||
# arr-flatten [![NPM version](https://img.shields.io/npm/v/arr-flatten.svg?style=flat)](https://www.npmjs.com/package/arr-flatten) [![NPM monthly downloads](https://img.shields.io/npm/dm/arr-flatten.svg?style=flat)](https://npmjs.org/package/arr-flatten) [![NPM total downloads](https://img.shields.io/npm/dt/arr-flatten.svg?style=flat)](https://npmjs.org/package/arr-flatten) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/arr-flatten.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/arr-flatten) [![Windows Build Status](https://img.shields.io/appveyor/ci/jonschlinkert/arr-flatten.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/jonschlinkert/arr-flatten)
|
||||
|
||||
> Recursively flatten an array or arrays.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm install --save arr-flatten
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Install with [bower](https://bower.io/)
|
||||
|
||||
```sh
|
||||
$ bower install arr-flatten --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var flatten = require('arr-flatten');
|
||||
|
||||
flatten(['a', ['b', ['c']], 'd', ['e']]);
|
||||
//=> ['a', 'b', 'c', 'd', 'e']
|
||||
```
|
||||
|
||||
## Why another flatten utility?
|
||||
|
||||
I wanted the fastest implementation I could find, with implementation choices that should work for 95% of use cases, but no cruft to cover the other 5%.
|
||||
|
||||
## About
|
||||
|
||||
### Related projects
|
||||
|
||||
* [arr-filter](https://www.npmjs.com/package/arr-filter): Faster alternative to javascript's native filter method. | [homepage](https://github.com/jonschlinkert/arr-filter "Faster alternative to javascript's native filter method.")
|
||||
* [arr-union](https://www.npmjs.com/package/arr-union): Combines a list of arrays, returning a single array with unique values, using strict equality… [more](https://github.com/jonschlinkert/arr-union) | [homepage](https://github.com/jonschlinkert/arr-union "Combines a list of arrays, returning a single array with unique values, using strict equality for comparisons.")
|
||||
* [array-each](https://www.npmjs.com/package/array-each): Loop over each item in an array and call the given function on every element. | [homepage](https://github.com/jonschlinkert/array-each "Loop over each item in an array and call the given function on every element.")
|
||||
* [array-unique](https://www.npmjs.com/package/array-unique): Remove duplicate values from an array. Fastest ES5 implementation. | [homepage](https://github.com/jonschlinkert/array-unique "Remove duplicate values from an array. Fastest ES5 implementation.")
|
||||
|
||||
### Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
|
||||
|
||||
### Contributors
|
||||
|
||||
| **Commits** | **Contributor** |
|
||||
| --- | --- |
|
||||
| 20 | [jonschlinkert](https://github.com/jonschlinkert) |
|
||||
| 1 | [lukeed](https://github.com/lukeed) |
|
||||
|
||||
### Building docs
|
||||
|
||||
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
|
||||
|
||||
To generate the readme, run the following command:
|
||||
|
||||
```sh
|
||||
$ npm install -g verbose/verb#dev verb-generate-readme && verb
|
||||
```
|
||||
|
||||
### Running tests
|
||||
|
||||
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
|
||||
|
||||
```sh
|
||||
$ npm install && npm test
|
||||
```
|
||||
|
||||
### Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
|
||||
|
||||
### License
|
||||
|
||||
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
|
||||
Released under the [MIT License](LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on July 05, 2017._
|
22
theme/node_modules/arr-flatten/index.js
generated
vendored
Normal file
22
theme/node_modules/arr-flatten/index.js
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/*!
|
||||
* arr-flatten <https://github.com/jonschlinkert/arr-flatten>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function (arr) {
|
||||
return flat(arr, []);
|
||||
};
|
||||
|
||||
function flat(arr, res) {
|
||||
var i = 0, cur;
|
||||
var len = arr.length;
|
||||
for (; i < len; i++) {
|
||||
cur = arr[i];
|
||||
Array.isArray(cur) ? flat(cur, res) : res.push(cur);
|
||||
}
|
||||
return res;
|
||||
}
|
113
theme/node_modules/arr-flatten/package.json
generated
vendored
Normal file
113
theme/node_modules/arr-flatten/package.json
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"_from": "arr-flatten@^1.1.0",
|
||||
"_id": "arr-flatten@1.1.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
|
||||
"_location": "/arr-flatten",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "arr-flatten@^1.1.0",
|
||||
"name": "arr-flatten",
|
||||
"escapedName": "arr-flatten",
|
||||
"rawSpec": "^1.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^1.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/braces"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
|
||||
"_shasum": "36048bbff4e7b47e136644316c99669ea5ae91f1",
|
||||
"_spec": "arr-flatten@^1.1.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/braces",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/arr-flatten/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "http://twitter.com/jonschlinkert"
|
||||
},
|
||||
{
|
||||
"name": "Luke Edwards",
|
||||
"url": "https://lukeed.com"
|
||||
}
|
||||
],
|
||||
"deprecated": false,
|
||||
"description": "Recursively flatten an array or arrays.",
|
||||
"devDependencies": {
|
||||
"ansi-bold": "^0.1.1",
|
||||
"array-flatten": "^2.1.1",
|
||||
"array-slice": "^1.0.0",
|
||||
"benchmarked": "^1.0.0",
|
||||
"compute-flatten": "^1.0.0",
|
||||
"flatit": "^1.1.1",
|
||||
"flatten": "^1.0.2",
|
||||
"flatten-array": "^1.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"gulp-format-md": "^0.1.12",
|
||||
"just-flatten-it": "^1.1.23",
|
||||
"lodash.flattendeep": "^4.4.0",
|
||||
"m_flattened": "^1.0.1",
|
||||
"mocha": "^3.2.0",
|
||||
"utils-flatten": "^1.0.0",
|
||||
"write": "^0.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/arr-flatten",
|
||||
"keywords": [
|
||||
"arr",
|
||||
"array",
|
||||
"elements",
|
||||
"flat",
|
||||
"flatten",
|
||||
"nested",
|
||||
"recurse",
|
||||
"recursive",
|
||||
"recursively"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "arr-flatten",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/arr-flatten.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"verb": {
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"related": {
|
||||
"list": [
|
||||
"arr-filter",
|
||||
"arr-union",
|
||||
"array-each",
|
||||
"array-unique"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"version": "1.1.0"
|
||||
}
|
21
theme/node_modules/arr-union/LICENSE
generated
vendored
Normal file
21
theme/node_modules/arr-union/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016, Jon Schlinkert.
|
||||
|
||||
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.
|
99
theme/node_modules/arr-union/README.md
generated
vendored
Normal file
99
theme/node_modules/arr-union/README.md
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
# arr-union [![NPM version](https://img.shields.io/npm/v/arr-union.svg)](https://www.npmjs.com/package/arr-union) [![Build Status](https://img.shields.io/travis/jonschlinkert/arr-union.svg)](https://travis-ci.org/jonschlinkert/arr-union)
|
||||
|
||||
> Combines a list of arrays, returning a single array with unique values, using strict equality for comparisons.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/):
|
||||
|
||||
```sh
|
||||
$ npm i arr-union --save
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
This library is **10-20 times faster** and more performant than [array-union](https://github.com/sindresorhus/array-union).
|
||||
|
||||
See the [benchmarks](./benchmark).
|
||||
|
||||
```sh
|
||||
#1: five-arrays
|
||||
array-union x 511,121 ops/sec ±0.80% (96 runs sampled)
|
||||
arr-union x 5,716,039 ops/sec ±0.86% (93 runs sampled)
|
||||
|
||||
#2: ten-arrays
|
||||
array-union x 245,196 ops/sec ±0.69% (94 runs sampled)
|
||||
arr-union x 1,850,786 ops/sec ±0.84% (97 runs sampled)
|
||||
|
||||
#3: two-arrays
|
||||
array-union x 563,869 ops/sec ±0.97% (94 runs sampled)
|
||||
arr-union x 9,602,852 ops/sec ±0.87% (92 runs sampled)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var union = require('arr-union');
|
||||
|
||||
union(['a'], ['b', 'c'], ['d', 'e', 'f']);
|
||||
//=> ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
```
|
||||
|
||||
Returns only unique elements:
|
||||
|
||||
```js
|
||||
union(['a', 'a'], ['b', 'c']);
|
||||
//=> ['a', 'b', 'c']
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
* [arr-diff](https://www.npmjs.com/package/arr-diff): Returns an array with only the unique values from the first array, by excluding all… [more](https://www.npmjs.com/package/arr-diff) | [homepage](https://github.com/jonschlinkert/arr-diff)
|
||||
* [arr-filter](https://www.npmjs.com/package/arr-filter): Faster alternative to javascript's native filter method. | [homepage](https://github.com/jonschlinkert/arr-filter)
|
||||
* [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten)
|
||||
* [arr-map](https://www.npmjs.com/package/arr-map): Faster, node.js focused alternative to JavaScript's native array map. | [homepage](https://github.com/jonschlinkert/arr-map)
|
||||
* [arr-pluck](https://www.npmjs.com/package/arr-pluck): Retrieves the value of a specified property from all elements in the collection. | [homepage](https://github.com/jonschlinkert/arr-pluck)
|
||||
* [arr-reduce](https://www.npmjs.com/package/arr-reduce): Fast array reduce that also loops over sparse elements. | [homepage](https://github.com/jonschlinkert/arr-reduce)
|
||||
* [array-unique](https://www.npmjs.com/package/array-unique): Return an array free of duplicate values. Fastest ES5 implementation. | [homepage](https://github.com/jonschlinkert/array-unique)
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/arr-union/issues/new).
|
||||
|
||||
## Building docs
|
||||
|
||||
Generate readme and API documentation with [verb](https://github.com/verbose/verb):
|
||||
|
||||
```sh
|
||||
$ npm i verb && npm run docs
|
||||
```
|
||||
|
||||
Or, if [verb](https://github.com/verbose/verb) is installed globally:
|
||||
|
||||
```sh
|
||||
$ verb
|
||||
```
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
* [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2016 [Jon Schlinkert](https://github.com/jonschlinkert)
|
||||
Released under the [MIT license](https://github.com/jonschlinkert/arr-union/blob/master/LICENSE).
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on February 23, 2016._
|
29
theme/node_modules/arr-union/index.js
generated
vendored
Normal file
29
theme/node_modules/arr-union/index.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function union(init) {
|
||||
if (!Array.isArray(init)) {
|
||||
throw new TypeError('arr-union expects the first argument to be an array.');
|
||||
}
|
||||
|
||||
var len = arguments.length;
|
||||
var i = 0;
|
||||
|
||||
while (++i < len) {
|
||||
var arg = arguments[i];
|
||||
if (!arg) continue;
|
||||
|
||||
if (!Array.isArray(arg)) {
|
||||
arg = [arg];
|
||||
}
|
||||
|
||||
for (var j = 0; j < arg.length; j++) {
|
||||
var ele = arg[j];
|
||||
|
||||
if (init.indexOf(ele) >= 0) {
|
||||
continue;
|
||||
}
|
||||
init.push(ele);
|
||||
}
|
||||
}
|
||||
return init;
|
||||
};
|
108
theme/node_modules/arr-union/package.json
generated
vendored
Normal file
108
theme/node_modules/arr-union/package.json
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"_from": "arr-union@^3.1.0",
|
||||
"_id": "arr-union@3.1.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
|
||||
"_location": "/arr-union",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "arr-union@^3.1.0",
|
||||
"name": "arr-union",
|
||||
"escapedName": "arr-union",
|
||||
"rawSpec": "^3.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/class-utils",
|
||||
"/union-value"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
||||
"_shasum": "e39b09aea9def866a8f206e288af63919bae39c4",
|
||||
"_spec": "arr-union@^3.1.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/union-value",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/arr-union/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Combines a list of arrays, returning a single array with unique values, using strict equality for comparisons.",
|
||||
"devDependencies": {
|
||||
"ansi-bold": "^0.1.1",
|
||||
"array-union": "^1.0.1",
|
||||
"array-unique": "^0.2.1",
|
||||
"benchmarked": "^0.1.4",
|
||||
"gulp-format-md": "^0.1.7",
|
||||
"minimist": "^1.1.1",
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/jonschlinkert/arr-union",
|
||||
"keywords": [
|
||||
"add",
|
||||
"append",
|
||||
"array",
|
||||
"arrays",
|
||||
"combine",
|
||||
"concat",
|
||||
"extend",
|
||||
"union",
|
||||
"uniq",
|
||||
"unique",
|
||||
"util",
|
||||
"utility",
|
||||
"utils"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "arr-union",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/arr-union.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"verb": {
|
||||
"run": true,
|
||||
"toc": false,
|
||||
"layout": "default",
|
||||
"tasks": [
|
||||
"readme"
|
||||
],
|
||||
"plugins": [
|
||||
"gulp-format-md"
|
||||
],
|
||||
"related": {
|
||||
"list": [
|
||||
"arr-diff",
|
||||
"arr-flatten",
|
||||
"arr-filter",
|
||||
"arr-map",
|
||||
"arr-pluck",
|
||||
"arr-reduce",
|
||||
"array-unique"
|
||||
]
|
||||
},
|
||||
"reflinks": [
|
||||
"verb",
|
||||
"array-union"
|
||||
],
|
||||
"lint": {
|
||||
"reflinks": true
|
||||
}
|
||||
},
|
||||
"version": "3.1.0"
|
||||
}
|
7
theme/node_modules/array-differ/index.js
generated
vendored
Normal file
7
theme/node_modules/array-differ/index.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
module.exports = function (arr) {
|
||||
var rest = [].concat.apply([], [].slice.call(arguments, 1));
|
||||
return arr.filter(function (el) {
|
||||
return rest.indexOf(el) === -1;
|
||||
});
|
||||
};
|
64
theme/node_modules/array-differ/package.json
generated
vendored
Normal file
64
theme/node_modules/array-differ/package.json
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"_from": "array-differ@^1.0.0",
|
||||
"_id": "array-differ@1.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
|
||||
"_location": "/array-differ",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "array-differ@^1.0.0",
|
||||
"name": "array-differ",
|
||||
"escapedName": "array-differ",
|
||||
"rawSpec": "^1.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^1.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/gulp-util"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
|
||||
"_shasum": "eff52e3758249d33be402b8bb8e564bb2b5d4031",
|
||||
"_spec": "array-differ@^1.0.0",
|
||||
"_where": "/home/lafrite/tmp/site_pelican/theme/node_modules/gulp-util",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "http://sindresorhus.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sindresorhus/array-differ/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Create an array with values that are present in the first input array but not additional ones",
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"homepage": "https://github.com/sindresorhus/array-differ#readme",
|
||||
"keywords": [
|
||||
"array",
|
||||
"difference",
|
||||
"diff",
|
||||
"differ",
|
||||
"filter",
|
||||
"exclude"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "array-differ",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sindresorhus/array-differ.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
}
|
41
theme/node_modules/array-differ/readme.md
generated
vendored
Normal file
41
theme/node_modules/array-differ/readme.md
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
# array-differ [![Build Status](https://travis-ci.org/sindresorhus/array-differ.svg?branch=master)](https://travis-ci.org/sindresorhus/array-differ)
|
||||
|
||||
> Create an array with values that are present in the first input array but not additional ones
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install --save array-differ
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var arrayDiffer = require('array-differ');
|
||||
|
||||
arrayDiffer([2, 3, 4], [3, 50]);
|
||||
//=> [2, 4]
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### arrayDiffer(input, values, [values, ...])
|
||||
|
||||
Returns the new array.
|
||||
|
||||
#### input
|
||||
|
||||
Type: `array`
|
||||
|
||||
#### values
|
||||
|
||||
Type: `array`
|
||||
|
||||
Arrays of values to exclude.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user