Skip to content

Commit eeb8b9d

Browse files
authored
Merge pull request #284 from ma10/refactor-yaml2x-20250221
yaml2x以下のリファクタリング
2 parents bc20242 + 35752aa commit eeb8b9d

22 files changed

+910
-262
lines changed

requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ sphinx >= 3.0
33
sphinx_rtd_theme
44
sphinxcontrib-trimblank
55
pyyaml
6+
toml
67
jsonschema < 4.18.0
78
GitPython
89
sphinx-lint
910
google-auth-oauthlib
1011
google-api-python-client
1112
pytz
13+
pydantic
1214
tools/yaml2x/libs/freee_a11y_gl
1315
tools/yaml2x/libs/get_yaml_data

tools/yaml2x/libs/freee_a11y_gl/freee_a11y_gl/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
from .constants import *
33
from .source import get_src_path
44
from .initializer import setup_instances
5+
from .info_utils import get_info_links
6+
from .version_utils import get_version_info

tools/yaml2x/libs/freee_a11y_gl/freee_a11y_gl/classes.py

+15-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import re
33
from urllib.parse import quote as url_encode
44
from .constants import PLATFORM_NAMES, SEVERITY_TAGS, CHECK_TARGETS, IMPLEMENTATION_TARGETS
5+
from .config import Config
56

67
class RelationshipManager:
78
_instance = None
@@ -194,25 +195,20 @@ def get_category_and_id(self, lang):
194195
'guideline': self.id
195196
}
196197

197-
def link_data(self, baseurl = ''):
198-
separator_char = {
199-
'ja': ':',
200-
'en': ': '
201-
}
202-
basedir = {
203-
'ja': '/categories/',
204-
'en': '/en/categories/'
205-
}
198+
def link_data(self):
199+
langs = self.title.keys()
206200
data = {
207201
'text': {},
208202
'url': {}
209203
}
210-
langs = self.title.keys()
211204
for lang in langs:
205+
separator_char = Config.get_separator(lang, "text")
206+
basedir = Config.get_guidelines_path()
207+
baseurl = Config.get_base_url(lang)
212208
category = self.category.get_name(lang)
213209
basename = self.category.id
214-
data['text'][lang] = f'{category}{separator_char[lang]}{self.title[lang]}'
215-
data['url'][lang] = f'{baseurl}{basedir[lang]}{basename}.html#{self.id}'
210+
data['text'][lang] = f'{category}{separator_char}{self.title[lang]}'
211+
data['url'][lang] = f'{baseurl}{basedir}{basename}.html#{self.id}'
216212
return data
217213

218214
def template_data(self, lang):
@@ -311,10 +307,10 @@ def object_data(self, baseurl = ''):
311307
'platform': self.platform,
312308
'guidelines': []
313309
}
314-
data['guidelines'] = [gl.link_data(baseurl) for gl in rel.get_check_to_guidelines(self)]
310+
data['guidelines'] = [gl.link_data() for gl in rel.get_check_to_guidelines(self)]
315311
faqs = rel.get_check_to_faqs(self)
316312
if len(faqs) > 0:
317-
data['faqs'] = [faq.link_data(baseurl) for faq in faqs]
313+
data['faqs'] = [faq.link_data() for faq in faqs]
318314
info = rel.get_check_to_info(self)
319315
if len(info) > 0:
320316
data['info'] = [inforef.link_data() for inforef in info]
@@ -426,20 +422,18 @@ def get_dependency(self):
426422
dependency.extend([check.src_path for check in checks])
427423
return uniq(dependency)
428424

429-
def link_data(self, baseurl = ''):
430-
basedir = {
431-
'ja': '/faq/articles/',
432-
'en': '/en/faq/articles/'
433-
}
425+
def link_data(self):
426+
langs = self.title.keys()
427+
basedir = Config.get_faq_path()
434428
data = {
435429
'text': {},
436430
'url': {}
437431
}
438-
langs = self.title.keys()
439432
for lang in langs:
433+
baseurl = Config.get_base_url(lang)
440434
basename = self.id
441435
data['text'][lang] = self.title[lang]
442-
data['url'][lang] = f'{baseurl}{basedir[lang]}{basename}.html'
436+
data['url'][lang] = f'{baseurl}{basedir}{basename}.html'
443437
return data
444438

445439
def template_data(self, lang):
@@ -501,12 +495,6 @@ def __init__(self, category_id, names):
501495
self.guidelines = []
502496
Category.all_categories[category_id] = self
503497

504-
# def add_guideline(self, guideline):
505-
# if guideline in self.guidelines:
506-
# return
507-
# self.guidelines.append(guideline)
508-
# guideline.set_category(self)
509-
510498
def get_name(self, lang):
511499
if lang in self.names:
512500
return self.names[lang]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Development configuration
2+
# Usage: Copy this file to config.yaml in your project directory
3+
4+
# URLs for development environment
5+
urls:
6+
base:
7+
ja: "http://localhost:8000"
8+
en: "http://localhost:8000/en"
9+
docs:
10+
ja: "/categories/"
11+
en: "/en/categories/"
12+
13+
# Other settings inherit from defaults
14+
languages:
15+
available:
16+
- ja
17+
- en
18+
default: ja
19+
required:
20+
- ja
21+
- en
22+
23+
# Standard separators (same as defaults)
24+
separators:
25+
text:
26+
ja: ""
27+
en: ": "
28+
list:
29+
ja: ""
30+
en: ", "
31+
and:
32+
ja: ""
33+
en: " and "
34+
or:
35+
ja: "または"
36+
en: " or "
37+
and_conjunction:
38+
ja: "、かつ"
39+
en: ", and "
40+
or_conjunction:
41+
ja: "、または"
42+
en: ", or "
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Production configuration
2+
# Usage: Copy this file to config.yaml in your production environment
3+
4+
# URLs for production environment
5+
urls:
6+
base:
7+
ja: "https://a11y-guidelines.freee.co.jp"
8+
en: "https://a11y-guidelines.freee.co.jp/en"
9+
docs:
10+
ja: "/categories/"
11+
en: "/en/categories/"
12+
13+
# Other settings inherit from defaults
14+
languages:
15+
available:
16+
- ja
17+
- en
18+
default: ja
19+
required:
20+
- ja
21+
- en
22+
23+
# Standard separators (same as defaults)
24+
separators:
25+
text:
26+
ja: ""
27+
en: ": "
28+
list:
29+
ja: ""
30+
en: ", "
31+
and:
32+
ja: ""
33+
en: " and "
34+
or:
35+
ja: "または"
36+
en: " or "
37+
and_conjunction:
38+
ja: "、かつ"
39+
en: ", and "
40+
or_conjunction:
41+
ja: "、または"
42+
en: ", or "
43+
44+
# Note: In production, you might want to:
45+
# 1. Use environment variables for sensitive settings
46+
# 2. Restrict file permissions (e.g., chmod 600 config.yaml)
47+
# 3. Use a secure location for the config file
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
"""Configuration interface for freee_a11y_gl module."""
2+
import re
3+
from typing import Dict, Literal, Optional
4+
from .settings import settings
5+
6+
LanguageCode = Literal["ja", "en"]
7+
8+
class Config:
9+
"""Configuration interface."""
10+
11+
@classmethod
12+
def register_settings(cls, new_settings: Optional[Dict[str, any]] = None) -> None:
13+
"""Register new settings."""
14+
settings.update(new_settings)
15+
16+
@classmethod
17+
def get_basedir(cls) -> str:
18+
"""Get base directory path.
19+
20+
Returns:
21+
Base directory path from settings, or '.' if not set
22+
"""
23+
return settings.get("basedir", ".")
24+
25+
@classmethod
26+
def get_base_url(cls, lang: Optional[LanguageCode] = None) -> str:
27+
"""Get base URL for specified language."""
28+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
29+
return settings.get(f"base_url.{effective_lang}", "")
30+
31+
@classmethod
32+
def get_guidelines_path(cls) -> str:
33+
"""Get guidelines (categories) path."""
34+
return settings.get("paths.guidelines", "/")
35+
36+
@classmethod
37+
def get_separator(cls, lang: Optional[LanguageCode] = None, separator_type: Optional[str] = None) -> str:
38+
"""Get separator of specified type for language."""
39+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
40+
effective_type = separator_type if separator_type is not None else "text"
41+
return settings.get(f"separators.{effective_type}.{effective_lang}", "")
42+
43+
@classmethod
44+
def get_text_separator(cls, lang: Optional[LanguageCode] = None) -> str:
45+
"""Get text separator for specified language."""
46+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
47+
return settings.get(f"separators.text.{effective_lang}", "")
48+
49+
@classmethod
50+
def get_list_separator(cls, lang: Optional[LanguageCode] = None) -> str:
51+
"""Get list item separator for specified language."""
52+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
53+
return settings.get(f"separators.list.{effective_lang}", ", ")
54+
55+
@classmethod
56+
def get_pass_text(cls, lang: Optional[LanguageCode] = None) -> str:
57+
"""Get localized pass text for conditions.
58+
59+
Args:
60+
lang: Language code. If None, default language from settings will be used.
61+
62+
Returns:
63+
Localized pass text
64+
"""
65+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
66+
return settings.get(f"separators.pass_text.{effective_lang}", " is true")
67+
68+
def get_conjunction(cls, lang: Optional[LanguageCode] = None, conjunction_type: Optional[str] = None) -> str:
69+
"""Get conjunction of specified type for language."""
70+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
71+
effective_type = conjunction_type if conjunction_type is not None else "and"
72+
return settings.get(f"separators.{effective_type}_conjunction.{effective_lang}", " and ")
73+
74+
@classmethod
75+
def get_check_tool_name(cls, tool_id: str, lang: Optional[LanguageCode] = None) -> str:
76+
"""Get localized check tool name."""
77+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
78+
try:
79+
return settings.config.check_tools.names[tool_id][effective_lang]
80+
except (KeyError, AttributeError):
81+
return tool_id
82+
83+
@classmethod
84+
def get_check_target_name(cls, target: str, lang: Optional[LanguageCode] = None) -> str:
85+
"""Get localized check target name."""
86+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
87+
try:
88+
return settings.config.check_targets.names[target][effective_lang]
89+
except (KeyError, AttributeError):
90+
return target
91+
92+
@classmethod
93+
def get_severity_tag(cls, severity: str, lang: Optional[LanguageCode] = None) -> str:
94+
"""Get localized severity tag."""
95+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
96+
try:
97+
return settings.config.severity_tags.tags[severity][effective_lang]
98+
except (KeyError, AttributeError):
99+
return severity
100+
101+
@classmethod
102+
def get_implementation_target_name(cls, target: str, lang: Optional[LanguageCode] = None) -> str:
103+
"""Get localized implementation target name."""
104+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
105+
try:
106+
return settings.config.implementation_targets.targets[target][effective_lang]
107+
except (KeyError, AttributeError):
108+
return target
109+
110+
@classmethod
111+
def get_platform_name(cls, platform: str, lang: Optional[LanguageCode] = None) -> str:
112+
"""Get localized platform name."""
113+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
114+
try:
115+
return settings.config.platform.names[platform][effective_lang]
116+
except (KeyError, AttributeError):
117+
return platform
118+
119+
@classmethod
120+
def get_platform_separator(cls, lang: Optional[LanguageCode] = None) -> str:
121+
"""Get platform list separator for specified language."""
122+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
123+
try:
124+
return settings.config.platform.separator[effective_lang]
125+
except (KeyError, AttributeError):
126+
return ", "
127+
128+
@classmethod
129+
def get_faq_path(cls) -> str:
130+
"""Get FAQ path
131+
Returns:
132+
Path string for FAQ articles
133+
"""
134+
return settings.get("paths.faq", "/faq/articles/")
135+
136+
@classmethod
137+
def get_examples_url(cls, lang: Optional[LanguageCode] = None) -> str:
138+
"""Get examples base URL for specified language."""
139+
"""Get examples base URL for specified language.
140+
141+
Args:
142+
lang: Language code. If None, default language from settings will be used.
143+
144+
Returns:
145+
URL string for examples in the specified language
146+
"""
147+
base_url = cls.get_base_url(lang)
148+
return f"{base_url}/checks/examples/"
149+
150+
@staticmethod
151+
@classmethod
152+
def get_date_format(cls, lang: Optional[LanguageCode] = None) -> str:
153+
"""Get localized date format string.
154+
155+
Args:
156+
lang: Language code. If None, default language from settings will be used.
157+
158+
Returns:
159+
Date format string in strftime format
160+
"""
161+
effective_lang = lang if lang is not None else settings.get("languages.default", "ja")
162+
default_format = "%Y年%-m月%-d日" if effective_lang == "ja" else "%B %-d, %Y"
163+
return settings.get(f"formats.date.{effective_lang}", default_format)
164+
165+
@staticmethod
166+
def tag2sc(tag: str) -> str:
167+
"""Convert axe-core tag to WCAG SC identifier.
168+
169+
Args:
170+
tag: axe-core tag (e.g., 'wcag111')
171+
172+
Returns:
173+
WCAG SC identifier (e.g., '1.1.1')
174+
"""
175+
return re.sub(r'wcag(\d)(\d)(\d+)', r'\1.\2.\3', tag)

0 commit comments

Comments
 (0)