mkdocs-document-dates 3.8.1__tar.gz → 3.8.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {mkdocs_document_dates-3.8.1/mkdocs_document_dates.egg-info → mkdocs_document_dates-3.8.5}/PKG-INFO +2 -1
  2. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/plugin.py +64 -33
  3. mkdocs_document_dates-3.8.1/mkdocs_document_dates/static/config/user.config.css → mkdocs_document_dates-3.8.5/mkdocs_document_dates/static/config/config.css +1 -1
  4. mkdocs_document_dates-3.8.1/mkdocs_document_dates/static/config/user.config.js → mkdocs_document_dates-3.8.5/mkdocs_document_dates/static/config/config.js +1 -1
  5. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/default.config.js +1 -1
  6. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/utils.py +49 -11
  7. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5/mkdocs_document_dates.egg-info}/PKG-INFO +2 -1
  8. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates.egg-info/SOURCES.txt +2 -2
  9. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates.egg-info/requires.txt +1 -0
  10. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/pyproject.toml +3 -2
  11. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/setup.py +4 -2
  12. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/LICENSE +0 -0
  13. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/MANIFEST.in +0 -0
  14. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/README.md +0 -0
  15. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/__init__.py +0 -0
  16. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/cache_manager.py +0 -0
  17. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/hooks/pre-commit +0 -0
  18. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/hooks_installer.py +0 -0
  19. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/.DS_Store +0 -0
  20. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/core.css +0 -0
  21. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/core.js +0 -0
  22. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/md5.min.js +0 -0
  23. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/timeago.full.min.js +0 -0
  24. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/timeago.min.js +0 -0
  25. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/core/utils.js +0 -0
  26. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/fonts/material-icons.css +0 -0
  27. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/fonts/materialicons.woff2 +0 -0
  28. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/templates/recently_updated_detail.html +0 -0
  29. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/templates/recently_updated_grid.html +0 -0
  30. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/templates/recently_updated_group.html +0 -0
  31. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/templates/recently_updated_list.html +0 -0
  32. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
  33. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/light.css +0 -0
  34. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/material.css +0 -0
  35. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
  36. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/scale.css +0 -0
  37. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
  38. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
  39. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
  40. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
  41. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
  42. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
  43. {mkdocs_document_dates-3.8.1 → mkdocs_document_dates-3.8.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.8.1
3
+ Version: 3.8.5
4
4
  Summary: A new generation MkDocs plugin for displaying exact creation date, last updated date, authors, email of documents
5
5
  Author-email: Aaron Wang <aaronwqt@gmail.com>
6
6
  License-Expression: MIT
@@ -14,6 +14,7 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: mkdocs<=1.6.1,>=1.6
16
16
  Requires-Dist: properdocs>=1.6.5
17
+ Requires-Dist: babel>=2.16
17
18
  Dynamic: license-file
18
19
 
19
20
  # mkdocs-document-dates
@@ -9,6 +9,7 @@ from mkdocs.config import config_options
9
9
  from mkdocs.structure.pages import Page
10
10
  from mkdocs.utils import get_relative_url
11
11
  from urllib.parse import urlparse
12
+ from babel.dates import format_datetime
12
13
  from .utils import compile_exclude_patterns, is_excluded, get_recently_updated_files, load_dates_and_authors
13
14
 
14
15
  logger = logging.getLogger("mkdocs.plugins.document_dates")
@@ -54,7 +55,7 @@ class DocumentDatesPlugin(BasePlugin):
54
55
 
55
56
  # 加载 author 配置
56
57
  authors_file = None
57
- for name in ("authors.yml", "authors.yaml"):
58
+ for name in ('authors.yml', 'authors.yaml'):
58
59
  candidate = docs_dir_path / name
59
60
  if candidate.exists():
60
61
  authors_file = candidate
@@ -67,19 +68,11 @@ class DocumentDatesPlugin(BasePlugin):
67
68
  authors_file = docs_dir_path / authors_file_resolved
68
69
  except Exception:
69
70
  pass
70
- self._load_authors_from_yaml(authors_file)
71
-
72
- # 复制配置文件到用户目录(如果不存在)
73
- dest_dir = docs_dir_path / 'assets' / 'document_dates'
74
- dest_dir.mkdir(parents=True, exist_ok=True)
75
- config_files = ['user.config.css', 'user.config.js']
76
- for config_file in config_files:
77
- source_config = Path(__file__).parent / 'static' / 'config' / config_file
78
- target_config = dest_dir / config_file
79
- if not target_config.exists():
80
- shutil.copy2(source_config, target_config)
81
-
82
- # 添加离线 Google Fonts Icons: https://fonts.google.com/icons
71
+
72
+ if authors_file:
73
+ self._load_authors_from_yaml(authors_file)
74
+
75
+ # 添加离线 Google Fonts Icons, https://fonts.google.com/icons
83
76
  # material_icons_url = 'https://fonts.googleapis.com/icon?family=Material+Icons'
84
77
  material_icons_url = 'assets/document_dates/fonts/material-icons.css'
85
78
  config['extra_css'].append(material_icons_url)
@@ -116,23 +109,36 @@ class DocumentDatesPlugin(BasePlugin):
116
109
  tippy_css_dir = Path(__file__).parent / 'static' / 'tippy'
117
110
  for css_file in tippy_css_dir.glob('*.css'):
118
111
  config['extra_css'].append(f'assets/document_dates/tippy/{css_file.name}')
119
-
120
- # 添加自定义 CSS 文件
121
- config['extra_css'].extend([
122
- 'assets/document_dates/core/core.css',
123
- 'assets/document_dates/user.config.css'
124
- ])
125
-
112
+
113
+ # User override config
114
+ override_dir = docs_dir_path / 'assets' / 'document_dates'
115
+ override_css = override_dir / 'config.css'
116
+ override_js = override_dir / 'config.js'
117
+
118
+ # Plugin CSS
119
+ config['extra_css'].append('assets/document_dates/core/core.css')
120
+
121
+ # 用户 override CSS(可选)
122
+ if override_css.exists():
123
+ config['extra_css'].append('assets/document_dates/config.css')
124
+
126
125
  # 按顺序添加 Tippy JS 文件
127
126
  js_core_files = ['popper.min.js', 'tippy.umd.min.js']
128
127
  for js_file in js_core_files:
129
128
  config['extra_javascript'].append(f'assets/document_dates/tippy/{js_file}')
130
-
131
- # 添加自定义 JS 文件
129
+
130
+ # Plugin JS
132
131
  config['extra_javascript'].extend([
133
132
  'assets/document_dates/core/md5.min.js',
134
133
  'assets/document_dates/core/default.config.js',
135
- 'assets/document_dates/user.config.js',
134
+ ])
135
+
136
+ # 用户 override JS(可选)
137
+ if override_js.exists():
138
+ config['extra_javascript'].append('assets/document_dates/config.js')
139
+
140
+ # core runtime
141
+ config['extra_javascript'].extend([
136
142
  'assets/document_dates/core/utils.js',
137
143
  'assets/document_dates/core/core.js'
138
144
  ])
@@ -250,8 +256,6 @@ class DocumentDatesPlugin(BasePlugin):
250
256
 
251
257
 
252
258
  def _load_authors_from_yaml(self, file_path: Path):
253
- if not file_path.exists():
254
- return
255
259
  try:
256
260
  with open(file_path, 'r', encoding='utf-8') as f:
257
261
  data = yaml.safe_load(f)
@@ -367,11 +371,38 @@ class DocumentDatesPlugin(BasePlugin):
367
371
 
368
372
 
369
373
  def _formatting_date(self, date: datetime):
370
- if self.config['type'] == 'timeago':
371
- return ""
372
- elif self.config['type'] == 'datetime':
373
- return date.strftime(f"{self.config['date_format']} {self.config['time_format']}")
374
- return date.strftime(self.config['date_format'])
374
+ locale = self.config.get('locale', 'en')
375
+
376
+ # 兼容旧 strftime 配置,转换为 Babel/ICU 格式
377
+ date_format = (
378
+ self.config['date_format']
379
+ .replace('%Y', 'yyyy')
380
+ .replace('%y', 'yy')
381
+ .replace('%m', 'MM')
382
+ .replace('%d', 'dd')
383
+ .replace('%B', 'MMMM')
384
+ .replace('%b', 'MMM')
385
+ )
386
+
387
+ time_format = (
388
+ self.config['time_format']
389
+ .replace('%H', 'HH')
390
+ .replace('%I', 'hh')
391
+ .replace('%M', 'mm')
392
+ .replace('%S', 'ss')
393
+ .replace('%p', 'a')
394
+ )
395
+
396
+ if self.config['type'] == 'datetime':
397
+ fmt = f"{date_format} {time_format}"
398
+ else:
399
+ fmt = date_format
400
+
401
+ return format_datetime(
402
+ date,
403
+ format=fmt,
404
+ locale=locale
405
+ )
375
406
 
376
407
  def _generate_html_info(self, meta, created: datetime, updated: datetime, authors=None):
377
408
  try:
@@ -391,11 +422,11 @@ class DocumentDatesPlugin(BasePlugin):
391
422
  html_parts.append(f"<div class='document-dates-plugin' locale='{self.config['locale']}'>")
392
423
 
393
424
  def build_time_icon(time_obj: datetime, icon: str):
394
- formatted = time_obj.strftime(self.config['date_format'])
425
+ formatted = self._formatting_date(time_obj)
395
426
  return (
396
427
  f"<span class='dd-item' data-tippy-content data-tippy-raw='{formatted}'>"
397
428
  f"<span class='material-icons' data-icon='{icon}'></span>"
398
- f"<time datetime='{time_obj.astimezone().isoformat()}'>{self._formatting_date(time_obj)}</time>"
429
+ f"<time datetime='{time_obj.astimezone().isoformat()}'>{formatted}</time>"
399
430
  f"</span>"
400
431
  )
401
432
 
@@ -69,7 +69,7 @@
69
69
  font-size: 12px;
70
70
  } */
71
71
 
72
- /* Demo of the custom theme 'sorrel' and 'sublime', you can configure it in user.config.js (optional) */
72
+ /* Demo of the custom theme 'sorrel' and 'sublime', you can configure it in config.js (optional) */
73
73
  /*
74
74
  .tippy-box[data-theme~='sorrel'] {
75
75
  background-color: #F7E6E2;
@@ -14,7 +14,7 @@ Part 1:
14
14
  /*
15
15
  TooltipConfig.setConfig({
16
16
  theme: {
17
- // configurable: light material, or custom theme in user.config.css, for example: sorrel sublime tomato
17
+ // configurable: light material, or custom theme in config.css, for example: sorrel sublime tomato
18
18
  light: 'light',
19
19
  dark: 'material'
20
20
  },
@@ -2,7 +2,7 @@
2
2
  Tooltip 配置
3
3
  */
4
4
  const ttDefaultConfig = {
5
- // 可配置: light material, 或在 user.config.css 中自定义的主题
5
+ // 可配置: light material, 或在 config.css 中自定义的主题
6
6
  theme: {
7
7
  light: 'light',
8
8
  dark: 'material'
@@ -103,6 +103,24 @@ def load_git_first_commit_date(file_path) -> datetime:
103
103
  logger.info(f"Error load git first commit date for {file_path}: {e}")
104
104
  return datetime.now(timezone.utc)
105
105
 
106
+ COAUTHOR_RE = re.compile(
107
+ r'^Co-authored-by:\s*(.+?) <([^<>]+)>$',
108
+ re.MULTILINE | re.IGNORECASE
109
+ )
110
+ def parse_commit_authors(name, email, body):
111
+ authors = [(name, email)]
112
+ seen = {(name, email)}
113
+
114
+ for co_name, co_email in COAUTHOR_RE.findall(body):
115
+ author = (co_name, co_email)
116
+ if author in seen:
117
+ continue
118
+
119
+ seen.add(author)
120
+ authors.append(author)
121
+
122
+ return authors
123
+
106
124
  def load_git_metadata(docs_dir_path: Path):
107
125
  dates_cache = {}
108
126
  try:
@@ -112,26 +130,46 @@ def load_git_metadata(docs_dir_path: Path):
112
130
  ).strip())
113
131
  rel_docs_path = docs_dir_path.relative_to(git_root).as_posix()
114
132
 
115
- cmd = ['git', '-c', 'core.quotepath=false', 'log', '--reverse', '--no-merges', '--use-mailmap', '--name-only', '--format=%aN|%aE|%at', f'--relative={rel_docs_path}', '--', '*.md']
133
+ cmd = [
134
+ 'git',
135
+ '-c', 'core.quotepath=false',
136
+ 'log',
137
+ '--reverse',
138
+ '--no-merges',
139
+ '--use-mailmap',
140
+ '--name-only',
141
+ '-z',
142
+ '--format=%aN%x1f%aE%x1f%at%x1f%B%x00',
143
+ f'--relative={rel_docs_path}',
144
+ '--',
145
+ '*.md'
146
+ ]
116
147
  process = subprocess.run(cmd, cwd=docs_dir_path, capture_output=True, encoding='utf-8')
117
148
  if process.returncode == 0:
118
149
  authors_dict = defaultdict(dict)
119
150
  first_commit = {}
120
151
  current_commit = None
121
- for line in process.stdout.splitlines():
122
- line = line.strip()
123
- if not line:
152
+
153
+ records = process.stdout.split('\x00')
154
+ for item in records:
155
+ item = item.strip()
156
+ if not item:
124
157
  continue
125
- if '|' in line:
126
- # 使用元组,更轻量
127
- current_commit = tuple(line.split('|', 2))
128
- elif line.endswith('.md') and current_commit:
129
- name, email, created = current_commit
158
+
159
+ parts = item.split('\x1f', 3)
160
+ if len(parts) == 4:
161
+ name, email, created, body = parts
162
+ authors = parse_commit_authors(name, email, body)
163
+ current_commit = (authors, int(created))
164
+ elif item.endswith('.md') and current_commit:
165
+ authors, created = current_commit
130
166
  # 使用 defaultdict(dict)结构,处理有序与去重
131
167
  # a.巧用 Python 字典的 setdefault 特性来去重(setdefault 为不存在的键提供初始值,不会覆盖已有值)
132
168
  # b.巧用 Python 字典的插入顺序特性来保留内容插入顺序(Python 3.7+ 字典会保持插入顺序)
133
- authors_dict[line].setdefault((name, email), None)
134
- first_commit.setdefault(line, int(created))
169
+ for author in authors:
170
+ authors_dict[item].setdefault(author, None)
171
+
172
+ first_commit.setdefault(item, created)
135
173
 
136
174
  # 构建最终的缓存数据
137
175
  for file_path in first_commit:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mkdocs-document-dates
3
- Version: 3.8.1
3
+ Version: 3.8.5
4
4
  Summary: A new generation MkDocs plugin for displaying exact creation date, last updated date, authors, email of documents
5
5
  Author-email: Aaron Wang <aaronwqt@gmail.com>
6
6
  License-Expression: MIT
@@ -14,6 +14,7 @@ Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Requires-Dist: mkdocs<=1.6.1,>=1.6
16
16
  Requires-Dist: properdocs>=1.6.5
17
+ Requires-Dist: babel>=2.16
17
18
  Dynamic: license-file
18
19
 
19
20
  # mkdocs-document-dates
@@ -16,8 +16,8 @@ mkdocs_document_dates.egg-info/requires.txt
16
16
  mkdocs_document_dates.egg-info/top_level.txt
17
17
  mkdocs_document_dates/hooks/pre-commit
18
18
  mkdocs_document_dates/static/.DS_Store
19
- mkdocs_document_dates/static/config/user.config.css
20
- mkdocs_document_dates/static/config/user.config.js
19
+ mkdocs_document_dates/static/config/config.css
20
+ mkdocs_document_dates/static/config/config.js
21
21
  mkdocs_document_dates/static/core/core.css
22
22
  mkdocs_document_dates/static/core/core.js
23
23
  mkdocs_document_dates/static/core/default.config.js
@@ -1,2 +1,3 @@
1
1
  mkdocs<=1.6.1,>=1.6
2
2
  properdocs>=1.6.5
3
+ babel>=2.16
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mkdocs-document-dates"
7
- version = "3.8.1"
7
+ version = "3.8.5"
8
8
  description = "A new generation MkDocs plugin for displaying exact creation date, last updated date, authors, email of documents"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.7"
@@ -12,7 +12,8 @@ license = "MIT"
12
12
  authors = [{ name = "Aaron Wang", email = "aaronwqt@gmail.com" }]
13
13
  dependencies = [
14
14
  "mkdocs>=1.6,<=1.6.1",
15
- "properdocs>=1.6.5"
15
+ "properdocs>=1.6.5",
16
+ "babel>=2.16"
16
17
  ]
17
18
  classifiers = [
18
19
  "Programming Language :: Python :: 3",
@@ -4,7 +4,7 @@ from setuptools import find_packages, setup
4
4
  def legacy_setup():
5
5
  setup(
6
6
  name="mkdocs-document-dates",
7
- version="3.8.1",
7
+ version="3.8.5",
8
8
  author="Aaron Wang",
9
9
  author_email="aaronwqt@gmail.com",
10
10
  license="MIT",
@@ -15,7 +15,9 @@ def legacy_setup():
15
15
  packages=find_packages(),
16
16
  include_package_data=True,
17
17
  install_requires=[
18
- "mkdocs>=1.1.0",
18
+ "mkdocs>=1.6,<=1.6.1",
19
+ "properdocs>=1.6.5",
20
+ "babel>=2.16"
19
21
  ],
20
22
  classifiers=[
21
23
  "Programming Language :: Python :: 3",