diff --git a/poxy/data/poxy-badge-c++23.svg b/poxy/data/poxy-badge-c++23.svg
new file mode 100644
index 0000000..65c8b16
--- /dev/null
+++ b/poxy/data/poxy-badge-c++23.svg
@@ -0,0 +1 @@
+
diff --git a/poxy/data/poxy-badge-c++26.svg b/poxy/data/poxy-badge-c++26.svg
new file mode 100644
index 0000000..23d9297
--- /dev/null
+++ b/poxy/data/poxy-badge-c++26.svg
@@ -0,0 +1 @@
+
diff --git a/poxy/data/poxy-badge-c++29.svg b/poxy/data/poxy-badge-c++29.svg
new file mode 100644
index 0000000..6596af4
--- /dev/null
+++ b/poxy/data/poxy-badge-c++29.svg
@@ -0,0 +1 @@
+
diff --git a/poxy/data/poxy.css b/poxy/data/poxy.css
index 7c6b875..aa1b992 100644
--- a/poxy/data/poxy.css
+++ b/poxy/data/poxy.css
@@ -460,3 +460,12 @@ ul.m-doc > li.m-doc-collapsible li
{
color: #CCCCCC !important;
}
+
+/* implementation detail blocks */
+.poxy-impl
+{
+ padding: 0rem !important;
+ margin: 0rem 0.2rem !important;
+ font-weight: normal;
+ color: rgb(87,166,74) !important;
+}
diff --git a/poxy/data/version.txt b/poxy/data/version.txt
index 1c09c74..42045ac 100644
--- a/poxy/data/version.txt
+++ b/poxy/data/version.txt
@@ -1 +1 @@
-0.3.3
+0.3.4
diff --git a/poxy/fixers.py b/poxy/fixers.py
index d5ede90..4e02527 100644
--- a/poxy/fixers.py
+++ b/poxy/fixers.py
@@ -16,11 +16,22 @@
+#=======================================================================================================================
+# base classes
+#=======================================================================================================================
+
+class HTMLFixer(object):
+ pass
+
+class PlainTextFixer(object):
+ pass
+
+
#=======================================================================================================================
# custom tags
#=======================================================================================================================
-class CustomTags(object):
+class CustomTags(HTMLFixer):
'''
Modifies HTML using custom square-bracket [tags].
'''
@@ -149,7 +160,7 @@ def __call__(self, doc, context):
# C++
#=======================================================================================================================
-class _ModifiersBase(object):
+class _ModifiersBase(HTMLFixer):
'''
Base type for modifier parsing fixers.
'''
@@ -241,7 +252,7 @@ def __call__(self, doc, context):
-class TemplateTemplate(object):
+class TemplateTemplate(HTMLFixer):
'''
Spreads consecutive template <> declarations out over multiple lines.
'''
@@ -262,7 +273,7 @@ def __call__(self, doc, context):
-class StripIncludes(object):
+class StripIncludes(HTMLFixer):
'''
Strips #include based on context.sources.strip_includes.
'''
@@ -291,11 +302,31 @@ def __call__(self, doc, context):
return changed
+
+class ImplementationDetails(PlainTextFixer):
+ '''
+ Replaces implementation details with appropriate shorthands.
+ '''
+ __shorthands = (
+ (r'POXY_IMPLEMENTATION_DETAIL', r'/* ... */
'),
+ )
+ def __call__(self, doc, context):
+ changed = False
+ for shorthand, replacement in self.__shorthands:
+ idx = doc[0].find(shorthand)
+ while idx >= 0:
+ doc[0] = doc[0][:idx] + replacement + doc[0][idx + len(shorthand):]
+ changed = True
+ idx = doc[0].find(shorthand)
+ return changed
+
+
+
#=======================================================================================================================
# index.html
#=======================================================================================================================
-class IndexPage(object):
+class IndexPage(HTMLFixer):
'''
Applies some basic fixes to index.html
'''
@@ -325,7 +356,7 @@ def __call__(self, doc, context):
# blocks
#=======================================================================================================================
-class CodeBlocks(object):
+class CodeBlocks(HTMLFixer):
'''
Fixes various issues and improves syntax highlighting in blocks.
'''
@@ -534,6 +565,25 @@ def __call__(self, doc, context):
span['class'] = 'k'
changed_this_block = True
+ # 'using' statements
+ spans = code_block('span', class_=('k'), string=r'using')
+ for using in spans:
+ assign = using.find_next_sibling('span', class_='o', string='=')
+ if assign is None:
+ continue
+ next = using.next_sibling
+ while next != assign:
+ current = next
+ next = current.next_sibling
+ if isinstance(current, soup.NavigableString):
+ if len(current.string.strip()) > 0:
+ break
+ continue
+ if current.name != r'span' or r'class' not in current.attrs or r'n' not in current['class']:
+ continue
+ soup.set_class(current, r'ut')
+ changed_this_block = True
+
if changed_this_block:
code_block.smooth()
changed_this_pass = True
@@ -580,7 +630,7 @@ def _m_doc_anchor_tags(tag):
-class AutoDocLinks(object):
+class AutoDocLinks(HTMLFixer):
'''
Adds links to additional sources where appropriate.
'''
@@ -645,7 +695,7 @@ def __call__(self, doc, context):
-class Links(object):
+class Links(HTMLFixer):
'''
Fixes various minor issues with anchor tags.
'''
@@ -723,7 +773,7 @@ def __call__(self, doc, context):
# empty tags
#=======================================================================================================================
-class EmptyTags(object):
+class EmptyTags(HTMLFixer):
'''
Prunes the tree of various empty tags (happens as a side-effect of some other operations).
'''
@@ -741,7 +791,7 @@ def __call__(self, doc, context):
# tags
#=======================================================================================================================
-class HeadTags(object):
+class HeadTags(HTMLFixer):
'''
Injects poxy-specific tags into the document's block.
'''
diff --git a/poxy/run.py b/poxy/run.py
index 3545162..bf564e1 100644
--- a/poxy/run.py
+++ b/poxy/run.py
@@ -754,16 +754,31 @@ def _postprocess_html_file(path, context=None):
assert context is not None
assert isinstance(context, project.Context)
+ html_fixers = [f for f in context.fixers if isinstance(f, fixers.HTMLFixer)]
+ plain_text_fixers = [f for f in context.fixers if isinstance(f, fixers.PlainTextFixer)]
+
context.verbose(rf'Post-processing {path}')
- changed = False
- doc = soup.HTMLDocument(path, logger=context.verbose_logger)
- for fix in context.fixers:
- if fix(doc, context):
- doc.smooth()
- changed = True
- if changed:
- doc.flush()
- return changed
+ html_changed = False
+ if html_fixers:
+ doc = soup.HTMLDocument(path, logger=context.verbose_logger)
+ for fix in html_fixers:
+ if fix(doc, context):
+ doc.smooth()
+ html_changed = True
+ if html_changed:
+ doc.flush()
+
+ plain_text_changed = False
+ if plain_text_fixers:
+ doc = [ read_all_text_from_file(path, logger=context.verbose_logger) ]
+ for fix in plain_text_fixers:
+ if fix(doc, context):
+ plain_text_changed = True
+ if plain_text_changed:
+ with open(path, 'w', encoding='utf-8', newline='\n') as f:
+ f.write(doc[0])
+
+ return html_changed or plain_text_changed
@@ -790,6 +805,7 @@ def _postprocess_html(context):
, fixers.CustomTags()
, fixers.EmptyTags()
, fixers.HeadTags()
+ , fixers.ImplementationDetails()
)
context.verbose(rf'Post-processing {len(files)} HTML files...')
if threads > 1: