一、技术栈
后端技术:
- Python:核心开发语言
- Node.js:提供markmap转换支持
- Chromium内核浏览器:提供无头浏览器服务
依赖组件:
- markmap-cli:Markdown到思维导图转换工具
- puppeteer-core:浏览器自动化工具
- requests:HTTP客户端
AI服务:
- GPT API:提供文本结构化能力
- 支持自定义API端点
- 支持自定义AI模型
二、实现思路
- 处理流程:
文本输入 -> AI结构化 -> Markdown生成 -> markmap转换 -> 浏览器渲染 -> 图片导出
关键优化点:
- 利用系统Edge浏览器,避免下载Chromium
- 支持HTML转png文件,两种格式保存
- 使用‘--no-open --no-toolbar’避免生成的图片中显示工具栏
文件管理:
文件流转:
输入文本 -> 临时MD文件 -> 临时HTML -> PNG输出
|
└-> HTML输出(保留)
三、系统架构
三层架构设计:
- md转思维导图层(MarkmapGenerator):负责文件转换
- AI处理层(Chatbot):负责文本结构化
- 接口层(MindMapGenerator):提供统一接口
项目结构:
project/
├── src/
│ ├── __init__.py
│ ├── chatbot.py # AI接口封装
│ ├── md2mindmap.py # Markdown转换器
│ └── mindmap_generator.py # 主要接口
├── scripts/ # puppeteer脚本
├── temp/ # 临时文件目录
├── output/ # 输出目录
└── examples/ # 示例输出
- 主要功能:
- 文本到思维导图的转换
- Markdown直接生成思维导图
- 自定义输出目录
- 支持PNG和HTML双格式输出
四、源代码
1. md2mindmap.py
import subprocess
from pathlib import Path
import os
class MarkmapGenerator:
def __init__(self):
# 获取当前脚本所在目录作为项目根目录
self.project_root = Path(__file__).parent.absolute()
# 确保必要的目录存在
self.ensure_project_structure()
# 使用本地 markmap,注意路径
if os.name == 'nt': # Windows 系统
self.markmap_path = str(self.project_root / 'node_modules' / '.bin' / 'markmap.cmd')
else:
self.markmap_path = str(self.project_root / 'node_modules' / '.bin' / 'markmap')
# 检查 markmap 是否存在
if not Path(self.markmap_path).exists():
raise FileNotFoundError(f"找不到 markmap: {self.markmap_path}")
# 创建其他必要路径
self.script_dir = self.project_root / 'scripts'
self.script_path = self.script_dir / 'capture_markmap.js'
self._create_puppeteer_script()
def ensure_project_structure(self):
"""确保项目目录结构完整"""
directories = [
self.project_root / 'node_modules',
self.project_root / 'scripts',
self.project_root / 'temp',
self.project_root / 'examples'
]
for directory in directories:
directory.mkdir(exist_ok=True)
def find_edge_path(self):
"""查找Edge浏览器路径"""
possible_paths = [
r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
r"C:\Program Files\Microsoft\Edge\Application\msedge.exe"
]
for path in possible_paths:
if os.path.exists(path):
return path.replace('\\', '\\\\') # 转义反斜杠
raise FileNotFoundError("找不到Edge浏览器,请确保已安装")
def _create_puppeteer_script(self):
"""创建puppeteer截图脚本"""
edge_path = self.find_edge_path()
script_content = f"""
const puppeteer = require('puppeteer-core');
async function captureMarkmap(htmlPath, pngPath) {{
const browser = await puppeteer.launch({{
headless: 'new',
args: ['--no-sandbox'],
executablePath: '{edge_path}',
product: 'chrome'
}});
try {{
const page = await browser.newPage();
await page.setViewport({{ width: 3840, height: 2160, deviceScaleFactor: 2}});
await page.goto('file://' + htmlPath, {{ waitUntil: 'networkidle0' }});
const svg = await page.$('svg');
if (!svg) throw new Error('SVG element not found');
const bbox = await svg.boundingBox();
await page.setViewport({{
width: Math.ceil(bbox.width),
height: Math.ceil(bbox.height)
}});
await svg.screenshot({{
path: pngPath,
omitBackground: true
}});
}} finally {{
await browser.close();
}}
}}
captureMarkmap(process.argv[2], process.argv[3])
.catch(error => {{
console.error('Error:', error);
process.exit(1);
}});
"""
# 确保scripts目录存在
self.script_dir.mkdir(exist_ok=True)
# 写入脚本文件
self.script_path.write_text(script_content)
def generate_and_export(self, markdown_text, output_dir=None, output_png='mindmap.png',
temp_html='temp_mindmap.html'):
"""
生成思维导图并导出为PNG和HTML
Args:
markdown_text (str): Markdown格式的思维导图内容
output_dir (str/Path, optional): 输出目录路径,如果为None则使用项目的examples目录
output_png (str): PNG文件名
temp_html (str): HTML文件名
Returns:
tuple: (PNG文件路径, HTML文件路径), 如果失败则相应位置为None
"""
# 处理输出目录
if output_dir is None:
output_dir = self.project_root / 'examples'
else:
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
# 使用临时目录
temp_dir = self.project_root / 'temp'
temp_dir.mkdir(exist_ok=True)
# 设置文件路径
temp_md = temp_dir / 'temp_markmap.md'
html_path = output_dir / temp_html
png_path = output_dir / output_png
try:
# 保存markdown内容
temp_md.write_text(markdown_text, encoding='utf-8')
# 打印调试信息
print(f"Markdown文件路径: {temp_md}")
print(f"Markmap路径: {self.markmap_path}")
print(f"HTML输出路径: {html_path}")
print(f"PNG输出路径: {png_path}")
# 使用markmap生成HTML,使用绝对路径
command = f'"{self.markmap_path}" "{temp_md.absolute()}" -o "{html_path.absolute()}" --no-open --no-toolbar'
print(f"执行命令: {command}")
result = subprocess.run(
command,
shell=True,
check=True,
capture_output=True,
text=True
)
# 打印命令输出
if result.stdout:
print("命令输出:", result.stdout)
if result.stderr:
print("命令错误:", result.stderr)
# 使用puppeteer截图
subprocess.run(
['node', str(self.script_path),
str(html_path.absolute()),
str(png_path.absolute())],
check=True,
capture_output=True,
text=True
)
# 检查文件是否生成成功
png_success = png_path.exists()
html_success = html_path.exists()
if png_success and html_success:
print(f"已生成文件:\nPNG: {png_path}\nHTML: {html_path}")
return png_path, html_path
else:
print("文件生成失败")
return (None if not png_success else png_path,
None if not html_success else html_path)
except subprocess.CalledProcessError as e:
print(f"执行失败: {e}")
print(f"命令输出: {e.output if hasattr(e, 'output') else '无输出'}")
return None, None
except Exception as e:
print(f"发生错误: {str(e)}")
return None, None
finally:
# 清理临时文件
if temp_md.exists():
temp_md.unlink()
2. chatbot.py
import requests
import json
# 支持自定义url,apikey,模型以及提示词,且支持在对话过程中切换模型和提示词,实际应用中主要使用single_chat避免污染大模型记忆
class Chatbot:
def __init__(self, url, api_key, model, system_prompt="You are a helpful assistant."):
self.url = url
self.api_key = api_key
self.model = model
self.conversation_history = [{"role": "system", "content": system_prompt}]
self.headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
self.total_tokens = 0
def set_system_prompt(self, system_prompt):
self.conversation_history[0] = {"role": "system", "content": system_prompt}
def set_system_model(self, model):
self.model = model
def _send_request(self, messages):
payload = {
"model": self.model,
"messages": messages
}
response = requests.post(self.url, headers=self.headers, json=payload)
if response.status_code == 200:
try:
json_response = response.json()
if 'choices' in json_response and len(json_response['choices']) > 0:
# 更新 total_tokens
if 'usage' in json_response and 'total_tokens' in json_response['usage']:
self.total_tokens += json_response['usage']['total_tokens']
return json_response['choices'][0]['message']['content']
else:
return response.text
except json.JSONDecodeError:
return response.text
else:
raise Exception(f"API request failed with status code {response.status_code}: {response.text}")
def add_to_history(self, user_input, ai_output):
self.conversation_history.append({"role": "user", "content": user_input})
self.conversation_history.append({"role": "assistant", "content": ai_output})
def add_role_to_history(self, role, role_input):
self.conversation_history.append({"role": role, "content": role_input})
def chat(self, user_input):
messages = self.conversation_history.copy()
messages.append({"role": "user", "content": user_input})
response = self._send_request(messages)
self.add_to_history(user_input, response)
return response
def single_chat(self, user_input):
messages = self.conversation_history.copy()
messages.append({"role": "user", "content": user_input})
response = self._send_request(messages)
return response
def single_chat_complex(self, user_input, system_message):
messages = self.conversation_history.copy()
messages.append({"role": "user", "content": user_input})
messages.append({"role": "system", "content": system_message})
response = self._send_request(messages)
return response
def clear_history(self):
system_prompt = self.conversation_history[0]
self.conversation_history = [system_prompt]
def get_conversation_history(self):
return self.conversation_history
def remove_last_conversation(self):
if len(self.conversation_history) > 1: # 确保至少保留系统提示
self.conversation_history.pop()
if self.conversation_history[-1]["role"] == "user":
self.conversation_history.pop()
def get_tokens(self):
return self.total_tokens
3. mindmap_generator.py
from pathlib import Path
from typing import Tuple, Optional
from md2mindmap import MarkmapGenerator
from Chatbot import Chatbot
class MindMapGenerator:
"""思维导图生成器,用于将文本转换为思维导图"""
def __init__(self, chatbot: Chatbot, output_dir: str = None):
self.chatbot = chatbot
# 初始化思维导图生成器
self.markmap_generator = MarkmapGenerator()
# 设置输出目录
if output_dir is None:
self.output_dir = self.markmap_generator.project_root / 'output'
else:
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
# 设置AI提示词
self.set_mindmap_prompt()
def set_mindmap_prompt(self):
"""设置生成思维导图的AI提示词"""
prompt = """你现在是一个文本结构分析专家,擅长将文本内容转换为层次清晰的Markdown格式(你输出的格式需要符合markmap的要求)。
请遵循以下规则:
1. 使用Markdown标题语法(#)创建层次结构
2. 主标题使用一个#,每一个层级增加一个#
3. 层级不要超过4层
4. 提取文本的关键信息和主要概念
5. 保持结构清晰和逻辑性
6. 使用简洁的语言
7. 不要包含任何额外的解释或者非Markdown的内容
例如:
---
title: markmap
markmap:
colorFreezeLevel: 2
---
## Links
- [Website](https://markmap.js.org/)
- [GitHub](https://github.com/gera2ld/markmap)
## Related Projects
- [coc-markmap](https://github.com/gera2ld/coc-markmap) for Neovim
- [markmap-vscode](https://marketplace.visualstudio.com/items?itemName=gera2ld.markmap-vscode) for VSCode
- [eaf-markmap](https://github.com/emacs-eaf/eaf-markmap) for Emacs
## Features
Note that if blocks and lists appear at the same level, the lists will be ignored.
### Lists
- **strong** ~~del~~ *italic* ==highlight==
- `inline code`
- [x] checkbox
- Katex: $x = {-b \pm \sqrt{b^2-4ac} \over 2a}$ <!-- markmap: fold -->
- [More Katex Examples](#?d=gist:af76a4c245b302206b16aec503dbe07b:katex.md)
- Now we can wrap very very very very long text based on `maxWidth` option
- Ordered list
1. item 1
2. item 2
### Blocks
| Products | Price |
|-|-|
| Apple | 4 |
| Banana | 2 |

请将我提供的文本按照上述规则转换为Markdown格式。使用txt格式直接输出Markdown内容,不需要其他解释,禁止使用代码块。"""
self.chatbot.set_system_prompt(prompt)
def text_to_markdown(self, text: str) -> str:
# 使用AI将文本转换为Markdown格式
markdown = self.chatbot.single_chat(text)
return markdown
def generate_mindmap(self, text: str, output_name: str = "mindmap") -> Tuple[Optional[Path], Optional[Path]]:
try:
# 1. 将文本转换为Markdown
markdown = self.text_to_markdown(text)
print("\nMarkdown转换结果:")
print(markdown)
# 2. 生成思维导图
png_path, html_path = self.markmap_generator.generate_and_export(
markdown_text=markdown,
output_dir=self.output_dir,
output_png=f"{output_name}.png",
temp_html=f"{output_name}.html"
)
return png_path, html_path
except Exception as e:
print(f"生成思维导图时发生错误: {str(e)}")
return None, None
def generate_mindmap_from_markdown(self, markdown: str, output_name: str = "mindmap") -> Tuple[
Optional[Path], Optional[Path]]:
try:
png_path, html_path = self.markmap_generator.generate_and_export(
markdown_text=markdown,
output_dir=self.output_dir,
output_png=f"{output_name}.png",
temp_html=f"{output_name}.html"
)
return png_path, html_path
except Exception as e:
print(f"生成思维导图时发生错误: {str(e)}")
return None, None
def generate_mindmap_for_text(text: str, output_name: str, output_dir: str = None):
# 创建Chatbot实例
chatbot = Chatbot(
url="api端点",
api_key="api密钥",
model="模型"
)
# 创建生成器实例
generator = MindMapGenerator(chatbot, output_dir)
# 生成思维导图
png_path, html_path = generator.generate_mindmap(text, output_name)
if png_path and html_path:
print(f"\n思维导图生成成功!")
print(f"文件保存在:\nPNG: {png_path}\nHTML: {html_path}")
return png_path, html_path
else:
print("\n思维导图生成失败!")
return None, None
def test_mindmap_generator():
"""测试思维导图生成器"""
# 测试文本
test_text = "你是否也曾疑惑过,肚脐下面会通向哪里呢?你看,这玩意儿常年散发了一股不可名状的气息,当你凝望肚脐的时候,肚脐好像也在凝望着你似的。而且更诡异的是,教科望说肚脐是脐带脱落留下的疤,但问题是刚出生的小鸡、小牙、蜥蜴甚至龟龟身上,我们都能看到那个肚脐,总不能他们在丹里还能跟妈妈无限传输养分吧?好,那么贴心的方法福今天就来给你们讲讲关于肚脐的一切,这事儿我们还得从3年5亿年前史探记开始说起。当此之时,茂密的雨林覆盖着广袤大地,大气涵氧样殖随着层层上涨,那么枝液瓦开之下,刚登陆才小几千万年的脊椎动物一片勃勃生机。然而,明明再努力掩外吧就能上班了,这些家伙就突然纷纷停下了像更深内入前进的脚步,问题出在它们的繁殖方式上。当时人的脊椎动物基本上都还像今天青蛙一样产出凝胶包物胚胎形式的卵,这种卵在空气中很容易干死,必须产在水中才能发育孵化,而且它们的幼体也往往需要经历一段类似鱼类的水生形态才能长大成熟,重新登陆。这祖宗之法可没不么容易撼动,没关系,正所谓不杀生,演化止步不前。很快当时一种水族就盯上这漏洞,但老祖宗前脚过来产卵子,后脚就过来加餐,个别得寸进尺,还帮助来分亲子洞。这层摇篮到坟墓一揽的服务,终于是撬动了我们的底层发育逻辑。一开始,我们祖先也许只能养成一些凑合的办法,这也许可以参考今天的I事舰员,他们给自己凝胶碗的外面又包上一层薄薄包膜,从而得以在一定程度上保住其中的水分。这样只要是一些猪物灵工土坑之类相对潮湿的地方救能产卵,所以说靠这一手繁衍就不会变成大窝了。但问题是诱地孵衰也没地方生活呀。诶,既然整不活,那就继续整活,我们祖先就转而大大减少产卵数量,有。 营养生到手术的卵中,精成一个大大的卵黄胚胎,直接把血管长过去就能吸收养分,这让后代可以在卵中度过整个蝌蚪阶段,直接孵化出能够在陆地上生活的小儿科。有很多小伙伴问我们微博老师,为啥咱人类不会经历幼虫阶段了?诶,现在你知道了,咱人类其实有幼虫阶段,波过兰祖先几年前就把这合并到胚胎发育过程中去了,而这条演化路径再走远一点,就缔造出了真正意义上的陆壁脊椎动物,那就是我们羊膜动物。而当初我们原祖用来包裹住自己凝胶卵的薄膜,也就演化成我们今天包裹住胎儿的羊膜。只不过在后来的演化中,羊膜动物祖先在这次羊膜之外又添置了很多层结构,让这个卵保睡能力越来越强,也越来越皮实,最终就形成了所谓的羊膜卵,差不多就是我们今天口语中所谓的蛋窝。外面的问题解决了,里面的问题又冒了出来。你想幼虫阶段给病毒,胚胎发育了以后,那孵化时间可就长了,这期间胚胎吃喝拉撒全在一个蛋米,尤其代谢产生的含氮废物组成尿可是有毒了,那咋办呢?蛋有三级血无气窍啊日羊毛卵虫产生了一个结构,叫做尿囊,顾名思义就是储存尿液的囊。用你接受胎儿发育过程中的含难废物,不介于胚胎液不是很难生活自理,但大理宫胚液不似乎不太够。对此,尿囊给出的相当简单粗暴解决方案,它直接伸出到尿管,穿透胚胎肚皮,连通膀胱,非常方便。不过这样一来,保出身以后,尿囊、胰腺就会在肚子上留下的凹陷的疤痕,这便是我们不奇最早的来源。因为所有羊毛动物的卵都有尿囊的个结构,所以鸡、鸭、蛇、手工海龟这些卵生动物刚出生时也会有肚脐,而这根导尿管也正是我们脐带最早的雏形。至此,羊毛卵终于神功出尘,这位小小的蛋夫就成了我们远古鲜卑的曲驴飞船。 带领他们冲出了水体的演化黑域,然而即将抵达的却是一片黑暗森林,结果顷刻之间,这些最初的真度地脊椎动物就突然对自己的同侪们亮出了嗜血的爪牙,对不起,地球足够小,容不下这么多族裔,而我们哺乳动物或者说兽族和公共祖先这是最早意识到这法则,一批入一起椎动物这所谓开局抢地盘,你关键器胞晚出18年,那你就是个死人了。所以咱受族老祖宗的演化斯宗突出的莽子,凡事儿够用不行就力求快速爆科技开局一波,这事儿他一年土很多,回了会头就回,又会以会看这些往期视频,虽然这波操作让我们祖先在最近约3亿年前迅速扫出天下,一路成为当时最强势的羊魔动物族裔,没有之一,具有限的巨大隐患,其中之一就殃及了这羊魔卵,故是我们之前所说的我们受阻还依旧和两栖祖先一样,主要靠水溶线尿素来代谢海氮废物,那对于陈年动物来说也还好,但是对蛋里面的小宝宝来说就很麻烦了,因着尿素的溶间在水中排出,那蛋里面的尿囊最多就那些空间,宝宝要是尿再黄也用不了多久就会装满哦喉完蛋那活食不能给尿憋死啊。于是我们这是养母动物就无奈只能全力压缩胚胎在蛋里面留存的时间,提前破壳复出发育极端不良的幼崽。更麻烦的是开局先狩灭了咬灵居杀不窗全场,在当时盘古超化坞边边角角的苦寒之地,依然幸存了另一只羊魔动物,那就是龙族七形纲,而他们的科技树就明显比咱州远古科技一波流要扎实的多。比如在代谢含氮废物这块儿,龙族就改用了固态的尿酸,养过手工的硒粉,很有应该见过他们拉屎时一并排出一大白花花像牙膏一样的玩意儿,那就是他们饿的尿酸,这可比撒尿节省空间多了。就靠着全称无尿田的代谢,龙族终于把羊膜卵也就是它。 的蛋发展到了极致,完全可以等孩子发育的全区全尾了再出来。于是乎就因为205亿年前,随着西利亚火山的一声巨响,动物也迎来自诞生以来最惨烈的二叠寂寞大灭绝。废土之上,种族进儿必然比受族犬子能多上几分生机,这在一定程度上也促使大灾之后天罡一晚兽族王朝轰然崩塌,而以恐龙为代表龙族飞入高歌们进这了终生代最靓的崽。反观来兽族祖先却然被逼了一度神绝地求生与虫豸威武,很多兽族类群眼瞅着咱这羊魔卵是好不了的,那就干脆放开这甩子一身多生,只求能抽出几个八字阴根,有后来这小崽子把自身香火给传递下去。刘生活在君,因为1.91年前走出物鸡的咔咔延兽仍们在记丑聚乙其中发现多了38个微小幼崽,把丈夫揣又仔就更加惨不忍睹了。这人先天不足,后天来臭,也许就是什么机缘巧合之下,变说咱们的不木科技鼠波兰受族好歹也是救我们后裔大耗子身居天地间,其能郁郁久居龙下,我有些扶过相野的意味,受阻织不堪大育的羊波卵,其实已经悄然为我们开启了另一条未曾设想的道路。最开始为了尽量让胚胎发育的时间长一些,我们祖先就转而让胚胎现在自己输卵管里面发育一段时间,有妈妈不断吸收期含氮废物,一直到宝宝实在没办法继续的输卵管里待下去了,才给它包上蛋壳生出来。今年只生活在霍拉亚期附近岛屿的鸭腿生活针眼或者说单恐目哺乳动物,它依然暴露这种生育方式,当分子生物学证据来看,我们在最精病1多年前,三叠接素线很有可能也是这么干的,尽管这饮食压岁时候妈妈所能做到极限了,但这距离真正的胎神还有非成能非常遥远的距离,最大的困难在于重情一下宝宝就业园地排放给妈妈是没问题,但妈妈却很难把营养输送给宝宝。因此,当胎儿长了到单纯的物。 扩塞已经无法提供足之养分的时候,就不得不伸出来了,而最好的方法就让胎儿长出一部分组织,直接扎根到妈妈的生殖到内壁,从妈妈的血液中直接吸收养分。但别的不说,面对这种操作,妈妈血管的免疫细胞稳见了高低的问候一句,而要是什么保健是否锋利了,这可是动物自古以来老爸难的问题了。很多其他走胎山路线动物,有时候都会逼得搞出一些相当逆天的解法,比如软骨鱼,也就是我们平时说的各种沙和礁,就不止一次独立养化出一种称为胚胎相食的行为,就是字面意义上的养儿当养骨,最种应颊通吃。好在咱祖先育儿里念没这么灵存诊取,他们在一开始可能只在尿囊表面配置一层,除了传递物质以外没啥功能,故而缺乏特性膜蛋白的细胞,你可以理解为这玩意儿在免疫细胞也能属于肠命物件,一般无法选中。然后再把带有重细胞尿囊贴到目前输卵管内壁上扎根,于是就有了原始的胎盘。只不过这个方案吧,也不完美,毕竟随着胎盘不断长大,各种变隙,它的屏脏细胞之间难免会出现一些缝隙,更不用说等胚胎发育都能运动了,它时不时对着胎盘太阳角拽体下接眼闷,而免疫细胞,尤其是其中攻击欲望最强的中性粒细胞,又刚好极其善于变形脊过缝隙,因此这样的原始胎盘虽然也许能实现真胎神,但还是只能感生出几端早产儿。但是吧,就这样落的看似比领导化的比还大的麻烦,居然在最近1亿多年前莫名其妙的就给解决了,那年有这么一位神通广大病毒,他竟有本事从千里之外把自己的基因克到我们祖先的DNA里,他想干什么呀?他就是想不再跟免疫系统斗智斗勇,要走后门,让我们祖先直接帮他把基因传下去,他奶奶的竟打起了子孙后代的主意,那我们祖先就偏要把这。 众多基因部署在胚胎屏障第一线,那么永生永世都去正面高免疫细胞,恰好这种病毒可以制造一类被称为核胞素的特殊蛋白质,而这种蛋白质能够进到动物细胞互相融合,于是乎我们祖先就把这核胞素基因表达在了原始胎盘上面,进早其表面的屏障细胞互相融合,这样就从根本上断绝产生缝隙的可能性,使彻底变成一股面小胞卡,过去的空气墙被称为荷胞体滋养层。至此胎盘演化植物前方再无坎壳,胎儿也终于可以发育到非常大。为此,这些毒乳动物有所性,但一部分输卵管很大,程断门有纳胎儿的子宫。这一切都标志着当今地球中最王道的哺乳物类群有胎盘类正式登上了历史舞台,不久后最行于6600万年前神法天降,大到磨灭,而这一次有胎盘类好大儿果然没创到二叠纪祖先了覆辙,这大明人中物种幸存比例最高的类群之一,这一回我又赢了龙族。但盈盈盈的烦恼在新生代,哺乳动物体型急剧增大,于是乎联动胎盘与胎儿乞爱也随之越来越长,妊娠期的延长也让这哺乳动物的微生儿主观的动性不断提升,尤其是在咱灵长类这里,爆坝阳胎里就特别能扯,那乞丐的工作压力就更大了呀。不过那么多大风大浪都挺过来了,这点小事儿显然不足挂齿。一方面我们让脐丐拧不上几拳,这样就能像脚下的麻绳一样提升抗巴强度,但关键是大铁心里自身硬,为此,我们祖宗严选了一种性能易绝的其爱填充物,那就是华通胶热种物质一听就知道得名于17世纪的英国老西医托马斯华通,而且主要组成成分正是透明质酸,或者打一个更常见的名字玻尿酸,由于透明质酸本来就是各种动物填充组织建些重要材料,让我们自古。 癌就具备很多跟透明质酸代谢相关的基因,可以根据需要制造出许多多种不同性能的透明质酸来满足不同中组织的支撑、弹性、润滑的不同需求。而且脐带这里透明质酸的黑科技也迎来了它在生物中的巅峰。据估计,在人类脐带中透明质酸的含量能达到4.1g未深,是人体中的含量最高的部位。由于透明质酸作为类常电分子,并此以像其他高分子材料一样具有绝佳的抗拉强度,经测算其来平均断液拉力足足有肉体重量的2.5倍。就算胎儿来子宫中舒展筋骨,大一跳闪用连鞭也扯不断了。而且划分胶这玩意儿捏起来苯球苯久的,再怎么挤压也很难阻断脐带中的血管和尿管。当母亲分娩,孩子连成脐带,胎寒都一同排出母毒体,而这时候问题又来了,脐带里这些大血管跟着脐带一起灌胎,那岂不是要大出血?咱现在人类分娩,有专业医护给你止血,那也是,那么可能一人给碰上医保啊,没事儿,只要华生胶出手,一切都会好起来的。由于各种不同透明质酸的黑壁恰到好处,使华生胶对温度十分敏感,一旦胎儿出生,脐带温度下降,氨胶变的立即随之收缩,大月在5分钟内就能自动加紧脐带中的血管,不但能防止新儿从脐带血管大量失血,还能让残疾的脐带失血儿干枯萎缩,最终从新生儿身上脱落。而脐带或者说导药管在我们体内的部分也会在出生后的几天里逐渐闭锁消失。因此我们的不起就是和单纯的凹根,它的背后没有通到任何地方,但他的背后却又蕴藏了无穷的历史,仿佛永远在诉说着我们祖先打碎命运的桎梏,穿透亿万思年逆天改命的传奇。这里是方卡福,我们下期再见。"
# 生成思维导图
generate_mindmap_for_text(test_text, "ai_introduction")
if __name__ == "__main__":
test_mindmap_generator()
使用说明:
- 环境配置:
# 安装Node.js依赖
npm install markmap-cli puppeteer-core
# 安装Python依赖
pip install requests pathlib
package.json:
{
"name": "markmap-project",
"version": "1.0.0",
"description": "Markmap generator project",
"main": "index.js",
"dependencies": {
"markmap-cli": "^0.14.4",
"puppeteer-core": "^21.0.0"
},
"scripts": {
}
}
- 基本使用:
# 创建Chatbot实例
chatbot = Chatbot(
url="your_api_url",
api_key="your_api_key",
model="your_model"
)
# 创建生成器实例
generator = MindMapGenerator(chatbot)
# 生成思维导图
png_path, html_path = generator.generate_mindmap(
text="your text content",
output_name="mindmap"
)
注意事项:
- 确保系统已安装Edge浏览器
- 确保Node.js环境正确配置
- 确保输出目录具有写入权限
- 配置正确的AI API认证信息
可选配置:
- 自定义输出目录
- 调整AI提示词
- 修改图片分辨率
- 自定义文件命名
评论区