Compare commits
48 Commits
Author | SHA1 | Date |
---|---|---|
Bertrand Benjamin | 0d4e4d74b0 | |
Bertrand Benjamin | 1ae89f63d0 | |
Bertrand Benjamin | d90ed8149d | |
Bertrand Benjamin | dab40dddd0 | |
Bertrand Benjamin | 9a2d687434 | |
Bertrand Benjamin | 7ea7fba87c | |
Bertrand Benjamin | ae45ff7d42 | |
Bertrand Benjamin | 75060070b9 | |
Bertrand Benjamin | 0607f2a69a | |
Bertrand Benjamin | 1764489028 | |
Bertrand Benjamin | b6b089542e | |
Bertrand Benjamin | 735cd0bd59 | |
Bertrand Benjamin | dc470aec10 | |
Bertrand Benjamin | f2adf72aa0 | |
Bertrand Benjamin | 0653ac2bf8 | |
Bertrand Benjamin | 5b9910bb0f | |
Bertrand Benjamin | dbbb0b5ecf | |
Bertrand Benjamin | 6060a52717 | |
Bertrand Benjamin | 12d10e6ace | |
Bertrand Benjamin | abe52dd5c9 | |
Bertrand Benjamin | 1c92eedfb2 | |
Bertrand Benjamin | 1f34a326ad | |
Bertrand Benjamin | d6e575ea45 | |
Bertrand Benjamin | 438251f75d | |
Bertrand Benjamin | b720e17c61 | |
Bertrand Benjamin | 02dbc94f31 | |
Bertrand Benjamin | dd92f1a77e | |
Bertrand Benjamin | 952d19859c | |
Bertrand Benjamin | ba64771efb | |
Bertrand Benjamin | c7ecf06733 | |
Bertrand Benjamin | 548aecf9e3 | |
Bertrand Benjamin | d49fabf259 | |
Bertrand Benjamin | c6ee0ce838 | |
Bertrand Benjamin | edc12f1430 | |
Bertrand Benjamin | ef808a597b | |
Bertrand Benjamin | 5b475a2f38 | |
Bertrand Benjamin | 1ad81faabe | |
Bertrand Benjamin | da8b91989f | |
Bertrand Benjamin | 5239c34f50 | |
Bertrand Benjamin | adab4cdd33 | |
Bertrand Benjamin | dbb4f2f9e5 | |
Bertrand Benjamin | 75c13ae761 | |
Bertrand Benjamin | c015b18394 | |
Bertrand Benjamin | 9037131275 | |
Bertrand Benjamin | b56e99040e | |
Bertrand Benjamin | ad1275cfe8 | |
Bertrand Benjamin | 81dc32f301 | |
Bertrand Benjamin | 7e4121a577 |
103
.drone.yml
103
.drone.yml
|
@ -1,101 +1,28 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: Opytex Main
|
||||
name: Opytex 2023-2024
|
||||
type: docker
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
- 2023-2024
|
||||
|
||||
steps:
|
||||
- name: Build Opytex base
|
||||
- name: Deploy
|
||||
image: python:3.8-alpine
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
path: /output
|
||||
commands:
|
||||
- apk add --no-cache git imagemagick-dev imagemagick
|
||||
- apk add --no-cache openssh-client ca-certificates bash rsync git imagemagick-dev imagemagick
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- git clone https://git.opytex.org/lafrite/2021-2022.git content
|
||||
- pip install --no-cache-dir -r requirements.txt
|
||||
- export MAGICK_HOME=/usr
|
||||
- pelican ./content/ -o /output -s publishconf.py --relative-urls
|
||||
- ls /output
|
||||
|
||||
- name: Push to bucket opytex.org
|
||||
image: plugins/s3
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
path: /output
|
||||
settings:
|
||||
bucket: opytex.org
|
||||
endpoint: https://storage.opytex.org
|
||||
access_key:
|
||||
from_secret: minio_access_key
|
||||
secret_key:
|
||||
from_secret: minio_secret_key
|
||||
source: /output/**/*
|
||||
target: /
|
||||
path_style: true
|
||||
strip_prefix: /output
|
||||
|
||||
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
temp: {}
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: Opytex Year
|
||||
type: docker
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- 2022-2023
|
||||
- 2021-2022
|
||||
- 2020-2021
|
||||
- 2019-2020
|
||||
- 2018-2019
|
||||
- 2017-2018
|
||||
- 2016-2017
|
||||
- 2015-2016
|
||||
|
||||
steps:
|
||||
- name: Build Opytex ${DRONE_BRANCH}
|
||||
image: python:3.8-alpine
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
path: /output
|
||||
commands:
|
||||
- apk add --no-cache git imagemagick-dev imagemagick
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- git clone https://git.opytex.org/lafrite/${DRONE_BRANCH}.git content
|
||||
- pip install --no-cache-dir -r requirements.txt
|
||||
- apk add --no-cache git imagemagick-dev imagemagick
|
||||
- pip install --no-cache-dir -r requirements.txt
|
||||
- export MAGICK_HOME=/usr
|
||||
- pelican ./content/ -o /output -s publishconf.py --relative-urls
|
||||
- ls /output
|
||||
|
||||
- name: Push to bucket opytex.org
|
||||
image: plugins/s3-sync:1
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
path: /drone/src/output
|
||||
settings:
|
||||
bucket: opytex.org
|
||||
endpoint: https://storage.opytex.org
|
||||
access_key:
|
||||
from_secret: minio_access_key
|
||||
secret_key:
|
||||
from_secret: minio_secret_key
|
||||
source: /output
|
||||
target: /enseignements/${DRONE_BRANCH}
|
||||
path_style: true
|
||||
delete: true
|
||||
|
||||
|
||||
volumes:
|
||||
- name: pelican-output
|
||||
temp: {}
|
||||
- pelican ./content/ -o output -s publishconf.py --relative-urls
|
||||
- eval `ssh-agent -s`
|
||||
- echo "$SSH_KEY" | ssh-add -
|
||||
- mkdir -p ~/.ssh
|
||||
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
|
||||
- ssh sshcontent@91.121.90.228 'mkdir -p ~/opytex.org/www/enseignements/2021-2022/'
|
||||
- rsync -rv --delete -e "ssh -p 22" ./output/ sshcontent@91.121.90.228:~/opytex.org/www/enseignements/2021-2022/ --checksum
|
||||
environment:
|
||||
SSH_KEY:
|
||||
from_secret: sshcontent-key
|
||||
|
|
|
@ -2,9 +2,8 @@ cache/*
|
|||
output/*
|
||||
pelican-plugins/*
|
||||
pelican-themes/*
|
||||
content/Enseignements/2*
|
||||
content
|
||||
__pycache__
|
||||
*.pid
|
||||
venv/
|
||||
.vim/
|
||||
.python-version
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "pelican-plugins"]
|
||||
path = pelican-plugins
|
||||
url = https://github.com/getpelican/pelican-plugins
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.6.0
|
||||
hooks:
|
||||
- id: black
|
25
Makefile
25
Makefile
|
@ -2,21 +2,24 @@ PY?=python3
|
|||
PELICAN?=pelican
|
||||
PELICANOPTS=
|
||||
|
||||
YEARSUBFOLDER=
|
||||
YEARSUBFOLDER=enseignements/DEV/
|
||||
BASEDIR=$(CURDIR)
|
||||
INPUTDIR=$(BASEDIR)/content
|
||||
OUTPUTDIR=$(BASEDIR)/output
|
||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||
|
||||
FAKEDIR=../output/
|
||||
FAKEDIR=../../output/
|
||||
|
||||
SSH_HOST=Embrevade
|
||||
SSH_PORT=22
|
||||
SSH_USER=sshcontent
|
||||
SSH_TARGET_DIR=/home/sshcontent/opytex.org/www/
|
||||
FTP_HOST=localhost
|
||||
FTP_USER=anonymous
|
||||
FTP_TARGET_DIR=/
|
||||
|
||||
SSH_HOST=localhost
|
||||
SSH_CONF=Embrevade
|
||||
#SSH_TARGET_DIR=/var/docker/opytex.org/www/
|
||||
SSH_TARGET_DIR=/home/sshcontent/opytex.org/www/$(YEARSUBFOLDER)
|
||||
|
||||
RSYNC_EXCLUDE=--exclude "pymath" --exclude "opytex" --exclude "enseignements"
|
||||
|
||||
DEBUG ?= 0
|
||||
ifeq ($(DEBUG), 1)
|
||||
|
@ -46,8 +49,10 @@ help:
|
|||
@echo 'Set the RELATIVE variable to 1 to enable relative urls '
|
||||
@echo ' '
|
||||
|
||||
html:
|
||||
css:
|
||||
lessc $(BASEDIR)/theme/static/stylesheet/style.less $(BASEDIR)/theme/static/stylesheet/style.min.css -x
|
||||
|
||||
html: css
|
||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||
|
||||
clean:
|
||||
|
@ -88,6 +93,6 @@ rsync_upload: publish
|
|||
|
||||
fake_upload: html
|
||||
mkdir -p $(FAKEDIR)$(YEARSUBFOLDER)
|
||||
rsync -P -rvzc --delete $(RSYNC_EXCLUDE) $(OUTPUTDIR)/ $(FAKEDIR)$(YEARSUBFOLDER) --cvs-exclude
|
||||
rsync -P -rvzc --delete $(OUTPUTDIR)/ $(FAKEDIR)$(YEARSUBFOLDER) --cvs-exclude
|
||||
|
||||
.PHONY: html help clean regenerate serve serve-global devserver publish ssh_upload rsync_upload
|
||||
.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,77 +0,0 @@
|
|||
Questions flashs
|
||||
################
|
||||
|
||||
:date: 2022-02-02
|
||||
:modified: 2022-02-02
|
||||
:tags: Partage de pratiques, pédagogie
|
||||
:category: Enseignement
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: Compte rendu d'une présentation des questions flashs que j'ai réalisé dans le groupe partage de pratiques.
|
||||
|
||||
Notes prises pas Audrey lors de ma présentation de ma pratique des questions flashs au groupe "partage de pratiques".
|
||||
|
||||
Objectifs
|
||||
=========
|
||||
|
||||
- **Mise en place de la classe :** Les élèves savent en rentrant que le
|
||||
cours commence avec des questions flashs. Ils sont tout de suite mis
|
||||
en activité.
|
||||
|
||||
- **Échauffement :** Les questions flashs sont conçues pour mettre en
|
||||
les élèves en situation de réussite. Comme un échauffement sportif,
|
||||
les élèves commencent par quelque chose qu’ils savent qu’ils vont
|
||||
réussir.
|
||||
|
||||
- **Révision et préparation :** les questions posées servent à préparer
|
||||
un chapitre qui arrivera dans un future proche, à remobiliser des
|
||||
connaissances étudiées que l’enseignant juge fondamental.
|
||||
L’enseignant gère le rythme pour que les élèves ancrent les savoirs.
|
||||
|
||||
Quoi
|
||||
====
|
||||
|
||||
**4 questions** appelant à des réponses courtes, axées sur
|
||||
les **bases de la matière** et sur les points susceptibles de générer
|
||||
des difficultés chez les élèves. Les 4 questions doivent aborder des
|
||||
**notions différentes** . L’élève ne doit pas après la première question
|
||||
flash se dire qu’il ne sera pas faire les autres. Ces 4 notions pourront
|
||||
être reprises à chaque séance sur une semaine ou deux.
|
||||
|
||||
Exemple :
|
||||
---------
|
||||
|
||||
- Question 1 sur les pourcentages
|
||||
- Question 2 sur les fractions
|
||||
- Question 3 sur les vecteurs
|
||||
- Question 4 sur les conversions
|
||||
|
||||
Sur la semaine les quatre thèmes sont repris. On ajuste la difficulté pour qu'ils soient en réussite mais qu'ils renforce une connaissance.
|
||||
|
||||
`Diapositives du jour 1 <https://opytex.org/enseignements/2021-2022/2nd/Questions_flashs/P3/QF_S01-1.pdf>`_
|
||||
|
||||
`Diapositives du jour 2 <https://opytex.org/enseignements/2021-2022/2nd/Questions_flashs/P3/QF_S01-2.pdf>`_
|
||||
|
||||
`Diapositives du jour 3 <https://opytex.org/enseignements/2021-2022/2nd/Questions_flashs/P3/QF_S01-3.pdf>`_
|
||||
|
||||
Quand
|
||||
=====
|
||||
|
||||
A **chaque début de cours** (sauf les jours de DS). Même quand on a deux heures dans la même journée (ça fait toujours tiquer les élèves ça!)
|
||||
|
||||
Support
|
||||
=======
|
||||
|
||||
Le professeur projette les questions au tableau durant 30 secondes à 1 minute, les élèves répondent individuellement à l’écrit, soit sur un brouillon (quand le travail n’est pas ramassé), soit sur la fiche-réponse donnée par l’enseignant (les jours où le travail est ramassé/noté).
|
||||
|
||||
Correction – notation
|
||||
=====================
|
||||
|
||||
Le professeur ramasse et note le travail environ une fois sur quatre (à ajuster selon le volume horaire dont il bénéficie avec la classe).
|
||||
|
||||
Le reste du temps, les questions-flash sont corrigées immédiatement après avoir répondu aux 4 questions : les élèves indiquent leurs résultats. On ne va pas plus loin dès lors que tous ont la bonne réponse. Dans le cas contraire, un élève ou le professeur donne les détails de la correction. C’est l’occasion d’insister sur la notion qui pose problème (notation, rédaction, erreurs fréquentes...)
|
||||
|
||||
Variante
|
||||
========
|
||||
|
||||
Selon les matières, on peut imaginer des questions-flash sous forme de phrase à trou, de questions donnant lieu à une courte énumération, de traduction, de définition… l’essentiel étant d’appeler à une **réponse courte** sans explication écrite et qui ne demande pas un raisonnement trop complexe.
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
Fonctions de référence en mode renversé
|
||||
########################################
|
||||
|
||||
:date: 2022-05-25
|
||||
:modified: 2022-05-25
|
||||
:tags: Partage de pratiques, pédagogie, Classe renversée, Évaluation, 2nd
|
||||
:category: Enseignement
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: Compte rendu d'un travail fait en classe autour des fonctions de référence.
|
||||
|
||||
Au départ, on était partis, avec Camille, pour faire travailler nos élèves de 2nd sur les fonctions de référence avec des exposés. On leur donne des fonctions avec le nom et la formule. Ils étudient en groupe une seule fonction pour répondre à une série de questions. Enfin ils présentent à l'oral cette fonction.
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/2P_exposes.pdf
|
||||
:height: 200px
|
||||
:alt: consignes initiales pour les exposés.
|
||||
|
||||
Plusieurs problèmes sont ressortis après cette planification. Mais pour l'essentiel, faire passer à l'oral 8 groupes prend beaucoup de temps et c'est du temps où les autres élèves ne font rien et le plus souvent n'écoutent pas. Pas très satisfaisant quand le programme veut que toutes les fonctions de référence soient étudiées.
|
||||
|
||||
Récemment, j'ai découvert le concept de classe renversée de Jean-Charles Caillez. Son propos peut être un peu trop rapidement résumé à "dans ma classe, il y a un élève et 80 enseignants". Il pose plusieurs questions aux élèves qui, en groupe, sont en charge d'y répondre. En parallèle de cette idée bousculante, il a développé de nombreuses "technologies" pour rendre la restitution un peu plus interactive.
|
||||
|
||||
J'ai donc adapté notre idée de départ en m'inspirant de l'approche renversée.
|
||||
|
||||
Redéfinition du l'activité: première séance
|
||||
===========================================
|
||||
|
||||
La première fois que je leur parle de cette activité, il reste 15 minutes de cours. Ils ont déjà fait des questions flashs. Je viens de leur expliquer le concept de domaine de définition et ils l'ont travaillé en parallèle d'études graphiques de fonctions. Je leur explique qu'ils vont commencer une activité de groupe qui conduira à la création d'un poster et qui sera notée. Je suis honnête avec eux, je n'ai pas encore fixé le cadre de l'évolution, je ne peux pas encore tout leur expliquer.
|
||||
|
||||
Les élèves sont déjà en îlots, les groupes sont donc déjà constitués. J'attribue à chaque groupe une fonction en ne leur donnant que son nom. Il y a 4 fonctions de référence à étudier en 2nd: la fonction carrée, la fonction cube, la fonction racine carrée et la fonction inverse. En amont, j'ai veillé à avoir 8 ilots. C'est parfait: deux groupes par fonction.
|
||||
|
||||
La première phase de recherche commence et voilà la consigne: "avec l'aide de ce que vous voulez, décrivez moi votre fonction. À la fin, vous devrez produire un poster mais je n'ai pas de feuille A3 alors notez ce qui vous semble important, vous réaliserez le poster plus tard". Ils commencent à travailler, beaucoup ne savent pas à quoi correspond leur fonction. Un élève demande si dans "tout ce que vous voulez", ils peuvent utiliser leur téléphone portable. Je réponds oui, les écrans s'allument et les partages de connection s'activent.
|
||||
|
||||
Le temps d'ouvrir les premiers sites internet, d'avoir un premier contact avec leur fonction, la fin du cours sonne.
|
||||
|
||||
Explication du mode d'évaluation: deuxième séance
|
||||
=================================================
|
||||
|
||||
Comme à la première séance, il reste 15 minutes quand on se replonge dans cette activité. Je rappelle le cadre de cette activité et comme j'ai fait mes devoirs, je peux leur expliquer comment ils seront évalués.
|
||||
|
||||
Dans deux cours, les posters devront être terminés. Je leur donnerai un QCM qu'ils devront réaliser individuellement avec l'aide unique des posters réalisés par les autres élèves. Leur note sera la somme de leur réussite au QCM et de la moyenne des résultats qu'auront eu leur camarade sur les questions qui portent sur leur fonction. Ils demandent quels types de questions je pourrai leur poser. Je ne réponds que très vaguement en leur disant que ce sera des questions d'un niveau 2nd sur des concepts déjà étudiés cette année.
|
||||
|
||||
Ils se remettent au travail. À part deux élèves en gros décrochage et que je n'arrive pas à raccrocher, tous les élèves sont actifs. Ils trouvent rapidement toutes les informations dont ils ont besoin. Malheureusement presque personne ne prend sa calculatrice pour vérifier les graphiques qu'ils trouvent. Mais le temps est vite écoulé.
|
||||
|
||||
Je me rends compte que si je veux que les posters soient terminés et qu'il y ait du contenu, je vais devoir leur donner plus de temps que ce que j'avais initialement planifié (c'est toujours comme ça...).
|
||||
|
||||
Réalisation des posters: troisième séance
|
||||
=========================================
|
||||
|
||||
Cette fois, je suis bien décidé à leur donner le temps dont ils auront besoin. Ils font les questions flashs, je rappelle le cadre et je leur distribue une feuille A3. Je leur dis quand même qu'ils ont du temps mais qu'ils ne faut pas qu'ils s'endorment, les posters doivent être terminés au prochain cours pour les QCM. C'est la dernière fois que je les verrai avant le conseil de classe.
|
||||
|
||||
Comme au cours précédent, ils se mettent volontairement au travail. Très vite, le problème du tri des informations est soulevé par certain groupe. Que doivent-ils faire apparaitre sur leur poster? Ils ne comprennent pas tout ce qu'ils lisent. Je les incite à n'écrire que ce qu'ils comprennent. Je pousse aussi les élèves les moins à l'aise à se montrer critique vis à vis de ce qu'ils écrivent. S'ils ne comprennent pas, d'autres ne comprendront pas, il est alors nécessaire d'améliorer les explications.
|
||||
|
||||
Je ne l'avais pas anticipé, mais plusieurs groupes ne veulent pas dessiner le graphique des fonctions, ils disent qu'il l'imprimeront chez eux. Je précise donc les règles: "rien n'a le droit d'être imprimé tout doit être fait à la main". Mais ils ont le droit d'écrire sur une autre feuille puis coller le papier sur le poster.
|
||||
|
||||
C'est alors que dans certains groupes, une belle dynamique se crée. Les élèves se partagent les tâches et travaillent en parallèle. Un élève poursuit les recherches sur internet, deux autres se lancent dans la réalisation d'un graphique et s'interrogent sur la méthode à adopter et un quatrième s'occupe de rendre le poster lisible et agréable.
|
||||
|
||||
Mais la grosse demi-heure passe vite, les posters ne sont pas terminés. Je ramasse les productions pour être sûr qu'aucune ne soit perdue ou restée dans le sac d'un élève absent!
|
||||
|
||||
Finitions et évaluation: quatrième séance
|
||||
=========================================
|
||||
|
||||
Dernières 15 minutes de préparation, je mets un gros chrono au tableau en mode TopChef, les équipes s'activent. Certain ont travaillé chez eux et sont arrivés avec des morceaux de papier près à coller. Le stress monte. Un groupe est en phase d'abandon. Il estime qu'il n'aura pas le temps de terminer et donc que ça ne sert à rien de continuer. J'essaie de mettre une pièce pour relancer la motivation. J'explique qu'ils ne sont pas obligé de faire un beau poster, qu'ils doivent se montrer efficaces et sélectionner uniquement les informations les plus importante. Je leur donne les astuces d'organisation des autres groupes et ils se relancent.
|
||||
|
||||
Les 15 minutes se terminent, c'est l'heure de l'évaluation
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/sujets_QCM.pdf
|
||||
:height: 200px
|
||||
:alt: 2 exemples de sujets du QCM
|
||||
|
||||
|
||||
On dispose 4 posters avec 4 fonctions différentes dans le fond de la classe et les 4 autres vers le tableau. Les élèves vont là où leur poster n'est pas. Je distribue les sujets. Ils doivent répondre individuellement avec les posters qu'ils ont à leur disposition. Pas facile de les empêcher de communiquer mais en 15minutes tout le monde a terminé.
|
||||
|
||||
Réalisations
|
||||
============
|
||||
|
||||
Voici les posters réalisés par les groupes
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_carre1.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction carrée 1
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_carre2.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction carrée 2
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_cube1.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction cube 1
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_cube2.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction cube 2
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_inverse1.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction inverse 1
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_inverse2.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction inverse 2
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_racine1.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction racine carré 1
|
||||
|
||||
.. image:: {attach}2205_expose_renverse/poster_racine2.pdf
|
||||
:height: 200px
|
||||
:alt: Présentation de la fonction racine carré 2
|
||||
|
||||
|
||||
Les plus pertinents sont sélectionnés et imprimés. Ils sont, quand c'est nécessaire, corrigés. C'est le cours pour cette séquence.
|
||||
|
||||
|
||||
Bilan
|
||||
=====
|
||||
|
||||
J'ai du mal à me rendre compte de ce que les élèves garderont comme connaissance des fonctions étudiées par eux-mêmes et par les autres. Ils ont surtout recopié les informations qu'ils trouvaient sur Internet sans se dire qu'ils étaient capables eux aussi de réaliser seuls les tableaux de valeurs des fonctions ou les tableaux de signes et de variations.
|
||||
|
||||
Par contre, ils ont été presque tous actifs du début à la fin sur cette activité. À aucun moment, ils ne se sont montrés passifs vis à vis du travail réalisé.
|
||||
|
||||
Et puis ça fait du bien de faire une séquence qui sort un peu de l'ordinaire. Toute l'année, j'ai du mal à les faire travailler de façon constructive en groupe. J'ai essayé les cahiers de groupe, les exercices de recherche en groupe mais peu de choses ont fonctionné. Là, j'ai pu constater de belles collaborations et un vrai travail de groupe auto-organisé.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,13 +0,0 @@
|
|||
404: Not Found
|
||||
##############
|
||||
|
||||
:date: 2023-07-25
|
||||
:modified: 2023-07-25
|
||||
:slug: 404
|
||||
:status: hidden
|
||||
:authors: Benjamin Bertrand
|
||||
:save_as: 404.html
|
||||
|
||||
Désolé, cette page n'existe pas.
|
||||
|
||||
`Retour en terrain connu </index.html>`_
|
|
@ -1,24 +0,0 @@
|
|||
À propos
|
||||
#########
|
||||
|
||||
:date: 2020-06-04
|
||||
:modified: 2020-06-04
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: À propos de ce site et de l'auteur.
|
||||
|
||||
Ce site
|
||||
=======
|
||||
|
||||
Ce site est né après ma première année d'enseignement. Je quittais l'établissement où j'avais été stagiaire et où j'avais beaucoup travaillé avec mes collègues. L'idée était d'avoir un lieu où ce qui avait été fait pourrait être disponible et réutilisé.
|
||||
|
||||
Aujourd'hui, il ne reste malheureusement pas grand chose de cette période à cause d'un travail d'édition trop important à réaliser pour le rendre publiable. Par contre la volonté d'avoir un lieu où tout ce que je produis pour mes cours est accessible à n'important qui est resté.
|
||||
|
||||
Il m'a fallut plusieurs années avant de réussir à trouver une façon de m'organiser pour que l'édition ne soit pas un frein à la production documents mais une façon efficace de structurer et pérenniser mon travail. Ce site en est le résultat.
|
||||
|
||||
Il repose sur une série de fichiers `reStructuredText <http://docutils.sourceforge.net/>`_ passé à la moulinette de `Pelican <https://blog.getpelican.com/>`_ pour produire le code HTML que vous voyez. Le tout est géré avec git et auto-hébergé pour garder un maximum d'indépendance.
|
||||
|
||||
L'auteur
|
||||
========
|
||||
|
||||
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
Tout sur mes cours
|
||||
##################
|
||||
|
||||
:date: 2016-01-23
|
||||
:modified: 2016-01-24
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: Résumé sur ma façon d'enseigner depuis le début ou presque.
|
||||
|
||||
|
||||
Les années qui s'écoulent
|
||||
=========================
|
||||
|
||||
Au lycée de Bellegarde.
|
||||
|
||||
- `2022/2023 </enseignements/2022-2023/>`_ Lycée de Bellegarde (Secondes, SNT, spécialité NSI, Première ST et enseignements scientifique)
|
||||
- `2021/2022 </enseignements/2021-2022/>`_ Lycée de Bellegarde (Secondes et enseignements scientifique), Établissement de santé pour adolescents à Chanay (ST et 4e)
|
||||
- `2020/2021 </enseignements/2020-2021/>`_ (SNT, Terminale ST, Terminale ST sti2d, Enseignement scientifique en terminale)
|
||||
- `2019/2020 </enseignements/2019-2020/>`_ (SNT, Première ST, Première ST sti2d, TES-L, Tsti2d)
|
||||
|
||||
Un an de TZR dans le Jura à chercher comment m'occuper.
|
||||
|
||||
- `2018/2019 </enseignements/2018-2019/>`_
|
||||
|
||||
Trois ans au collège de Kaweni 1 à Mayotte.
|
||||
|
||||
- `2017/2018 </enseignements/2017-2018/>`_ (3e, 3e passerelles, 6e)
|
||||
- `2016/2017 </enseignements/2016-2017/>`_ (3e, 5e)
|
||||
- `2015/2016 </enseignements/2015-2016/>`_ (3e, 5e, 5e passerelles)
|
||||
|
||||
Mes outils pour faire mes cours
|
||||
===============================
|
||||
|
||||
- `Zoologie des workflows </pages/a-bas-le-bon-vieux-classe-eleve-classe.html>`_
|
||||
|
||||
Méthodes, pratiques et inspirations
|
||||
===================================
|
||||
|
||||
En classe, j’aime me souvenir de cette phrase *Plus le professeur travaille, moins l’élève travaille*. Je crois que l’élève doit, le plus possible, **faire** et pas seulement écouter. Ainsi, l’élève est source de contenu pour faire avancer le cours. Il n’attend pas passivement que la bonne parole du prof lui soit donnée.
|
||||
|
||||
J’ai donc abandonné le cahier de cours au profit d’un **cahier de bord**, où l’avancée et les résultats trouvés par la classe sont inscrits. Les théorèmes ne pouvant plus être donnés, ils sont découverts par la classe et, quand c’est possible, démontrés. En relisant ce cahier, l’élève peut refaire le cheminement qui nous a permis de trouver un résultat. Il a donc à nouveau la possibilité de **comprendre** et plus seulement d’apprendre.
|
||||
|
||||
Pour que cela soit possible, il me faut choisir avec attention chaque activité. Elle a besoin d’être fractale ou riche. C’est à dire dotée de plusieurs niveaux de lecture. Chaque élève doit avoir la possibilité de faire quelque chose. Certains comprendront le sens profond de l’activité tandis que d’autres pourront simplement revoir et solidifier des acquis. L’activité elle-même apporte de la **différenciation**.
|
||||
|
||||
Comme exemple, je donnerais l’activité de découverte de `cosinus <./2017-2018/3e/Geometrie/Triangle_rectangle/>`_ . Elle permet de construire des triangles, de revoir la notion d’angle, de manipuler le rapporteur, de spiraler sur la notion d’agrandissement, de remobiliser les notions de proportionnalité, de définir le cosinus et enfin de ne pas enfermer ce cosinus dans une seule formule.
|
||||
|
||||
Ce genre d’activité, exigeante pour les élèves, peut difficilement se faire sur une heure complète. C’est pourquoi, mes heures de classe sont découpées en 2 ou 3 parties distinctes.
|
||||
|
||||
Une partie peut être dédiée à la découverte d’une notion et la suivante à la consolidation d’une notion dans un autre domaine. Ainsi les élèves ne restent pas toute l’heure en situation d’échec et ont, à chaque cours, l’opportunité de montrer qu’ils savent faire des choses. De plus, cette organisation étale d’avantage dans le temps l’apprentissage d’une notion pour la rendre plus pérenne.
|
||||
|
||||
Certains thèmes sont traités tout au long de l’année à raison d’une heure par semaine. C’est le cas du calcul littéral et de la programmation avec Scratch. Au collège, nous avons désormais accès à la salle informatique une heure par semaine. J’en profite pour travailler régulièrement la programmation avec Scratch au travers de **projets** à réaliser en équipe. La progression sur l’année est spiralée. L’objectif étant d’avoir fait le tour du programme aux vacances de Noël et ensuite, de revoir et d’approfondir les notions. Cette organisation me laisse le temps de tester plusieurs approches et de désamorcer les problèmes.
|
||||
|
||||
L’organisation de la classe a aussi été transformée afin de tirer profit de plus de diversité. Les élèves sont amenés à travailler individuellement, en groupe et en plénière. À chaque mode d’organisation son support. Quand les élèves travaillent individuellement, ils utilisent leur **cahier de recherche**. En groupe, les traces collectives sont inscrites dans le **cahier de groupe**. Et enfin, les plénières aboutissent généralement à une trace écrite dans le **cahier de bord**. Les cahiers de groupe sont ramassés à chaque fin d’heure pour que je puisse préparer la plénière de mise en commun et utiliser les productions d’élèves.
|
||||
|
||||
Ma pratique et mes cours sont très largement inspirés du livre Les maths ensemble et pour chacun. Je m’inspire aussi de ce que font `Christian den Hartigh <https://pedagogieagile.com/>`_ , `Dan Meyer <http://mrmeyer.com/>`_ ou encore `Arnaud Durand et Julien Durand <http://mathix.org/>`_.
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
À bas le bon vieux: Classe -> eleve -> classe
|
||||
#############################################
|
||||
|
||||
:date: 2018-07-07
|
||||
:modified: 2018-07-07
|
||||
:authors: Benjamin Bertrand
|
||||
:category: Autres
|
||||
:summary: Zoologie des workflows rencontrés, expérimentés ou imaginé pour la classe.
|
||||
|
||||
Ici j'essaie de faire une zoologie des façons de travailler que j'ai pu rencontrer, expérimenter ou imaginé. J'espère qu'elle va s'aggrandir avec le temps. J'espérais que cette première énumération m'aiderai à en découvrir d'autre, raté pour le moment..!
|
||||
|
||||
L'ancien
|
||||
========
|
||||
|
||||
Le seul l'unique l'indetrônable, le workflow que l'on a tous subit dans notre scolarité.
|
||||
|
||||
Pleinière -> Seul -> Pleinière
|
||||
|
||||
**Description**: Le prof ecrit le cours (propriété/théorème, exemples), les élèves font les exercices seul dans leur coin (le plus grand silence est imposé) et enfin une correction est donnée au tableau (par les élèves ou le prof).
|
||||
|
||||
**Variantes**: Avant le cours, une activité d'introduction ou des révisions sont proposés aux élèves.
|
||||
|
||||
Le cours discuté
|
||||
================
|
||||
|
||||
On écrit le cours en posant des micros questions aux élèves. On a donc des micro boucles du genre
|
||||
|
||||
Pleinière -> Seul -> Pleinière -> Seul ...
|
||||
|
||||
**Description**: Ce cours se fait à partir d'une alternance entre le prof qui fait avancer le cours et les élèves qui réfléchissent sur des temps plutôt court à des questions. Un veritable dialogue entre classe et l'enseignant s'organise.
|
||||
|
||||
Le classique
|
||||
============
|
||||
|
||||
Celui là est celui qu'on utilise le plus souvent
|
||||
|
||||
Seul -> Groupe -> Pleinière
|
||||
|
||||
**Description**: Une activité est donnée au élèves. Ils commencent à plancher dessus seul (sans interactions avec les autres élèves ou avec l'enseignant). Quand ils semblent tous se l'être appropriée (signal de l'enseignant), un travail de groupe démarre. Il se termine sur une production de groupe. Enfin, l'enseignant séléctionne quelques productions pour en faire un bilan en pleinière où la classe toute ensemble reprend les productions les critiques et les améliore pour laisser finalement une trace "parfaite" (point de vue de la classe) sur le cahier de bord.
|
||||
|
||||
**Variantes**:
|
||||
|
||||
- Avant le travail individuel, il peut être interessant de faire une lecture collective de l'activité pour s'assurer que tout le monde à le vocabulaire ou les notions traitées (à Mayotte c'est la problématique permanante).
|
||||
- Pour sortir du syndrome de la page blanche, on peut fixer le temps de sortie du travail individuel uniquement une fois que tous les élèves ont commencé à écrire quelque chose d'interessant sur leur cahier de recherche.
|
||||
- Le temps de travail de groupe peut être coupé par des rapides retours en pleinières pour que les groupes les plus avancés partagent leurs découvertes (surtout celles non terminées).
|
||||
- Il peut être interessant de changer la composition des groupes surtout vers la fin. Les élèves devront alors expliquer ce qui avait été découvert dans leur ancien groupe et integrer les découvertes des autres groupes.
|
||||
- Dans le même style, on peut designer un temps où des butineurs (un par équipe) va pouvoir aller voir (sans moyen de prendre de notes) les autres groupes.
|
||||
- La pleinière peut aussi être annimée par les élèves eux même qui viendront expliquer leur travail aux autres.
|
||||
|
||||
DMTC
|
||||
====
|
||||
|
||||
J'aime ce workflow quand il s'ajit de faire faire des taches complexes aux élèves.
|
||||
|
||||
Seul -> Groupe -> Seul
|
||||
|
||||
**Description**: L'activité débute comme *le classique*. Les élèves décrouvrent le sujet, font leurs première expérimentations puis commencent le travail de groupe. Par contre au lieu de faire un pleinière de mise en commun, les élèves terminent la rédaction seul à la maison. Le but c'est que les difficultés techniques aient été résoluent en classe et avec l'aide des autres et que le travail de rédaction, de représentation (...) soit fait individuellement.
|
||||
|
||||
**Variantes**:
|
||||
|
||||
- Pour la partie Seul et Groupe, on retrouve les même que pour le *classique*.
|
||||
- Dan Meyer dans ses 3acts proposent que les élèves cherchent eux même la question et les informations dont ils voudraient avoir accès avant le travail individuel. Cette étape peut être faire sous forme d'un petit *cours discuté*.
|
||||
|
||||
La TC prépréparé
|
||||
================
|
||||
|
||||
Le workflow précendent est particulièrement difficile à mettre en place avec les petites classes (6e, 5e). On peut alors plutôt expérimenter celui là
|
||||
|
||||
Pleinière -> Pleinière -> individuel/groupe
|
||||
|
||||
**Description**: L'activité est donnée relativement en avance. À chaque cours on en parle en pleinière et les élèves sont invités la commencer. Ensuite, on faire l'activité en classe, individuellement ou en groupe.
|
||||
|
||||
Je n'ai jamais expérimenté ce workflow mais je sais que Maxime Dupont en était adepte (en espérant ne pas l'avoir trop dénaturé) et arrivait à faire des choses interessantes avec.
|
||||
|
||||
La technique/le bachotage
|
||||
=========================
|
||||
|
||||
Workflow parfait pour les séances de travail technique ou les séances de révisions.
|
||||
|
||||
Seul -> Groupe -> Seul -> Groupe ...
|
||||
|
||||
**Description**: Une série d'exercices techniques est données. Les élèves planchent individuellement dessus. Quand les membres du groupe en ont fait quelques uns, ils mettent leurs résultats en commun et discute des différences constatés pour aboutir à la réponse "parfaite". Si un point de désaccord n'arrive pas à trouver consensus, une correction est sur le bureau qu'ils penvent consulter. Pendant ce genre de scéance, l'enseignant doit être peu solicité, c'est lui qui décide qui il veut voir.
|
||||
|
||||
**Variantes**: Organisation du travail avec un kanban. Les élèves y indiquent ce qu'ils prévoient de travailler et là où ils en sont.
|
||||
|
||||
Pair à pair
|
||||
===========
|
||||
|
||||
Workflow trop peu exploité. Les élèves produisent des documents à destinations des autres élèves.
|
||||
|
||||
Seul -> Groupe -> Seul
|
||||
|
||||
**Description**: Les élèves font un premier exercice seul (ou en suivant n'importe quel workflow). Puis en groupe, ils doivent produire un ou plusieurs exercices du même type avec la correction. Les exercices produits sont redonnés aux autres élèves.
|
||||
|
||||
On peut demander aux groupes de produire plusieurs exercices du même type mais de difficultés différentes.
|
||||
|
||||
**Variantes**:
|
||||
|
||||
- Dire aux élèves que le meileur exercice (pas forcement le plus dure) sera dans la prochaine évaluation.
|
||||
- Echange de travaux de reproduction/codage géométrique.
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
Karibu Opytex
|
||||
##############
|
||||
|
||||
:date: 2015-05-16
|
||||
:modified: 2020-08-16
|
||||
:slug: index
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: Page d'accueil
|
||||
:save_as: index.html
|
||||
|
||||
`Mes cours </pages/tout-sur-mes-cours.html>`_
|
||||
=============================================
|
||||
|
||||
Ce site regroupe tout ce que j'ai pu écrire pour mes cours de math au collège et au lycée. Vous y trouverez des notes de cours (souvent incomplètes), des fiches d'exercices, des devoirs et quelques réflexions ou commentaires à leur sujet.
|
||||
|
||||
Les année s'écoulent tranquillement au lycée de Bellegarde
|
||||
|
||||
- `2022/2023 </enseignements/2022-2023/>`_ Lycée de Bellegarde (Secondes, SNT, spécialité NSI, Première ST et enseignements scientifique)
|
||||
- `2021/2022 </enseignements/2021-2022/>`_ Lycée de Bellegarde (Secondes et enseignements scientifique), Établissement de santé pour adolescents à Chanay (ST et 4e)
|
||||
- `2020/2021 </enseignements/2020-2021/>`_ (SNT, Terminale ST, Terminale ST sti2d, Enseignement scientifique en terminale)
|
||||
- `2019/2020 </enseignements/2019-2020/>`_ (SNT, Première ST, Première ST sti2d, TES-L, Tsti2d)
|
||||
|
||||
Un an de TZR dans le Jura à chercher comment m'occuper.
|
||||
|
||||
- `2018/2019 </enseignements/2018-2019/>`_
|
||||
|
||||
Trois ans au collège de Kaweni 1 à Mayotte.
|
||||
|
||||
- `2017/2018 </enseignements/2017-2018/>`_ (3e, 3e passerelles, 6e)
|
||||
- `2016/2017 </enseignements/2016-2017/>`_ (3e, 5e)
|
||||
- `2015/2016 </enseignements/2015-2016/>`_ (3e, 5e, 5e passerelles)
|
||||
|
||||
`Un blog </blog_index.html>`_
|
||||
=============================
|
||||
|
||||
Tentative de faire un blog! On verra si j'arrive prendre le temps rédiger quelques articles où si la nécessité de communiquer avec les élèves devient trop forte!
|
||||
|
||||
`Projets informatiques </pages/projets-informatiques.html>`_
|
||||
============================================================
|
||||
|
||||
Des programmes pour enseigner.
|
||||
|
||||
- `Mapytex <https://git.opytex.org/lafrite/Mapytex>`_: calculer comme un élève
|
||||
- `Bopytex <https://git.opytex.org/lafrite/Bopytex>`_: Intègrer du python dans du latex avant compilation (utilisé pour faire mes devoirs aléatoires)
|
||||
|
||||
De l'administration système.
|
||||
|
||||
- `Gérer mes machines <https://git.opytex.org/lafrite/Ansible_workstation>`_
|
||||
|
||||
Des outils en tout genre pour regagner le temps perdu à les coder!
|
||||
|
||||
- `Ce site <https://git.opytex.org/lafrite/site_opytex>`_
|
||||
- `Photobook <https://git.opytex.org/lafrite/photobook>`_: créer des bouquins de photos
|
||||
- `Pralo <https://git.opytex.org/lafrite/Pralo>`_: faire ses comptes entre amis
|
|
@ -1,43 +0,0 @@
|
|||
Projets informatiques
|
||||
#####################
|
||||
|
||||
:date: 2020-08-16
|
||||
:modified: 2020-08-16
|
||||
:authors: Benjamin Bertrand
|
||||
:summary: Projets informatiques que je mène en parallèle de mon activité de prof.
|
||||
|
||||
À côté de mon activité de prof de mathématiques, je passe une belle partie de mon temps libre à programmer ou administrer des machines.
|
||||
|
||||
La plupart d'entre eux sont hébergés sur mon `serveur Gitea <https://git.opytex.org/lafrite>`_.
|
||||
|
||||
`Mapytex <https://git.opytex.org/lafrite/Mapytex>`_: calculer comme un élève
|
||||
============================================================================
|
||||
|
||||
Librairie Python qui permet de créer aléatoirement des objets mathématiques (calculs, fonctions, fractions...) et de simplifier ces objets avec les explications pour qu'un élève les comprenne.
|
||||
|
||||
`Bopytex <https://git.opytex.org/lafrite/Bopytex>`_: intégrer python dans latex pour créer des DM aléatoires
|
||||
=============================================================================================================
|
||||
|
||||
Librairie et outils python pour intégrer des commandes python dans du latex et de compiler les documents produits.
|
||||
|
||||
Bopytex est un outil python qui transforme un modèle de devoir en sujet individuels avec éventuellement un correction.
|
||||
|
||||
`Photobook <https://git.opytex.org/lafrite/photobook>`_: créer des bouquins de photos
|
||||
=====================================================================================
|
||||
|
||||
Outil pour créer des livres photos prêts à être imprimés.
|
||||
|
||||
`Pralo <https://git.opytex.org/lafrite/Pralo>`_: faire ses comptes entre amis
|
||||
=============================================================================
|
||||
|
||||
Quand on part avec les copains, il y a toujours le moment où il faut faire les comptes. Avec cet outils, chacun écrit ce qu'il a payé pendant le séjour et hop, on sait qui doit quoi à qui!
|
||||
|
||||
`Ce site <https://git.opytex.org/lafrite/site_opytex>`_: site statique avec pelican
|
||||
===================================================================================
|
||||
|
||||
Sources pour créer ce site internet à partir de fichers rst et de Pelican.
|
||||
|
||||
`Gérer mes machines <https://git.opytex.org/lafrite/Ansible_workstation>`_: configuration avec ansible-pull
|
||||
===========================================================================================================
|
||||
|
||||
J'administre essentiellement mes machines avec Ansible et Ansible-pull en particulier.
|
|
@ -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
|
|
@ -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',
|
||||
)
|
143
hooks/pre-commit
143
hooks/pre-commit
|
@ -1,143 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim:fenc=utf-8
|
||||
#
|
||||
# Copyright © 2017 lafrite <lafrite@Poivre>
|
||||
#
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
"""
|
||||
Git hook to ensure validity of all rst files
|
||||
"""
|
||||
|
||||
from git import Repo
|
||||
from pathlib import Path
|
||||
import re
|
||||
import time
|
||||
import restructuredtext_lint
|
||||
import sys
|
||||
|
||||
import logging
|
||||
|
||||
formatter = logging.Formatter('%(name)s :: %(levelname)s :: %(message)s')
|
||||
steam_handler = logging.StreamHandler()
|
||||
#steam_handler = logging.FileHandler('logging.conf')
|
||||
steam_handler.setLevel(logging.DEBUG)
|
||||
steam_handler.setFormatter(formatter)
|
||||
|
||||
# création de l'objet logger qui va nous servir à écrire dans les logs
|
||||
logger = logging.getLogger("precommit")
|
||||
# on met le niveau du logger à DEBUG, comme ça il écrit tout
|
||||
logger.setLevel(logging.WARNING)
|
||||
logger.addHandler(steam_handler)
|
||||
|
||||
# Files selection
|
||||
|
||||
def get_commited_files(repo):
|
||||
hdiff = repo.head.commit.diff()
|
||||
diff = {"A":[], "M":[]}
|
||||
for f in hdiff.iter_change_type("A"):
|
||||
diff["A"].append(f.b_path)
|
||||
for f in hdiff.iter_change_type("M"):
|
||||
diff["M"].append(f.b_path)
|
||||
|
||||
return diff
|
||||
|
||||
def select_by_extension(files, ext="rst"):
|
||||
return [i for i in files if i.split(".")[-1] == ext]
|
||||
|
||||
# Rst linter
|
||||
|
||||
def rst_lint(filename):
|
||||
with open(filename, 'r') as f:
|
||||
errors = restructuredtext_lint.lint(f.read())
|
||||
for e in errors:
|
||||
logger.warning(f"{filename} \n{e.full_message}\n")
|
||||
return errors
|
||||
|
||||
|
||||
# Rst parameters normalize
|
||||
|
||||
def normalize_file(filename, normalizers = {}):
|
||||
logger.debug(f"Normalizing {filename}")
|
||||
logger.debug(f"With {normalizers}")
|
||||
new_file = ""
|
||||
modified_lines = []
|
||||
with open(filename, 'r') as f:
|
||||
for l in f.readlines():
|
||||
new_line = run_normalizers(l, normalizers)
|
||||
if new_line != l:
|
||||
modified_lines.append(f"{l}")
|
||||
logger.warning(f"{filename}\n\t{l}\t{new_line}")
|
||||
new_file += new_line
|
||||
|
||||
with open(filename, "w") as f:
|
||||
f.write(new_file)
|
||||
logger.debug(f"{filename} written")
|
||||
|
||||
return modified_lines
|
||||
|
||||
def run_normalizers(line, normalizers):
|
||||
for c in normalizers:
|
||||
obs = re.search(c, line)
|
||||
if obs:
|
||||
logger.debug(f"Find for {c}")
|
||||
return normalizers[c](line)
|
||||
return line
|
||||
|
||||
# Rst function tools
|
||||
|
||||
def update_date(line):
|
||||
date = time.strftime("%Y-%m-%d")
|
||||
logger.debug(f"Update Date to: {date}")
|
||||
return f":date: {date}\n"
|
||||
|
||||
def update_modified(line):
|
||||
modified = time.strftime("%Y-%m-%d")
|
||||
logger.debug(f"Update modified to: {modified}")
|
||||
return f":modified: {modified}\n"
|
||||
|
||||
def normalize_tags(line):
|
||||
logger.debug(f"Normaizing tags")
|
||||
tags = line.split(":")[-1]
|
||||
tags = [i.strip().capitalize() for i in tags.split(",")]
|
||||
tags_str = ", ".join(tags)
|
||||
return f":tags: {tags_str}\n"
|
||||
|
||||
NORMALIZERS_MODIFIED = {":modified:.*": update_modified,
|
||||
":tags:.*": normalize_tags,
|
||||
}
|
||||
|
||||
NORMALIZERS_NEW = {":date:.*": update_date,
|
||||
":modified:.*": update_modified,
|
||||
":tags:.*": normalize_tags,
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
r = Repo()
|
||||
diff = get_commited_files(r)
|
||||
|
||||
errors = []
|
||||
modified = []
|
||||
|
||||
# New files
|
||||
for f in select_by_extension(diff["A"], "rst"):
|
||||
errors += rst_lint(f)
|
||||
modified += normalize_file(f, NORMALIZERS_NEW)
|
||||
r.index.add([f])
|
||||
# Modified files
|
||||
for f in select_by_extension(diff["M"], "rst"):
|
||||
errors += rst_lint(f)
|
||||
modified += normalize_file(f, NORMALIZERS_MODIFIED)
|
||||
r.index.add([f])
|
||||
|
||||
if len(errors) > 0:
|
||||
logger.warning("Errors in rst formating, commit aborted")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
# -----------------------------
|
||||
# Reglages pour 'vim'
|
||||
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||
# cursor: 16 del
|
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
|
|
@ -8,11 +8,10 @@ sys.path.append(os.curdir)
|
|||
from globalconf import *
|
||||
|
||||
AUTHOR = "Benjamin Bertrand"
|
||||
SITENAME = "Opytex"
|
||||
SITETITLE = "Opytex"
|
||||
SITESUBTITLE = ""
|
||||
SITENAME = "OpyTex"
|
||||
SITETITLE = "OpyTex"
|
||||
SITESUBTITLE = "2022-2023"
|
||||
SITEURL = ""
|
||||
SITEDESCRIPTION = ""
|
||||
|
||||
CC_LICENSE_COMMERCIAL = True
|
||||
CC_LICENSE = True
|
||||
|
@ -23,14 +22,40 @@ TIMEZONE = "Europe/Paris"
|
|||
|
||||
DEFAULT_LANG = "fr"
|
||||
|
||||
# theme
|
||||
THEME = "./theme/"
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
# RELATIVE_URLS = True
|
||||
|
||||
# Files places
|
||||
IGNORE_FILES = ["venv", ".git", "tools"]
|
||||
# Pages, articles and static
|
||||
# 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",
|
||||
"always_modified",
|
||||
"tag_cloud",
|
||||
"pdf-img",
|
||||
"big-button",
|
||||
"source-link",
|
||||
]
|
||||
|
||||
ALWAYS_MODIFIED = True
|
||||
|
||||
# Mirror source structure
|
||||
PATH_METADATA = "(?P<path_no_ext>.*)\..*"
|
||||
ARTICLE_URL = ARTICLE_SAVE_AS = PAGE_URL = PAGE_SAVE_AS = "{path_no_ext}.html"
|
||||
|
||||
# USE_FOLDER_AS_CATEGORY = True
|
||||
# DEFAULT_CATEGORY = "Autre"
|
||||
|
||||
# Readers
|
||||
READERS = {"html": None}
|
||||
# Everythings in french
|
||||
|
@ -42,14 +67,23 @@ DEFAULT_LANG = "fr"
|
|||
OG_LOCALE = "fr"
|
||||
LOCALE = ("fr", "fr_FR.utf8")
|
||||
|
||||
# Themes
|
||||
THEME = "./theme/"
|
||||
USE_GOOGLE_FONTS = False
|
||||
|
||||
# Pages, articles and static
|
||||
PAGE_PATHS = ["pages"]
|
||||
# ARTICLE_PATHS = ['pages/Enseignement', 'Blog']
|
||||
ARTICLE_PATHS = ["blog"]
|
||||
STATIC_PATHS = ["blog", "."]
|
||||
INDEX_SAVE_AS = "blog_index.html"
|
||||
|
||||
# Main menu on the top
|
||||
MAIN_MENU = True
|
||||
DISPLAY_CATEGORIES_ON_MENU = False
|
||||
|
||||
# Sidebar
|
||||
DISPLAY_PAGES_ON_SIDE = False
|
||||
TOCTREE = True
|
||||
TAG_CLOUD = True
|
||||
|
||||
# SITELOGO = ""
|
||||
LINKS = ()
|
||||
DEFAULT_PAGINATION = 10
|
||||
|
||||
# Feed generation is usually not desired when developing
|
||||
FEED_ALL_ATOM = None
|
||||
|
@ -58,21 +92,6 @@ TRANSLATION_FEED_ATOM = None
|
|||
AUTHOR_FEED_ATOM = None
|
||||
AUTHOR_FEED_RSS = None
|
||||
|
||||
# Blogroll
|
||||
LINKS = [
|
||||
("2015-2016", "/enseignements/2015-2016/"),
|
||||
("2016-2017", "/enseignements/2016-2017/"),
|
||||
("2017-2018", "/enseignements/2017-2018/"),
|
||||
("2018-2019", "/enseignements/2018-2019/"),
|
||||
("2019-2020", "/enseignements/2019-2020/"),
|
||||
("2020-2021", "/enseignements/2020-2021/"),
|
||||
("2021-2022", "/enseignements/2021-2022/"),
|
||||
("2022-2023", "/enseignements/2022-2023/"),
|
||||
]
|
||||
# Social widget
|
||||
SOCIAL = ()
|
||||
|
||||
DEFAULT_PAGINATION = 10
|
||||
|
||||
# Uncomment following line if you want document-relative URLs when developing
|
||||
# RELATIVE_URLS = True
|
||||
# SOURCE LINK
|
||||
GIT_SOURCE_BASE_URL = "https://git.opytex.org/lafrite/2022-2023/src/branch/main"
|
||||
SOURCE_ICON_URL = "https://git.opytex.org/assets/img/logo.svg"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
from .always_modified import *
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
If "modified" date/time is not defined in article metadata, fall back to the "created" date.
|
||||
"""
|
||||
|
||||
from pelican import signals
|
||||
from pelican.contents import Content, Article
|
||||
|
||||
|
||||
def add_modified(content):
|
||||
if not isinstance(content, Article):
|
||||
return
|
||||
|
||||
if not content.settings.get("ALWAYS_MODIFIED", False):
|
||||
return
|
||||
|
||||
if hasattr(content, "date") and not hasattr(content, "modified"):
|
||||
content.modified = content.date
|
||||
content.locale_modified = content.locale_date
|
||||
|
||||
|
||||
def register():
|
||||
signals.content_object_init.connect(add_modified)
|
|
@ -0,0 +1,14 @@
|
|||
# Always Modified
|
||||
|
||||
Say you want to sort by modified date/time in a theme template, but not all
|
||||
your articles have modified date/timestamps explicitly defined in article
|
||||
metadata. This plugin facilitates that sorting by assuming the modified date
|
||||
(if undefined) is equal to the created date.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Add `ALWAYS_MODIFIED = True` to your settings file.
|
||||
2. Now you can sort by modified date in your templates:
|
||||
|
||||
{% for article in articles|sort(reverse=True,attribute='modified') %}
|
||||
|
|
@ -0,0 +1 @@
|
|||
from .big_button import *
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
big_button tags for reStructuredText
|
||||
==============================
|
||||
This plugin allows you to use big_button tags from within reST documents.
|
||||
|
||||
.. big_button::
|
||||
:title: Title
|
||||
:link: ""
|
||||
:color: default
|
||||
|
||||
Description
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives, Directive
|
||||
|
||||
|
||||
class BigButton(Directive):
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
has_content = True
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = False
|
||||
option_spec = {
|
||||
"title": directives.unicode_code,
|
||||
"link": directives.path,
|
||||
}
|
||||
|
||||
def settings(self):
|
||||
self.options['content'] = '\n'.join(self.content)
|
||||
|
||||
if not self.options.get('title'):
|
||||
self.options['title'] = 0
|
||||
if not self.options.get('link'):
|
||||
self.options['link'] = 0
|
||||
|
||||
def html(self):
|
||||
html = "<div class='button'>\n"
|
||||
if self.options["link"]:
|
||||
html += f"<a href={self.options['link']}>"
|
||||
else:
|
||||
html += f"<div class='nolink'>"
|
||||
if self.options["title"]:
|
||||
html += f"<h3> {self.options['title']}</h3>"
|
||||
if self.content:
|
||||
html += "<div class='content'>"
|
||||
html += f"{self.options['content']}"
|
||||
html += "</div>"
|
||||
if self.options["link"]:
|
||||
html += "</a>"
|
||||
else:
|
||||
html += "</div>"
|
||||
html += "</div>"
|
||||
return html
|
||||
|
||||
def run(self):
|
||||
self.settings()
|
||||
return [nodes.raw('', self.html(), format='html')]
|
||||
|
||||
|
||||
def register():
|
||||
directives.register_directive("big_button", BigButton)
|
|
@ -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)
|
|
@ -1,7 +0,0 @@
|
|||
404 stránka
|
||||
===========
|
||||
:slug: 404
|
||||
:lang: cz
|
||||
:status: hidden
|
||||
|
||||
Jednoduchá 404 stránka.
|
|
@ -1,7 +0,0 @@
|
|||
Eine 404 Seite
|
||||
==============
|
||||
:slug: 404
|
||||
:lang: de
|
||||
:status: hidden
|
||||
|
||||
Eine einfache 404 Seite.
|
|
@ -1,7 +0,0 @@
|
|||
A 404 page
|
||||
==========
|
||||
:slug: 404
|
||||
:lang: en
|
||||
:status: hidden
|
||||
|
||||
A simple 404 page.
|
|
@ -1,5 +0,0 @@
|
|||
Untranslated page
|
||||
=================
|
||||
:lang: en
|
||||
|
||||
This page has no translation.
|
|
@ -1,8 +0,0 @@
|
|||
Přeložený článek
|
||||
================
|
||||
:slug: translated-article
|
||||
:lang: cz
|
||||
:date: 2014-09-15
|
||||
|
||||
Jednoduchý článek s překlady.
|
||||
Zde je odkaz na `nějaký obrázek <{filename}/images/img.png>`_.
|
|
@ -1,8 +0,0 @@
|
|||
Ein übersetzter Artikel
|
||||
=======================
|
||||
:slug: translated-article
|
||||
:lang: de
|
||||
:date: 2014-09-14
|
||||
|
||||
Ein einfacher Artikel mit einer Übersetzung.
|
||||
Hier ist ein Link zur `einigem Bild <{filename}/images/img.png>`_.
|
|
@ -1,8 +0,0 @@
|
|||
A translated article
|
||||
====================
|
||||
:slug: translated-article
|
||||
:lang: en
|
||||
:date: 2014-09-13
|
||||
|
||||
A simple article with a translation.
|
||||
Here is a link to `some image <{filename}/images/img.png>`_.
|
|
@ -1,9 +0,0 @@
|
|||
An untranslated article
|
||||
=======================
|
||||
:date: 2014-07-14
|
||||
:lang: en
|
||||
|
||||
An article without a translation.
|
||||
Here is a link to an `untranslated page`_
|
||||
|
||||
.. _`untranslated page`: {filename}/pages/untranslated-page.rst
|
|
@ -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)
|
|
@ -0,0 +1,31 @@
|
|||
# Pelican source link plugin
|
||||
|
||||
This plugin for [Pelican](https://github.com/getpelican/pelican/) generate two attributes for articles:
|
||||
|
||||
- `source_link`: link to the source of the article from your forge
|
||||
- `path_source_link`: link to the path of the article from your forge
|
||||
|
||||
## Installation
|
||||
|
||||
Then, add the plugin to your pelicanconf.py file:
|
||||
|
||||
```python
|
||||
PLUGINS = [
|
||||
# other plugins...
|
||||
"source_link",
|
||||
]
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To use the plugin, define a constant named `GIT_SOURCE` in your pelicanconf.py file:
|
||||
|
||||
```python
|
||||
GIT_SOURCE_BASE_URLL = "https://github.com/your-username/your-repo"
|
||||
```
|
||||
|
||||
This constant should contain the base URL of your Git repository where your source code is stored.
|
||||
|
||||
Once the constant is defined, the plugin will generate a `source_link` and a `path_source_link` attributes for each article in your Pelican project.
|
||||
|
||||
Those links are generated based on the article's source path relative to the root directory of your Pelican project. If the constant PATH is defined in pelicanconf.py, the plugin will use this value as the root directory. Otherwise, it will use the default value of "", which assumes that your Pelican project is located in the same directory as your pelicanconf.py file.
|
|
@ -0,0 +1 @@
|
|||
from .source_link import *
|
|
@ -0,0 +1,37 @@
|
|||
from pelican import signals
|
||||
import logging
|
||||
import os
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
|
||||
|
||||
def set_default_settings(settings):
|
||||
settings.setdefault("GIT_SOURCE_BASE_URL", None)
|
||||
|
||||
|
||||
def init_default_config(pelican):
|
||||
set_default_settings(DEFAULT_CONFIG)
|
||||
if pelican:
|
||||
set_default_settings(pelican.settings)
|
||||
|
||||
|
||||
def source_link_generator(article_generator):
|
||||
git_source = article_generator.settings.get(
|
||||
"GIT_SOURCE_BASE_URL", DEFAULT_CONFIG["GIT_SOURCE_BASE_URL"]
|
||||
)
|
||||
root_path = article_generator.settings.get("PATH", DEFAULT_CONFIG.get("PATH", ""))
|
||||
for article in article_generator.articles:
|
||||
article_path = os.path.abspath(os.path.join(root_path, article.source_path))
|
||||
relative_path = os.path.relpath(article_path, root_path)
|
||||
if git_source.endswith("/"):
|
||||
article.source_link = f"{git_source}{relative_path}"
|
||||
else:
|
||||
article.source_link = f"{git_source}/{relative_path}"
|
||||
|
||||
article.path_source_link = "/".join(article.source_link.split("/")[:-1])
|
||||
|
||||
|
||||
def register():
|
||||
signals.initialized.connect(init_default_config)
|
||||
signals.article_generator_finalized.connect(source_link_generator)
|
|
@ -0,0 +1,98 @@
|
|||
tag_cloud
|
||||
=========
|
||||
|
||||
This plugin generates a tag-cloud.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
In order to use to use this plugin, you have to edit(*) or create(+) the following files::
|
||||
|
||||
blog/
|
||||
├── pelicanconf.py *
|
||||
├── content
|
||||
├── plugins +
|
||||
│ └── tag_cloud.py +
|
||||
└── themes
|
||||
└── mytheme
|
||||
├── templates
|
||||
│ └── base.html *
|
||||
└── static
|
||||
└── css
|
||||
└── style.css *
|
||||
|
||||
In **pelicanconf.py** you have to activate the plugin::
|
||||
|
||||
PLUGIN_PATHS = ["plugins"]
|
||||
PLUGINS = ["tag_cloud"]
|
||||
|
||||
Into your **plugins** folder, you should add tag_cloud.py (from this repository).
|
||||
|
||||
In your theme files, you should change **base.html** to apply formats (and sizes) defined in **style.css**, as specified in "Settings", below.
|
||||
|
||||
Settings
|
||||
--------
|
||||
|
||||
================================================ =====================================================
|
||||
Setting name (followed by default value) What does it do?
|
||||
================================================ =====================================================
|
||||
``TAG_CLOUD_STEPS = 4`` Count of different font sizes in the tag
|
||||
cloud.
|
||||
``TAG_CLOUD_MAX_ITEMS = 100`` Maximum number of tags in the cloud.
|
||||
``TAG_CLOUD_SORTING = 'random'`` The tag cloud ordering scheme. Valid values:
|
||||
random, alphabetically, alphabetically-rev, size and
|
||||
size-rev
|
||||
``TAG_CLOUD_BADGE = True`` Optionnal setting : can bring **badges**, which mean
|
||||
say : display the number of each tags present
|
||||
on all articles.
|
||||
================================================ =====================================================
|
||||
|
||||
The default theme does not include a tag cloud, but it is pretty easy to add one::
|
||||
|
||||
<ul class="tagcloud">
|
||||
{% for tag in tag_cloud %}
|
||||
<li class="tag-{{ tag.1 }}">
|
||||
<a href="{{ SITEURL }}/{{ tag.0.url }}">
|
||||
{{ tag.0 }}
|
||||
{% if TAG_CLOUD_BADGE %}
|
||||
<span class="badge">{{ tag.2 }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
You should then also define CSS styles with appropriate classes (tag-1 to tag-N,
|
||||
where N matches ``TAG_CLOUD_STEPS``), tag-1 being the most frequent, and
|
||||
define a ``ul.tagcloud`` class with appropriate list-style to create the cloud.
|
||||
You should copy/paste this **badge** CSS rule ``ul.tagcloud .list-group-item <span>.badge``
|
||||
if you're using ``TAG_CLOUD_BADGE`` setting. (this rule, potentially long , is suggested to avoid
|
||||
conflicts with CSS libs as twitter Bootstrap)
|
||||
|
||||
For example::
|
||||
|
||||
ul.tagcloud {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.tagcloud li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
li.tag-1 {
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
li.tag-2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
/* ... add li.tag-3 etc, as much as needed */
|
||||
|
||||
ul.tagcloud .list-group-item span.badge {
|
||||
background-color: grey;
|
||||
color: white;
|
||||
}
|
||||
|
||||
By default the tags in the cloud are sorted randomly, but if you prefers to have it alphabetically use the `alphabetically` (ascending) and `alphabetically-rev` (descending). Also is possible to sort the tags by it's size (number of articles with this specific tag) using the values `size` (ascending) and `size-rev` (descending).
|
|
@ -0,0 +1,2 @@
|
|||
from .tag_cloud import *
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
'''
|
||||
tag_cloud
|
||||
===================================
|
||||
|
||||
This plugin generates a tag cloud from available tags
|
||||
'''
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from collections import defaultdict
|
||||
from operator import itemgetter
|
||||
|
||||
import logging
|
||||
import math
|
||||
import random
|
||||
|
||||
from pelican import signals
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def set_default_settings(settings):
|
||||
settings.setdefault('TAG_CLOUD_STEPS', 4)
|
||||
settings.setdefault('TAG_CLOUD_MAX_ITEMS', 100)
|
||||
settings.setdefault('TAG_CLOUD_SORTING', 'random')
|
||||
settings.setdefault('TAG_CLOUD_BADGE', False)
|
||||
|
||||
|
||||
def init_default_config(pelican):
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
set_default_settings(DEFAULT_CONFIG)
|
||||
if(pelican):
|
||||
set_default_settings(pelican.settings)
|
||||
|
||||
|
||||
def generate_tag_cloud(generator):
|
||||
tag_cloud = defaultdict(int)
|
||||
for article in generator.articles:
|
||||
for tag in getattr(article, 'tags', []):
|
||||
tag_cloud[tag] += 1
|
||||
|
||||
tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True)
|
||||
tag_cloud = tag_cloud[:generator.settings.get('TAG_CLOUD_MAX_ITEMS')]
|
||||
|
||||
tags = list(map(itemgetter(1), tag_cloud))
|
||||
if tags:
|
||||
max_count = tags[0]
|
||||
min_count = tags[-1]
|
||||
steps = generator.settings.get('TAG_CLOUD_STEPS')
|
||||
|
||||
# calculate word sizes
|
||||
def generate_tag(tag, count):
|
||||
tag = (
|
||||
tag,
|
||||
int(math.floor(steps - (steps - 1) * math.log(count - min_count + 1)
|
||||
/ (math.log(max_count - min_count + 1) or 1)))
|
||||
)
|
||||
if generator.settings.get('TAG_CLOUD_BADGE'):
|
||||
tag += (count,)
|
||||
return tag
|
||||
|
||||
tag_cloud = [
|
||||
generate_tag(tag, count)
|
||||
for tag, count in tag_cloud
|
||||
]
|
||||
|
||||
sorting = generator.settings.get('TAG_CLOUD_SORTING')
|
||||
|
||||
if sorting == 'alphabetically':
|
||||
tag_cloud.sort(key=lambda elem: elem[0].name)
|
||||
elif sorting == 'alphabetically-rev':
|
||||
tag_cloud.sort(key=lambda elem: elem[0].name, reverse=True)
|
||||
elif sorting == 'size':
|
||||
tag_cloud.sort(key=lambda elem: elem[1])
|
||||
elif sorting == 'size-rev':
|
||||
tag_cloud.sort(key=lambda elem: elem[1], reverse=True)
|
||||
elif sorting == 'random':
|
||||
random.shuffle(tag_cloud)
|
||||
else:
|
||||
logger.warning("setting for TAG_CLOUD_SORTING not recognized: %s, "
|
||||
"falling back to 'random'", sorting)
|
||||
random.shuffle(tag_cloud)
|
||||
|
||||
# make available in context
|
||||
generator.tag_cloud = tag_cloud
|
||||
generator._update_context(['tag_cloud'])
|
||||
|
||||
|
||||
def register():
|
||||
signals.initialized.connect(init_default_config)
|
||||
signals.article_generator_finalized.connect(generate_tag_cloud)
|
|
@ -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 = ''
|
||||
SITEURL = 'https://opytex.org/enseignements/2022-2023/'
|
||||
RELATIVE_URLS = False
|
||||
|
||||
FEED_ALL_ATOM = 'feeds/all.atom.xml'
|
||||
|
|
32
tasks.py
32
tasks.py
|
@ -17,26 +17,10 @@ LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
|
|||
SETTINGS.update(LOCAL_SETTINGS)
|
||||
|
||||
CONFIG = {
|
||||
'current_path': os.getcwd(),
|
||||
'settings_base': SETTINGS_FILE_BASE,
|
||||
'settings_publish': 'publishconf.py',
|
||||
|
||||
'year_subfolder': '',
|
||||
|
||||
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
|
||||
'deploy_path': SETTINGS['OUTPUT_PATH'],
|
||||
|
||||
'fake_path': '../output/',
|
||||
|
||||
# Remote server configuration
|
||||
'ssh_user': 'sshcontent',
|
||||
'ssh_host': 'Embrevade',
|
||||
'ssh_port': '22',
|
||||
'ssh_path': '/home/sshcontent/opytex.org/www/',
|
||||
|
||||
# Rsync config
|
||||
'rsync_exclude': '--exclude "pymath" --exclude "opytex" --exclude "enseignements"',
|
||||
|
||||
# Port for `serve`
|
||||
'port': 8000,
|
||||
}
|
||||
|
@ -51,7 +35,6 @@ def clean(c):
|
|||
@task
|
||||
def build(c):
|
||||
"""Build local version of site"""
|
||||
c.run('lessc {current_path}/theme/static/stylesheet/style.less {current_path}/theme/static/stylesheet/style.min.css -x'.format(**CONFIG))
|
||||
c.run('pelican -s {settings_base}'.format(**CONFIG))
|
||||
|
||||
@task
|
||||
|
@ -119,18 +102,9 @@ def publish(c):
|
|||
"""Publish to production via rsync"""
|
||||
c.run('pelican -s {settings_publish}'.format(**CONFIG))
|
||||
c.run(
|
||||
'rsync --delete {rsync_exclude} -pthrvz -c '
|
||||
'-e "ssh " '
|
||||
'{} {ssh_host}:{ssh_path}'.format(
|
||||
'rsync --delete --exclude ".DS_Store" -pthrvz -c '
|
||||
'-e "ssh -p {ssh_port}" '
|
||||
'{} {ssh_user}@{ssh_host}:{ssh_path}'.format(
|
||||
CONFIG['deploy_path'].rstrip('/') + '/',
|
||||
**CONFIG))
|
||||
|
||||
@task(
|
||||
pre=[build]
|
||||
)
|
||||
def fake(c):
|
||||
""" Mimic a push to server """
|
||||
print('{fake_path}{year_subfolder}'.format(**CONFIG))
|
||||
os.makedirs('{fake_path}{year_subfolder}'.format(**CONFIG), exist_ok=True)
|
||||
c.run('rsync -P -rvzc --delete {rsync_exclude} {deploy_path}/ {fake_path}{year_subfolder} --cvs-exclude'.format(**CONFIG))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../atob/bin/atob.js
|
|
@ -0,0 +1 @@
|
|||
../color-support/bin.js
|
|
@ -0,0 +1 @@
|
|||
../gulp/bin/gulp.js
|
|
@ -0,0 +1 @@
|
|||
../mkdirp/bin/cmd.js
|
|
@ -0,0 +1 @@
|
|||
../semver/bin/semver
|
|
@ -0,0 +1 @@
|
|||
../strip-bom/cli.js
|
|
@ -0,0 +1 @@
|
|||
../user-home/cli.js
|
|
@ -0,0 +1 @@
|
|||
../which/bin/which
|
|
@ -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.
|
|
@ -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);
|
||||
};
|
|
@ -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"
|
||||
}
|
|
@ -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._
|
|
@ -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;
|
||||
};
|
|
@ -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.
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
|
@ -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
|
||||
});
|
|
@ -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.
|
|
@ -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"
|
||||
}
|
|
@ -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)
|
|
@ -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.
|
|
@ -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._
|
|
@ -0,0 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function(a, b, msg) {
|
||||
return '\u001b['+ a + 'm' + msg + '\u001b[' + b + 'm';
|
||||
};
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
|
@ -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.
|
|
@ -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);
|
|
@ -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);
|
|
@ -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('')
|
||||
;
|
||||
};
|
|
@ -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"
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
});
|
|
@ -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();
|
||||
});
|
|
@ -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();
|
||||
});
|
|
@ -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.
|
|
@ -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._
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
}
|
|
@ -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.
|
|
@ -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._
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue