1 # Copyright Hans Dembinski 2018 - 2019.
2 # Distributed under the Boost Software License, Version 1.0.
3 # (See accompanying file LICENSE_1_0.txt or copy at
4 # https://www.boost.org/LICENSE_1_0.txt)
6 from __future__ import print_function
8 import xml.etree.ElementTree as ET
13 print("post-processing:", *args)
16 def select(condition, *tags):
19 for item in root.iter(tag):
26 if x.text is not None:
27 if "detail" in x.text:
29 m = re.match("(?:typename)? *([A-Za-z0-9_\:]+)", x.text)
32 if s.startswith("detail") or s.endswith("_impl"):
38 return p.text.lower().lstrip().startswith("implementation detail")
45 return p.text.lower().lstrip().startswith("deprecated")
49 tree = ET.parse(sys.argv[1])
52 parent_map = {c:p for p in tree.iter() for c in p}
54 unspecified = ET.Element("emphasis")
55 unspecified.text = "unspecified"
57 # hide all unnamed template parameters, these are used for SFINAE
58 for item in select(lambda x: x.get("name") == "", "template-type-parameter"):
59 parent = parent_map[item]
60 assert parent.tag == "template"
62 parent = parent_map[parent]
63 name = parent.get("name")
65 log("removing unnamed template parameter from", parent.tag)
67 log("removing unnamed template parameter from", parent.tag, name)
69 # replace any type with "detail" in its name with "unspecified"
70 for item in select(is_detail, "type"):
71 log("replacing", '"%s"' % item.text, 'with "unspecified"')
73 item.append(unspecified)
75 # hide everything that's deprecated
76 for item in select(is_deprecated, "typedef"):
77 parent = parent_map[item]
78 log("removing deprecated", item.tag, item.get("name"), "from", parent.tag, parent.get("name"))
81 # hide private member functions
82 for item in select(lambda x: x.get("name") == "private member functions", "method-group"):
83 parent = parent_map[item]
84 log("removing private member functions from", parent.tag, parent.get("name"))
87 # hide undocumented classes, structs, functions and replace those declared
88 # "implementation detail" with typedef to implementation_defined
89 for item in select(lambda x:True, "class", "struct", "function"):
90 purpose = item.find("purpose")
92 parent = parent_map[item]
93 log("removing undocumented", item.tag, item.get("name"), "from",
94 parent.tag, parent.get("name"))
95 if item in parent_map[item]:
96 parent_map[item].remove(item)
97 elif purpose.text.strip().lower() == "implementation detail":
98 log("replacing", item.tag, item.get("name"), "with unspecified typedef")
99 name = item.get("name")
102 item.set("name", name)
103 type = ET.Element("type")
104 type.append(unspecified)
107 parent_map = {c:p for p in tree.iter() for c in p}
109 # hide methods and constructors explicitly declared as "implementation detail"
110 for item in select(is_detail, "constructor", "method"):
111 name = item.get("name")
112 log("removing", (item.tag + " " + name) if name is not None else item.tag,
113 "declared as implementation detail")
114 parent_map[item].remove(item)
116 tree.write(sys.argv[2])