Source code for atlas_doc_parser.nodes.node_bullet_list
# -*- coding: utf-8 -*-importtypingasTimportdataclassesfromfunc_args.apiimportREQ,OPTfrom..type_enumimportTypeEnumfrom..mark_or_nodeimportBaseNodeifT.TYPE_CHECKING:# pragma: no coverfrom.node_list_itemimportNodeListItem
[docs]@dataclasses.dataclass(frozen=True)classNodeBulletList(BaseNode):""" A container for an unordered (bulleted) list. The bulletList node is a top-level block node that groups multiple listItem nodes together for rendering as a bulleted list. - https://developer.atlassian.com/cloud/jira/platform/apis/document/nodes/bulletList/ """type:str=TypeEnum.bulletList.valuecontent:list["NodeListItem"]=REQ
[docs]defto_markdown(self,level:int=0,ignore_error:bool=False,)->str:""" Convert the bullet list to Markdown format. **ADF Structure** (nested list is a **child** of listItem):: bulletList ├── listItem (item 1) │ ├── paragraph → text nodes ← text wrapped in paragraph │ └── bulletList (nested) ← nested list is CHILD of listItem │ └── listItem (item 1.1) │ ├── paragraph │ └── bulletList (nested) ├── listItem (item 2) │ ├── paragraph │ └── bulletList (nested) ... **Implementation**: Uses two nested loops because: - Outer loop: iterates over ``listItem`` nodes in ``bulletList.content`` - Inner loop: iterates over ``listItem.content`` which contains both ``paragraph`` (text) and nested ``bulletList`` nodes .. note:: This structure differs from :meth:`~atlas_doc_parser.nodes.node_task_list.NodeTaskList.to_markdown` where nested ``taskList`` nodes are **siblings** of ``taskItem`` nodes, not children. See :class:`~atlas_doc_parser.nodes.node_task_list.NodeTaskList` for comparison. .. seealso:: - :meth:`~atlas_doc_parser.nodes.node_ordered_list.NodeOrderedList.to_markdown` - same structure, uses numbers - :meth:`~atlas_doc_parser.nodes.node_task_list.NodeTaskList.to_markdown` - different structure, single loop """lines=[]indent=" "*level# 4 spaces per levelforiteminself.content:ifitem.is_type_of(TypeEnum.listItem):# Process the list item contentcontent_lines=[]fornodeinitem.content:ifnode.is_type_of(TypeEnum.bulletList):# Nested list - increase leveltry:md=node.to_markdown(level=level+1)content_lines.append(md)exceptExceptionase:ifignore_error:passelse:raiseeelse:# Regular content (like paragraph)try:md=node.to_markdown().rstrip()content_lines.append(md)exceptExceptionase:ifignore_error:passelse:raisee# Join the content linesitem_content="\n".join(content_lines)# Format the first line with bullet pointbullet_content=item_content.split("\n")[0]first_line=f"{indent}- {bullet_content}"lines.append(first_line)# Add remaining linesremaining_lines=item_content.split("\n")[1:]ifremaining_lines:lines.extend(remaining_lines)return"\n".join(lines)