pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. commands/cat/debug_log +2806 -0
  2. commands/cat/debug_log.2025-07-15_14-28-38_087378.zip +0 -0
  3. commands/cat/debug_log.2025-07-16_15-48-50_037087.zip +0 -0
  4. commands/cat/dr_egeria_command_help.py +273 -0
  5. commands/cat/dr_egeria_md.py +90 -20
  6. commands/cat/glossary_actions.py +2 -2
  7. commands/cat/list_collections.py +24 -10
  8. commands/cat/list_data_designer.py +183 -0
  9. md_processing/__init__.py +28 -5
  10. md_processing/data/commands.json +31474 -1096
  11. md_processing/dr_egeria_outbox-pycharm/.obsidian/app.json +1 -0
  12. md_processing/dr_egeria_outbox-pycharm/.obsidian/appearance.json +1 -0
  13. md_processing/dr_egeria_outbox-pycharm/.obsidian/core-plugins.json +31 -0
  14. md_processing/dr_egeria_outbox-pycharm/.obsidian/workspace.json +177 -0
  15. md_processing/dr_egeria_outbox-pycharm/monday/processed-2025-07-14 12:38-data_designer_out.md +663 -0
  16. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 15:00-Derive-Dr-Gov-Defs.md +719 -0
  17. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:13-Derive-Dr-Gov-Defs.md +41 -0
  18. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:14-Derive-Dr-Gov-Defs.md +33 -0
  19. md_processing/dr_egeria_outbox-pycharm/thursday/processed-2025-07-17 20:50-Derive-Dr-Gov-Defs.md +192 -0
  20. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-16 19:15-gov_def2.md +527 -0
  21. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 12:08-gov_def2.md +527 -0
  22. md_processing/dr_egeria_outbox-pycharm/tuesday/processed-2025-07-17 14:27-gov_def2.md +474 -0
  23. md_processing/family_docs/Data Designer/Create_Data_Class.md +164 -0
  24. md_processing/family_docs/Data Designer/Create_Data_Dictionary.md +30 -0
  25. md_processing/family_docs/Data Designer/Create_Data_Field.md +162 -0
  26. md_processing/family_docs/Data Designer/Create_Data_Specification.md +36 -0
  27. md_processing/family_docs/Data Designer/Create_Data_Structure.md +38 -0
  28. md_processing/family_docs/Data Designer/View_Data_Classes.md +78 -0
  29. md_processing/family_docs/Data Designer/View_Data_Dictionaries.md +78 -0
  30. md_processing/family_docs/Data Designer/View_Data_Fields.md +78 -0
  31. md_processing/family_docs/Data Designer/View_Data_Specifications.md +78 -0
  32. md_processing/family_docs/Data Designer/View_Data_Structures.md +78 -0
  33. md_processing/family_docs/Data Designer.md +842 -0
  34. md_processing/family_docs/Digital Product Manager/Add_Member->Collection.md +42 -0
  35. md_processing/family_docs/Digital Product Manager/Attach_Collection->Resource.md +36 -0
  36. md_processing/family_docs/Digital Product Manager/Create_Agreement.md +96 -0
  37. md_processing/family_docs/Digital Product Manager/Create_Data_Sharing_Agreement.md +72 -0
  38. md_processing/family_docs/Digital Product Manager/Create_DigitalSubscription.md +102 -0
  39. md_processing/family_docs/Digital Product Manager/Create_Digital_Product.md +134 -0
  40. md_processing/family_docs/Digital Product Manager/Link_Agreement_Items.md +60 -0
  41. md_processing/family_docs/Digital Product Manager/Link_Contracts.md +26 -0
  42. md_processing/family_docs/Digital Product Manager/Link_Digital_Product_-_Digital_Product.md +30 -0
  43. md_processing/family_docs/Digital Product Manager/Link_Subscribers.md +48 -0
  44. md_processing/family_docs/Digital Product Manager.md +668 -0
  45. md_processing/family_docs/Glossary/Attach_Category_Parent.md +18 -0
  46. md_processing/family_docs/Glossary/Attach_Term-Term_Relationship.md +26 -0
  47. md_processing/family_docs/Glossary/Create_Category.md +38 -0
  48. md_processing/family_docs/Glossary/Create_Glossary.md +42 -0
  49. md_processing/family_docs/Glossary/Create_Term.md +70 -0
  50. md_processing/family_docs/Glossary.md +206 -0
  51. md_processing/family_docs/Governance Officer/Create_Business_Imperative.md +106 -0
  52. md_processing/family_docs/Governance Officer/Create_Certification_Type.md +112 -0
  53. md_processing/family_docs/Governance Officer/Create_Governance_Approach.md +114 -0
  54. md_processing/family_docs/Governance Officer/Create_Governance_Obligation.md +114 -0
  55. md_processing/family_docs/Governance Officer/Create_Governance_Principle.md +114 -0
  56. md_processing/family_docs/Governance Officer/Create_Governance_Procedure.md +128 -0
  57. md_processing/family_docs/Governance Officer/Create_Governance_Process.md +122 -0
  58. md_processing/family_docs/Governance Officer/Create_Governance_Processing_Purpose.md +106 -0
  59. md_processing/family_docs/Governance Officer/Create_Governance_Responsibility.md +122 -0
  60. md_processing/family_docs/Governance Officer/Create_Governance_Rule.md +122 -0
  61. md_processing/family_docs/Governance Officer/Create_Governance_Strategy.md +106 -0
  62. md_processing/family_docs/Governance Officer/Create_License_Type.md +112 -0
  63. md_processing/family_docs/Governance Officer/Create_Naming_Standard_Rule.md +122 -0
  64. md_processing/family_docs/Governance Officer/Create_Regulation_Article.md +106 -0
  65. md_processing/family_docs/Governance Officer/Create_Regulation_Definition.md +118 -0
  66. md_processing/family_docs/Governance Officer/Create_Security_Access_Control.md +114 -0
  67. md_processing/family_docs/Governance Officer/Create_Security_Group.md +120 -0
  68. md_processing/family_docs/Governance Officer/Create_Service_Level_Objectives.md +122 -0
  69. md_processing/family_docs/Governance Officer/Create_Threat_Definition.md +106 -0
  70. md_processing/family_docs/Governance Officer/Link_Governance_Controls.md +32 -0
  71. md_processing/family_docs/Governance Officer/Link_Governance_Drivers.md +32 -0
  72. md_processing/family_docs/Governance Officer/Link_Governance_Policies.md +32 -0
  73. md_processing/family_docs/Governance Officer/View_Governance_Definitions.md +82 -0
  74. md_processing/family_docs/Governance Officer.md +2412 -0
  75. md_processing/family_docs/Solution Architect/Create_Information_Supply_Chain.md +70 -0
  76. md_processing/family_docs/Solution Architect/Create_Solution_Blueprint.md +44 -0
  77. md_processing/family_docs/Solution Architect/Create_Solution_Component.md +96 -0
  78. md_processing/family_docs/Solution Architect/Create_Solution_Role.md +66 -0
  79. md_processing/family_docs/Solution Architect/Link_Information_Supply_Chain_Peers.md +32 -0
  80. md_processing/family_docs/Solution Architect/Link_Solution_Component_Peers.md +32 -0
  81. md_processing/family_docs/Solution Architect/View_Information_Supply_Chains.md +32 -0
  82. md_processing/family_docs/Solution Architect/View_Solution_Blueprints.md +32 -0
  83. md_processing/family_docs/Solution Architect/View_Solution_Components.md +32 -0
  84. md_processing/family_docs/Solution Architect/View_Solution_Roles.md +32 -0
  85. md_processing/family_docs/Solution Architect.md +490 -0
  86. md_processing/md_commands/data_designer_commands.py +1192 -710
  87. md_processing/md_commands/glossary_commands.py +19 -32
  88. md_processing/md_commands/governance_officer_commands.py +420 -0
  89. md_processing/md_commands/product_manager_commands.py +1180 -0
  90. md_processing/md_commands/project_commands.py +5 -2
  91. md_processing/md_commands/solution_architect_commands.py +1140 -0
  92. md_processing/md_processing_utils/common_md_proc_utils.py +288 -96
  93. md_processing/md_processing_utils/common_md_utils.py +205 -6
  94. md_processing/md_processing_utils/debug_log +574 -0
  95. md_processing/md_processing_utils/dr-egeria-help-2025-07-17T17:22:09.md +2065 -0
  96. md_processing/md_processing_utils/extraction_utils.py +1 -1
  97. md_processing/md_processing_utils/generate_dr_help.py +165 -0
  98. md_processing/md_processing_utils/generate_md_cmd_templates.py +143 -0
  99. md_processing/md_processing_utils/generate_md_templates.py +92 -0
  100. md_processing/md_processing_utils/generated_help_terms.md +842 -0
  101. md_processing/md_processing_utils/md_processing_constants.py +94 -17
  102. pyegeria/__init__.py +1 -0
  103. pyegeria/_client.py +39 -1
  104. pyegeria/classification_manager_omvs.py +1 -1
  105. pyegeria/collection_manager_omvs.py +4667 -1178
  106. pyegeria/data_designer_omvs.py +348 -31
  107. pyegeria/egeria_tech_client.py +9 -25
  108. pyegeria/glossary_browser_omvs.py +5 -6
  109. pyegeria/glossary_manager_omvs.py +2 -2
  110. pyegeria/governance_officer_omvs.py +2367 -0
  111. pyegeria/output_formatter.py +157 -32
  112. pyegeria/solution_architect_omvs.py +5063 -1110
  113. pyegeria/utils.py +22 -2
  114. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/METADATA +3 -1
  115. pyegeria-5.4.0.dist-info/RECORD +243 -0
  116. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/entry_points.txt +5 -0
  117. commands/cat/.DS_Store +0 -0
  118. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
  119. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
  120. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
  121. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
  122. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
  123. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
  124. md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
  125. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
  126. md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
  127. md_processing/dr_egeria_inbox/cat_test.md +0 -100
  128. md_processing/dr_egeria_inbox/data_field.md +0 -54
  129. md_processing/dr_egeria_inbox/data_spec.md +0 -77
  130. md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
  131. md_processing/dr_egeria_inbox/data_test.md +0 -86
  132. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
  133. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
  134. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
  135. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
  136. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
  137. md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
  138. md_processing/dr_egeria_inbox/rel.md +0 -8
  139. md_processing/dr_egeria_inbox/sb.md +0 -119
  140. md_processing/dr_egeria_inbox/search_test.md +0 -39
  141. md_processing/dr_egeria_inbox/solution-components.md +0 -154
  142. md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
  143. md_processing/dr_egeria_inbox/synonym_test.md +0 -42
  144. md_processing/dr_egeria_inbox/t1.md +0 -0
  145. md_processing/dr_egeria_inbox/t2.md +0 -268
  146. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
  147. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
  148. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
  149. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
  150. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
  151. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
  152. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
  153. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
  154. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
  155. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
  156. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
  157. md_processing/md_commands/blueprint_commands.py +0 -303
  158. pyegeria/.DS_Store +0 -0
  159. pyegeria/m_test.py +0 -118
  160. pyegeria-5.3.9.9.7.dist-info/RECORD +0 -196
  161. /commands/cat/{list_data_structures.py → list_data_structures_full.py} +0 -0
  162. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/LICENSE +0 -0
  163. {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dist-info}/WHEEL +0 -0
@@ -1,11 +1,74 @@
1
1
  from datetime import datetime
2
+ import re
2
3
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
4
+ from pyegeria.utils import (camel_to_title_case)
5
+ from markdown_it import MarkdownIt
3
6
  from rich.console import Console
4
7
 
8
+ from pyegeria.mermaid_utilities import construct_mermaid_web
9
+
5
10
  console = Console(width= 250)
6
11
  # Constants
7
12
  MD_SEPARATOR = "\n---\n\n"
8
13
 
14
+ def markdown_to_html(markdown_text: str) -> str:
15
+ """
16
+ Convert markdown text to HTML, with special handling for mermaid code blocks.
17
+
18
+ Args:
19
+ markdown_text: The markdown text to convert
20
+
21
+ Returns:
22
+ HTML string
23
+ """
24
+ # Initialize markdown-it
25
+ md = MarkdownIt()
26
+
27
+ # Find all mermaid code blocks
28
+ mermaid_blocks = re.findall(r'```mermaid\n(.*?)\n```', markdown_text, re.DOTALL)
29
+
30
+ # Replace each mermaid block with a placeholder
31
+ placeholders = []
32
+ for i, block in enumerate(mermaid_blocks):
33
+ placeholder = f"MERMAID_PLACEHOLDER_{i}"
34
+ markdown_text = markdown_text.replace(f"```mermaid\n{block}\n```", placeholder)
35
+ placeholders.append((placeholder, block))
36
+
37
+ # Convert markdown to HTML
38
+ html_text = md.render(markdown_text)
39
+
40
+ # Replace placeholders with rendered mermaid HTML
41
+ for placeholder, mermaid_block in placeholders:
42
+ mermaid_html = construct_mermaid_web(mermaid_block)
43
+ html_text = html_text.replace(placeholder, mermaid_html)
44
+
45
+ # Add basic HTML structure
46
+ html_text = f"""
47
+ <!DOCTYPE html>
48
+ <html>
49
+ <head>
50
+ <meta charset="UTF-8">
51
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
52
+ <title>Egeria Report</title>
53
+ <style>
54
+ body {{ font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; }}
55
+ h1 {{ color: #2c3e50; }}
56
+ h2 {{ color: #3498db; }}
57
+ pre {{ background-color: #f8f8f8; padding: 10px; border-radius: 5px; overflow-x: auto; }}
58
+ table {{ border-collapse: collapse; width: 100%; margin-bottom: 20px; }}
59
+ th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
60
+ th {{ background-color: #f2f2f2; }}
61
+ tr:nth-child(even) {{ background-color: #f9f9f9; }}
62
+ </style>
63
+ </head>
64
+ <body>
65
+ {html_text}
66
+ </body>
67
+ </html>
68
+ """
69
+
70
+ return html_text
71
+
9
72
  def make_preamble(obj_type: str, search_string: str, output_format: str = 'MD') -> Tuple[str, Optional[str]]:
10
73
  """
11
74
  Creates a preamble string and an elements action based on the given object type, search string,
@@ -26,14 +89,16 @@ def make_preamble(obj_type: str, search_string: str, output_format: str = 'MD')
26
89
  - A string or None indicating the action description for the elements,
27
90
  depending on the output format.
28
91
  """
29
- search_string = search_string if search_string else "All Elements"
92
+ # search_string = search_string if search_string else "All Elements"
93
+ elements_md = ""
30
94
  elements_action = "Update " + obj_type
31
95
  if output_format == "FORM":
32
- preamble = (f"\n# Update {obj_type} Form - created at {datetime.now().strftime('%Y-%m-%d %H:%M')}\n"
33
- f"\t {obj_type} found from the search string: `{search_string}`\n\n")
96
+ preamble = f"\n# Update {obj_type} Form - created at {datetime.now().strftime('%Y-%m-%d %H:%M')}\n"
97
+ if search_string:
98
+ preamble += f"\t {obj_type} found from the search string: `{search_string}`\n\n"
34
99
  return preamble, elements_action
35
100
  elif output_format == "REPORT":
36
- elements_md = (f"# {obj_type} Report - created at {datetime.now().strftime('%Y-%m-%d %H:%M')}\n"
101
+ elements_md += (f"# {obj_type} Report - created at {datetime.now().strftime('%Y-%m-%d %H:%M')}\n"
37
102
  f"\t{obj_type} found from the search string: `{search_string}`\n\n")
38
103
  elements_action = None
39
104
  return elements_md, elements_action
@@ -53,16 +118,32 @@ def make_md_attribute(attribute_name: str, attribute_value: str, output_type: st
53
118
  str: Formatted markdown for the attribute
54
119
  """
55
120
  output = ""
56
- attribute_value = attribute_value.strip() if attribute_value else ""
57
- attribute_title = attribute_name.title() if attribute_name else ""
121
+ if isinstance(attribute_value,str):
122
+ attribute_value = attribute_value.strip() if attribute_value else ""
123
+ elif isinstance(attribute_value,list):
124
+ attribute_value = ",\n".join(attribute_value)
125
+ if attribute_name:
126
+ if attribute_name.upper() == "GUID":
127
+ attribute_title = attribute_name.upper()
128
+ else:
129
+ # attribute_title = attribute_name.title()
130
+ attribute_title = camel_to_title_case(attribute_name)
131
+ else:
132
+ attribute_title = ""
133
+
58
134
  if output_type in ["FORM", "MD"]:
135
+ if attribute_name.lower() in [ "mermaid", "links", "implemented by", "sub_components"]:
136
+ return '\n'
137
+
59
138
  output = f"## {attribute_title}\n{attribute_value}\n\n"
60
139
  elif output_type == "REPORT":
61
- if attribute_value:
140
+ if attribute_title in ['Mermaid Graph', 'Mermaid']:
141
+ output = f"## Mermaid Graph\n\n```mermaid\n{attribute_value}\n```\n"
142
+ elif attribute_value:
62
143
  output = f"## {attribute_title}\n{attribute_value}\n\n"
63
144
  return output
64
145
 
65
- def format_for_markdown_table(text: str) -> str:
146
+ def format_for_markdown_table(text: str, guid: str = None) -> str:
66
147
  """
67
148
  Format text for markdown tables by replacing newlines with spaces and escaping pipe characters.
68
149
  No truncation is applied to allow full-length text display regardless of console width.
@@ -76,9 +157,15 @@ def format_for_markdown_table(text: str) -> str:
76
157
  if not text:
77
158
  return ""
78
159
  # Replace newlines with spaces and escape pipe characters
79
- return text.replace("\n", " ").replace("|", "\\|")
160
+ if isinstance(text, list):
161
+ text = "\n".join(text)
162
+ t = text.replace("\n", " ").replace("|", "\\|")
163
+ if '::' in t and guid:
164
+ t = f" [{t}](#{guid}) "
165
+ return t
80
166
 
81
- def generate_entity_md(elements: List[Dict],
167
+
168
+ def generate_entity_md(elements: List[Dict],
82
169
  elements_action: str,
83
170
  output_format: str,
84
171
  entity_type: str,
@@ -101,33 +188,44 @@ def generate_entity_md(elements: List[Dict],
101
188
  elements_md = ""
102
189
 
103
190
  for element in elements:
191
+ if element is None:
192
+ continue
104
193
  props = extract_properties_func(element)
105
194
 
106
195
  # Get additional properties if function is provided
107
196
  additional_props = {}
108
197
  if get_additional_props_func:
109
- additional_props = get_additional_props_func(element, props['guid'], output_format)
198
+ additional_props = get_additional_props_func(element,props['GUID'], output_format)
199
+
200
+ display_name = props.get('displayName', None)
201
+ if display_name is None:
202
+ display_name = props.get('title', None)
203
+ if display_name is None:
204
+ display_name = "NO DISPLAY NAME"
110
205
 
111
206
  # Format header based on output format
112
207
  if output_format in ['FORM', 'MD']:
113
208
  elements_md += f"# {elements_action}\n\n"
114
- elements_md += f"## {entity_type} Name \n\n{props['display_name']}\n\n"
209
+ elements_md += f"## {entity_type} Name \n\n{display_name}\n\n"
115
210
  elif output_format == 'REPORT':
116
- elements_md += f"# {entity_type} Name: {props['display_name']}\n\n"
211
+ elements_md += f'<a id="{props["GUID"]}"></a>\n\n# {entity_type} Name: {display_name}\n\n'
117
212
  else:
118
- elements_md += f"## {entity_type} Name \n\n{props['display_name']}\n\n"
213
+ elements_md += f"## {entity_type} Name \n\n{display_name}\n\n"
119
214
 
120
215
  # Add common attributes
121
216
  for key, value in props.items():
122
- if key not in ['guid', 'properties', 'display_name']:
217
+ if output_format in ['FORM', 'MD', 'DICT'] and key == 'mermaid':
218
+ continue
219
+
220
+ if key not in [ 'properties', 'display_name']:
123
221
  elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
124
222
 
125
223
  # Add additional properties
126
224
  for key, value in additional_props.items():
127
225
  elements_md += make_md_attribute(key.replace('_', ' '), value, output_format)
128
226
 
129
- # Add GUID
130
- elements_md += make_md_attribute("GUID", props['guid'], output_format)
227
+ # # Add GUID
228
+ # elements_md += make_md_attribute("GUID",props['GUID'], output_format)
131
229
 
132
230
  # Add separator if not the last element
133
231
  if element != elements[-1]:
@@ -160,8 +258,10 @@ def generate_entity_md_table(elements: List[Dict],
160
258
  # Handle pluralization - if entity_type ends with 'y', use 'ies' instead of 's'
161
259
  entity_type_plural = f"{entity_type[:-1]}ies" if entity_type.endswith('y') else f"{entity_type}s"
162
260
 
163
- elements_md = f"# {entity_type_plural} Table\n\n"
164
- elements_md += f"{entity_type_plural} found from the search string: `{search_string}`\n\n"
261
+ elements_md = ""
262
+ if output_format == "LIST":
263
+ elements_md = f"# {entity_type_plural} Table\n\n"
264
+ elements_md += f"{entity_type_plural} found from the search string: `{search_string}`\n\n"
165
265
 
166
266
  # Add column headers
167
267
  header_row = "| "
@@ -175,12 +275,15 @@ def generate_entity_md_table(elements: List[Dict],
175
275
 
176
276
  # Add rows
177
277
  for element in elements:
178
- props = extract_properties_func(element)
278
+ if output_format == "help":
279
+ props = element
280
+ else:
281
+ props = extract_properties_func(element)
179
282
 
180
283
  # Get additional properties if function is provided
181
284
  additional_props = {}
182
285
  if get_additional_props_func:
183
- additional_props = get_additional_props_func(element, props['guid'], output_format)
286
+ additional_props = get_additional_props_func(element,props['GUID'], output_format)
184
287
 
185
288
  # Build row
186
289
  row = "| "
@@ -196,7 +299,7 @@ def generate_entity_md_table(elements: List[Dict],
196
299
 
197
300
  # Format the value if needed
198
301
  if 'format' in column and column['format']:
199
- value = format_for_markdown_table(value)
302
+ value = format_for_markdown_table(value, props['GUID'])
200
303
 
201
304
  row += f"{value} | "
202
305
 
@@ -227,19 +330,21 @@ def generate_entity_dict(elements: List[Dict],
227
330
  result = []
228
331
 
229
332
  for element in elements:
333
+ if element is None:
334
+ continue
230
335
  props = extract_properties_func(element)
231
336
 
232
337
  # Get additional properties if function is provided
233
338
  additional_props = {}
234
339
  if get_additional_props_func:
235
- additional_props = get_additional_props_func(element, props['guid'], output_format)
340
+ additional_props = get_additional_props_func(element,props['GUID'], output_format)
236
341
 
237
342
  # Create entity dictionary
238
343
  entity_dict = {}
239
344
 
240
345
  # Add properties based on include/exclude lists
241
346
  for key, value in props.items():
242
- if key != 'properties': # Skip the raw properties object
347
+ if key not in [ 'properties', 'mermaid']: # Skip the raw properties object
243
348
  if (include_keys is None or key in include_keys) and (
244
349
  exclude_keys is None or key not in exclude_keys):
245
350
  entity_dict[key] = value
@@ -289,15 +394,19 @@ def extract_basic_dict(elements: Union[Dict, List[Dict]]) -> Union[Dict, List[Di
289
394
  # Add classifications if present
290
395
  classifications = elements['elementHeader'].get('classifications', [])
291
396
  if classifications:
292
- classification_names = ""
397
+ classification_names = "["
293
398
  for classification in classifications:
294
- classification_names += f"* {classification['classificationName']}\n"
295
- body['classification_names'] = classification_names
399
+ if len(classification_names) > 1:
400
+ classification_names += ", "
401
+ classification_names += f"{classification['classificationName']}"
402
+ body['classification_names'] = classification_names + ']'
296
403
 
297
404
  return body
298
405
 
299
406
  result = []
300
407
  for element in elements:
408
+ if element is None:
409
+ continue
301
410
  body = {'guid': element['elementHeader']['guid']}
302
411
  for key in element['properties']:
303
412
  body[key] = element['properties'][key]
@@ -305,10 +414,12 @@ def extract_basic_dict(elements: Union[Dict, List[Dict]]) -> Union[Dict, List[Di
305
414
  # Add classifications if present
306
415
  classifications = element['elementHeader'].get('classifications', [])
307
416
  if classifications:
308
- classification_names = ""
417
+ classification_names = "["
309
418
  for classification in classifications:
310
- classification_names += f"* {classification['classificationName']}\n"
311
- body['classifications'] = classification_names
419
+ if len(classification_names) > 1:
420
+ classification_names += ", "
421
+ classification_names += f"{classification['classificationName']}"
422
+ body['classifications'] = classification_names + ']'
312
423
 
313
424
  result.append(body)
314
425
  return result
@@ -327,7 +438,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
327
438
  elements: Dictionary or list of dictionaries containing element data
328
439
  search_string: The search string used to find the elements
329
440
  entity_type: The type of entity (e.g., "Glossary", "Term", "Category")
330
- output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID)
441
+ output_format: The desired output format (MD, FORM, REPORT, LIST, DICT, MERMAID, HTML)
331
442
  extract_properties_func: Function to extract properties from an element
332
443
  get_additional_props_func: Optional function to get additional properties
333
444
  columns: Optional list of column definitions for table output
@@ -347,6 +458,20 @@ def generate_output(elements: Union[Dict, List[Dict]],
347
458
  if output_format == 'MERMAID':
348
459
  return extract_mermaid_only(elements)
349
460
 
461
+ elif output_format == 'HTML':
462
+ # First generate the REPORT format output
463
+ report_output = generate_output(
464
+ elements=elements,
465
+ search_string=search_string,
466
+ entity_type=entity_type,
467
+ output_format="REPORT",
468
+ extract_properties_func=extract_properties_func,
469
+ get_additional_props_func=get_additional_props_func
470
+ )
471
+
472
+ # Convert the markdown to HTML
473
+ return markdown_to_html(report_output)
474
+
350
475
  elif output_format == 'DICT':
351
476
  return generate_entity_dict(
352
477
  elements=elements,
@@ -370,7 +495,7 @@ def generate_output(elements: Union[Dict, List[Dict]],
370
495
  output_format=output_format
371
496
  )
372
497
 
373
- else: # MD, FORM, REPORT
498
+ else: # MD, FORM, REPORT
374
499
  elements_md, elements_action = make_preamble(
375
500
  obj_type=entity_type,
376
501
  search_string=search_string,