Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / histogram / doc / doxygen_postprocessing.py
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)
5
6 from __future__ import print_function
7 import sys
8 import xml.etree.ElementTree as ET
9 import re
10
11
12 def log(*args):
13     print("post-processing:", *args)
14
15
16 def select(condition, *tags):
17     result = []
18     for tag in tags:
19         for item in root.iter(tag):
20             if condition(item):
21                 result.append(item)
22     return result
23
24
25 def is_detail(x):
26     if x.text is not None:
27         if "detail" in x.text:
28             return True
29         m = re.match("(?:typename)? *([A-Za-z0-9_\:]+)", x.text)
30         if m is not None:
31             s = m.group(1)
32             if s.startswith("detail") or s.endswith("_impl"):
33                 x.text = s
34                 return True
35
36     p = x.find("purpose")
37     if p is not None:
38         return p.text.lower().lstrip().startswith("implementation detail")
39     return False
40
41
42 def is_deprecated(x):
43     p = x.find("purpose")
44     if p is not None:
45         return p.text.lower().lstrip().startswith("deprecated")
46     return False
47
48
49 tree = ET.parse(sys.argv[1])
50 root = tree.getroot()
51
52 parent_map = {c:p for p in tree.iter() for c in p}
53
54 unspecified = ET.Element("emphasis")
55 unspecified.text = "unspecified"
56
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"
61     parent.remove(item)
62     parent = parent_map[parent]
63     name = parent.get("name")
64     if name is None:
65         log("removing unnamed template parameter from", parent.tag)
66     else:
67         log("removing unnamed template parameter from", parent.tag, name)
68
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"')
72     item.clear()
73     item.append(unspecified)
74
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"))
79     parent.remove(item)
80
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"))
85     parent.remove(item)
86
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")
91     if purpose is None:
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")
100         item.clear()
101         item.tag = "typedef"
102         item.set("name", name)
103         type = ET.Element("type")
104         type.append(unspecified)
105         item.append(type)
106
107 parent_map = {c:p for p in tree.iter() for c in p}
108
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)
115
116 tree.write(sys.argv[2])