diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py
index 58d487160..43f6717b5 100644
--- a/ietf/doc/templatetags/ietf_filters.py
+++ b/ietf/doc/templatetags/ietf_filters.py
@@ -192,15 +192,12 @@ def urlize_ietf_docs(string, autoescape=None):
"""
if autoescape and not isinstance(string, SafeData):
string = escape(string)
- string = re.sub(r"(RFC\s*?)0{0,3}(\d+)", "\\1\\2", string, flags=re.IGNORECASE)
- string = re.sub(r"(BCP\s*?)0{0,3}(\d+)", "\\1\\2", string, flags=re.IGNORECASE)
- string = re.sub(r"(STD\s*?)0{0,3}(\d+)", "\\1\\2", string, flags=re.IGNORECASE)
- string = re.sub(r"(FYI\s*?)0{0,3}(\d+)", "\\1\\2", string, flags=re.IGNORECASE)
- string = re.sub(r"(draft-[-0-9a-zA-Z._+]+)", "\\1", string, flags=re.IGNORECASE)
- string = re.sub(r"(bofreq-[-0-9a-zA-Z._+]+)", "\\1", string, flags=re.IGNORECASE)
- string = re.sub(r"(conflict-review-[-0-9a-zA-Z._+]+)", "\\1", string, flags=re.IGNORECASE)
- string = re.sub(r"(status-change-[-0-9a-zA-Z._+]+)", "\\1", string, flags=re.IGNORECASE)
- string = re.sub(r"(charter-[-0-9a-zA-Z._+]+)", "\\1", string, flags=re.IGNORECASE)
+ string = re.sub(
+ r"\b((RFC|BCP|STD|FYI|(?:draft-|bofreq-|conflict-review-|status-change-|charter-)[-\d\w.+]+)\s*0*(\d+))\b",
+ lambda x: f'{x[1]}',
+ string,
+ flags=re.IGNORECASE | re.ASCII,
+ )
return mark_safe(string)
urlize_ietf_docs = stringfilter(urlize_ietf_docs)
@@ -739,4 +736,4 @@ def absurl(viewname, **kwargs):
Uses settings.IDTRACKER_BASE_URL as the base.
"""
- return urljoin(settings.IDTRACKER_BASE_URL, urlreverse(viewname, kwargs=kwargs))
\ No newline at end of file
+ return urljoin(settings.IDTRACKER_BASE_URL, urlreverse(viewname, kwargs=kwargs))
diff --git a/ietf/doc/templatetags/tests_ietf_filters.py b/ietf/doc/templatetags/tests_ietf_filters.py
new file mode 100644
index 000000000..3db85f5f7
--- /dev/null
+++ b/ietf/doc/templatetags/tests_ietf_filters.py
@@ -0,0 +1,27 @@
+from ietf.doc.templatetags.ietf_filters import urlize_ietf_docs
+from ietf.utils.test_utils import TestCase
+
+# TODO: most other filters need test cases, too
+
+
+class IetfFiltersTests(TestCase):
+ def test_urlize_ietf_docs(self):
+ cases = [
+ ("no change", "no change"),
+ ("bcp1", 'bcp1'),
+ ("Std 003", 'Std 003'),
+ (
+ "FYI02 changes Std 003",
+ 'FYI02 changes Std 003',
+ ),
+ ("rfc2119", 'rfc2119'),
+ ("Rfc 02119", 'Rfc 02119'),
+ ("draft-abc-123", 'draft-abc-123'),
+ (
+ "draft-ietf-rfc9999-bis-01",
+ 'draft-ietf-rfc9999-bis-01',
+ ),
+ ]
+
+ for input, output in cases:
+ self.assertEqual(urlize_ietf_docs(input), output)