diff --git a/.gitignore b/.gitignore index a91c88e..d700c78 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,518 @@ dist/ build/ __pycache__ -.DS_Store \ No newline at end of file +.DS_Store +# Created by https://www.gitignore.io/api/r,macos,python,pycharm,windows,visualstudio,jupyternotebooks +# Edit at https://www.gitignore.io/?templates=r,macos,python,pycharm,windows,visualstudio,jupyternotebooks + +### JupyterNotebooks ### +# gitignore template for Jupyter Notebooks +# website: http://jupyter.org/ +.ipynb_checkpoints +*/.ipynb_checkpoints/* +# IPython +profile_default/ +ipython_config.py +# Remove previous ipynb_checkpoints +# git rm -r .ipynb_checkpoints/ +### macOS ### +# General +.AppleDouble +.LSOverride +# Icon must end with two \r +Icon +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### PyCharm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf +# Generated files +.idea/**/contentModel.xml +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml +# Gradle +.idea/**/gradle.xml +.idea/**/libraries +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr +# CMake +cmake-build-*/ +# Mongo Explorer plugin +.idea/**/mongoSettings.xml +# File-based project format +*.iws +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ +# JIRA plugin +atlassian-ide-plugin.xml +# Cursive Clojure plugin +.idea/replstate.xml +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +# Editor-based Rest Client +.idea/httpRequests +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser +### PyCharm Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 +# modules.xml +# .idea/misc.xml +# Sonarlint plugin +.idea/**/sonarlint/ +# SonarQube Plugin +.idea/**/sonarIssues.xml +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +# C extensions +*.so +# Distribution / packaging +.Python +develop-eggs/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +# 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/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ +# Translations +*.mo +*.pot +# Scrapy stuff: +.scrapy +# Sphinx documentation +docs/_build/ +# PyBuilder +target/ +# pyenv +.python-version +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock +# celery beat schedule file +celerybeat-schedule +# SageMath parsed files +*.sage.py +# Spyder project settings +.spyderproject +.spyproject +# Rope project settings +.ropeproject +# Mr Developer +.mr.developer.cfg +.project +.pydevproject +# mkdocs documentation +/site +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json +# Pyre type checker +.pyre/ +### R ### +# History files +.Rhistory +.Rapp.history +# Session Data files +.RData +# User-specific files +.Ruserdata +# Example code in package build process +*-Ex.R +# Output files from R CMD build +/*.tar.gz +# Output files from R CMD check +/*.Rcheck/ +# RStudio files +.Rproj.user/ +# produced vignettes +vignettes/*.html +vignettes/*.pdf +# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 +.httr-oauth +# knitr and R markdown default cache directories +*_cache/ +/cache/ +# Temporary files created by R markdown +*.utf8.md +*.knit.md +### R.Bookdown Stack ### +# R package: bookdown caching files +/*_files/ +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +# Dump file +*.stackdump +# Folder config file +[Dd]esktop.ini +# Recycle Bin used on file shares +$RECYCLE.BIN/ +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp +# Windows shortcuts +*.lnk +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs +# Mono auto generated files +mono_crash.* +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ +# Visual Studio 2017 auto generated files +Generated\ Files/ +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c +# Benchmark Results +BenchmarkDotNet.Artifacts/ +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +# StyleCop +StyleCopReport.xml +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc +# Chutzpah Test files +_Chutzpah* +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap +# Visual Studio Trace Files +*.e2e +# TFS 2012 Local Workspace +$tf/ +# Guidance Automation Toolkit +*.gpState +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user +# JustCode is a .NET coding add-in +.JustCode +# TeamCity is a build add-in +_TeamCity* +# DotCover is a Code Coverage Tool +*.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json +# Visual Studio code coverage results +*.coverage +*.coveragexml +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* +# MightyMoose +*.mm.* +AutoTest.Net/ +# Web workbench (sass) +.sass-cache/ +# Installshield output folder +[Ee]xpress/ +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html +# Click-Once directory +publish/ +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets +# Microsoft Azure Build Output +csx/ +*.build.csdef +# Microsoft Azure Emulator +ecf/ +rcf/ +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ +# RIA/Silverlight projects +Generated_Code/ +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak +# SQL Server files +*.mdf +*.ldf +*.ndf +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl +# Microsoft Fakes +FakesAssemblies/ +# GhostDoc plugin setting file +*.GhostDoc.xml +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ +# Visual Studio 6 build log +*.plg +# Visual Studio 6 workspace options file +*.opt +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions +# Paket dependency manager +.paket/paket.exe +paket-files/ +# FAKE - F# Make +.fake/ +# CodeRush personal settings +.cr/personal +# Python Tools for Visual Studio (PTVS) +*.pyc +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config +# Tabs Studio +*.tss +# Telerik's JustMock configuration file +*.jmconfig +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs +# OpenCover UI analysis results +OpenCover/ +# Azure Stream Analytics local run output +ASALocalRun/ +# MSBuild Binary and Structured Log +*.binlog +# NVidia Nsight GPU debugger configuration file +*.nvuser +# MFractors (Xamarin productivity tool) working folder +.mfractor/ +# Local History for Visual Studio +.localhistory/ +# BeatPulse healthcheck temp database +healthchecksdb +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ +# End of https://www.gitignore.io/api/r,macos,python,pycharm,windows,visualstudio,jupyternotebooks diff --git a/README.md b/README.md index 90754be..c1beceb 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,16 @@ # mkdocs-git-revision-date-localized-plugin -[MkDocs](https://www.mkdocs.org/) plugin that displays the localized date of the last modification of a markdown file. Forked from [mkdocs-git-revision-date-plugin](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin) +[MkDocs](https://www.mkdocs.org/) plugin that enables displaying the localized date of the last git modification of a markdown file. Forked from [mkdocs-git-revision-date-plugin](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin). + +![example](example.png) + +(*Example when used together with [mkdocs-material](https://github.com/squidfunk/mkdocs-material) theme*) ## Setup Install the plugin using pip: ```bash -# FIRST VERSION NOT YET PUBLISHED pip install mkdocs-git-revision-date-localized-plugin ``` @@ -26,7 +29,7 @@ In templates you can use `page.meta.git_revision_date_localized`: ```django hljs {% if page.meta.git_revision_date_localized %} -
Updated {{ page.meta.git_revision_date_localized }}
+ Last update: {{ page.meta.git_revision_date_localized }} {% endif %} ``` @@ -35,29 +38,29 @@ In templates you can use `page.meta.git_revision_date_localized`: In your markdown files you can use `{{ git_revision_date_localized }}`: ```django hljs -Updated {{ git_revision_date_localized_iso }} +Last update: {{ git_revision_date_localized }} ``` -## Localization updates - -There are three date formats: +## Localizated variants -- A date string format (using [babel](https://github.com/python-babel/babel/tree/master/babel) -- A ISO format *(YYYY-mm-dd)* -- A time ago format (using [timeago](https://github.com/hustcc/timeago) +The plugin uses [babel](https://github.com/python-babel/babel/tree/master/babel) and [timeago](https://github.com/hustcc/timeago) to provide different date formats: ```django hljs -Updated {{ git_revision_date_localized }} -Updated {{ git_revision_date_localized_iso }} -Updated {{ git_revision_date_localized_timeago }} +{{ git_revision_date_localized }} +{{ git_revision_date_localized_time }} +{{ git_revision_date_localized_iso }} +{{ git_revision_date_localized_iso_time }} +{{ git_revision_date_localized_timeago }} ``` Output: ``` -Updated 28 November, 2019 -Updated 2019-11-28 -Updated 20 hours agon +28 November, 2019 +28 November, 2019 13:57:28 +2019-11-28 +2019-11-28 13:57:26 +20 hours ago ``` ## Options diff --git a/example.png b/example.png new file mode 100644 index 0000000..6213362 Binary files /dev/null and b/example.png differ diff --git a/mkdocs_git_revision_date_localized_plugin/plugin.py b/mkdocs_git_revision_date_localized_plugin/plugin.py new file mode 100644 index 0000000..20013fd --- /dev/null +++ b/mkdocs_git_revision_date_localized_plugin/plugin.py @@ -0,0 +1,70 @@ +from os import environ + +from mkdocs.config import config_options +from mkdocs.plugins import BasePlugin +from mkdocs.utils import string_types +from jinja2 import Template +from .util import Util +from datetime import datetime + + +class GitRevisionDateLocalizedPlugin(BasePlugin): + config_scheme = ( + ('locale', config_options.Type(string_types, default='')), + ('modify_md', config_options.Type(bool, default=True)) + ) + + def __init__(self): + self.locale = 'en' + self.util = Util() + + def on_config(self, config): + + # Get locale settings + mkdocs_locale = config.get('locale') + plugin_locale = self.config['locale'] + theme_locale = vars(config['theme']).get('_vars', {}).get('locale') + if theme_locale is None: + theme_locale = vars(config['theme']).get('_vars', {}).get('language') + + # First prio: plugin locale + if plugin_locale != '': + if plugin_locale != mkdocs_locale: + print(f"WARNING - plugin locale setting '{plugin_locale}' will overwrite mkdocs locale '{mkdocs_locale}'") + self.locale = mkdocs_locale + return + + # Second prio: theme + if theme_locale: + self.locale = theme_locale + # Third is mkdocs locale setting (might be add in the future) + if mkdocs_locale: + self.locale = mkdocs_locale + + # Final fallback is english + return + + + def on_page_markdown(self, markdown, page, config, files): + + revision_dates = self.util.get_revision_date_for_file( + path = page.file.abs_src_path, + locale = self.locale + ) + + for variable, date in revision_dates.items(): + page.meta[variable] = date + + if 'macros' in config['plugins']: + keys = list(config['plugins'].keys()) + vals = list(config['plugins'].values()) + if keys.index('macros') > vals.index(self): + for variable, date in revision_dates.items(): + markdown = '{{% set' + variable + f" = '{date}' " + ' %}}' + markdown + return markdown + else: + print('WARNING - macros plugin must be placed AFTER the git-revision-date-localized plugin. Skipping markdown modifications') + return markdown + else: + return Template(markdown).render(revision_dates) + diff --git a/mkdocs_git_revision_date_localized_plugin/util.py b/mkdocs_git_revision_date_localized_plugin/util.py new file mode 100644 index 0000000..4f9a845 --- /dev/null +++ b/mkdocs_git_revision_date_localized_plugin/util.py @@ -0,0 +1,29 @@ +from git import Git +from datetime import datetime +import timeago +from babel.dates import format_date + +class Util: + + def __init__(self): + self.g = Git() + + def get_revision_date_for_file(self, path: str, locale: str = 'en'): + + unix_timestamp = self.g.log(path, n=1, date='short', format='%at') + if not unix_timestamp: + revision_date = datetime.now() + print('WARNING - %s has no git logs, revision date defaulting to today\'s date' % path) + else: + revision_date = datetime.utcfromtimestamp(int(unix_timestamp)) + + # Localized versions + revision_dates = { + 'git_revision_date_localized' : format_date(revision_date, format="long", locale=locale), + 'git_revision_date_localized_time' : format_date(revision_date, format="long", locale=locale) + ' ' +revision_date.strftime("%H:%M:%S"), + 'git_revision_date_localized_iso' : revision_date.strftime("%Y-%m-%d"), + 'git_revision_date_localized_iso_time' : revision_date.strftime("%Y-%m-%d %H:%M:%S"), + 'git_revision_date_localized_timeago' : timeago.format(revision_date, locale = locale) + } + + return revision_dates \ No newline at end of file diff --git a/mkdocs_git_revision_date_plugin/__init__.py b/mkdocs_git_revision_date_plugin/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/mkdocs_git_revision_date_plugin/plugin.py b/mkdocs_git_revision_date_plugin/plugin.py deleted file mode 100644 index 7c3c952..0000000 --- a/mkdocs_git_revision_date_plugin/plugin.py +++ /dev/null @@ -1,55 +0,0 @@ -from os import environ - -from mkdocs.config import config_options -from mkdocs.plugins import BasePlugin -from mkdocs.utils import string_types -from jinja2 import Template -from .util import Util - - -class GitRevisionDatePlugin(BasePlugin): - config_scheme = ( - ('enabled_if_env', config_options.Type(string_types)), - ('modify_md', config_options.Type(bool, default=True)) - ) - - def __init__(self): - self.enabled = True - self.util = Util() - - def on_config(self, config): - env_name = self.config['enabled_if_env'] - if env_name: - self.enabled = environ.get(env_name) == '1' - if not self.enabled: - print('PDF export is disabled (set environment variable %s to 1 to enable)' % env_name) - return - - def on_page_markdown(self, markdown, page, config, files): - if not self.enabled: - return markdown - - revision_date = self.util.get_revision_date_for_file(page.file.abs_src_path) - - if not revision_date: - from datetime import datetime - revision_date = datetime.now().date() - print('WARNING - %s has no git logs, revision date defaulting to today\'s date' % page.file.src_path) - - page.meta['revision_date'] = revision_date - - if not self.config['modify_md']: - return markdown - - if 'macros' in config['plugins']: - keys = list(config['plugins'].keys()) - vals = list(config['plugins'].values()) - if keys.index('macros') > vals.index(self): - new_markdown = '{{% set git_revision_date = \'{}\' %}}\n'.format(revision_date) + markdown - return new_markdown - else: - print('WARNING - macros plugin must be placed AFTER the git-revision-date plugin. Skipping markdown modifications') - return markdown - else: - md_template = Template(markdown) - return md_template.render({'git_revision_date': revision_date}) \ No newline at end of file diff --git a/mkdocs_git_revision_date_plugin/util.py b/mkdocs_git_revision_date_plugin/util.py deleted file mode 100644 index d9ce8f7..0000000 --- a/mkdocs_git_revision_date_plugin/util.py +++ /dev/null @@ -1,9 +0,0 @@ -from git import Git - -class Util: - - def __init__(self): - self.g = Git() - - def get_revision_date_for_file(self, path: str): - return self.g.log(path, n=1, date='short', format='%ad') \ No newline at end of file diff --git a/setup.py b/setup.py index ae82578..69f4e8f 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,26 @@ from setuptools import setup, find_packages setup( - name='mkdocs-git-revision-date-plugin', - version='0.1.5', - description='MkDocs plugin for setting revision date from git per markdown file.', - keywords='mkdocs git meta yaml frontmatter', - url='https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin/', - author='Terry Zhao', - author_email='zhao.terryy@gmail.com', + name='mkdocs-git-revision-date-localized-plugin', + version='0.2', + description='Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file.', + keywords='mkdocs git date timeago babel plugin', + url='https://github.com/timvink/mkdocs-git-revision-date-localized-plugin/', + author='Tim Vink', + author_email='vinktim@gmail.com', license='MIT', python_requires='>=3.4', install_requires=[ 'mkdocs>=0.17', 'GitPython', - 'jinja2' + 'jinja2', + 'babel>=2.7.0', + 'timeago>=1.0.10' ], packages=find_packages(), entry_points={ 'mkdocs.plugins': [ - 'git-revision-date = mkdocs_git_revision_date_plugin.plugin:GitRevisionDatePlugin' + 'git-revision-date-localized = mkdocs_git_revision_date_localized_plugin.plugin:GitRevisionDateLocalizedPlugin' ] } ) \ No newline at end of file