htmlgen-mcp 0.2.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.

Potentially problematic release.


This version of htmlgen-mcp might be problematic. Click here for more details.

@@ -0,0 +1,454 @@
1
+ """简单JavaScript功能工具"""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+
6
+
7
+ def create_simple_js_file(file_path: str) -> str:
8
+ """创建简单的JavaScript文件,只包含基础功能"""
9
+
10
+ js_content = """// 简单JavaScript功能
11
+
12
+ // 等待DOM加载完成
13
+ document.addEventListener('DOMContentLoaded', function() {
14
+ console.log('页面加载完成');
15
+
16
+ // 平滑滚动
17
+ setupSmoothScrolling();
18
+
19
+ // 简单的表单验证
20
+ setupFormValidation();
21
+
22
+ // 返回顶部按钮
23
+ setupBackToTop();
24
+ });
25
+
26
+ // 平滑滚动到锚点
27
+ function setupSmoothScrolling() {
28
+ const links = document.querySelectorAll('a[href^="#"]');
29
+
30
+ links.forEach(link => {
31
+ link.addEventListener('click', function(e) {
32
+ e.preventDefault();
33
+
34
+ const targetId = this.getAttribute('href');
35
+ const targetElement = document.querySelector(targetId);
36
+
37
+ if (targetElement) {
38
+ targetElement.scrollIntoView({
39
+ behavior: 'smooth'
40
+ });
41
+ }
42
+ });
43
+ });
44
+ }
45
+
46
+ // 简单表单验证
47
+ function setupFormValidation() {
48
+ const forms = document.querySelectorAll('form');
49
+
50
+ forms.forEach(form => {
51
+ form.addEventListener('submit', function(e) {
52
+ const requiredFields = form.querySelectorAll('[required]');
53
+ let isValid = true;
54
+
55
+ requiredFields.forEach(field => {
56
+ if (!field.value.trim()) {
57
+ isValid = false;
58
+ field.style.borderColor = '#dc3545';
59
+
60
+ // 移除错误样式(3秒后)
61
+ setTimeout(() => {
62
+ field.style.borderColor = '';
63
+ }, 3000);
64
+ } else {
65
+ field.style.borderColor = '';
66
+ }
67
+ });
68
+
69
+ if (!isValid) {
70
+ e.preventDefault();
71
+ alert('请填写所有必填字段');
72
+ }
73
+ });
74
+ });
75
+ }
76
+
77
+ // 返回顶部功能
78
+ function setupBackToTop() {
79
+ // 创建返回顶部按钮
80
+ const backToTopBtn = document.createElement('button');
81
+ backToTopBtn.innerHTML = '↑';
82
+ backToTopBtn.className = 'back-to-top';
83
+ backToTopBtn.style.cssText = `
84
+ position: fixed;
85
+ bottom: 20px;
86
+ right: 20px;
87
+ width: 50px;
88
+ height: 50px;
89
+ border-radius: 25px;
90
+ background-color: #007bff;
91
+ color: white;
92
+ border: none;
93
+ font-size: 20px;
94
+ cursor: pointer;
95
+ opacity: 0;
96
+ transition: opacity 0.3s;
97
+ z-index: 1000;
98
+ `;
99
+
100
+ document.body.appendChild(backToTopBtn);
101
+
102
+ // 滚动时显示/隐藏按钮
103
+ window.addEventListener('scroll', function() {
104
+ if (window.pageYOffset > 300) {
105
+ backToTopBtn.style.opacity = '1';
106
+ } else {
107
+ backToTopBtn.style.opacity = '0';
108
+ }
109
+ });
110
+
111
+ // 点击返回顶部
112
+ backToTopBtn.addEventListener('click', function() {
113
+ window.scrollTo({
114
+ top: 0,
115
+ behavior: 'smooth'
116
+ });
117
+ });
118
+ }
119
+
120
+ // 简单的切换功能
121
+ function toggleElement(elementId) {
122
+ const element = document.getElementById(elementId);
123
+ if (element) {
124
+ if (element.style.display === 'none') {
125
+ element.style.display = 'block';
126
+ } else {
127
+ element.style.display = 'none';
128
+ }
129
+ }
130
+ }
131
+
132
+ // 简单的模态框功能
133
+ function showModal(message) {
134
+ const modal = document.createElement('div');
135
+ modal.style.cssText = `
136
+ position: fixed;
137
+ top: 0;
138
+ left: 0;
139
+ width: 100%;
140
+ height: 100%;
141
+ background-color: rgba(0,0,0,0.5);
142
+ display: flex;
143
+ justify-content: center;
144
+ align-items: center;
145
+ z-index: 10000;
146
+ `;
147
+
148
+ const modalContent = document.createElement('div');
149
+ modalContent.style.cssText = `
150
+ background-color: white;
151
+ padding: 20px;
152
+ border-radius: 8px;
153
+ max-width: 400px;
154
+ text-align: center;
155
+ `;
156
+
157
+ modalContent.innerHTML = `
158
+ <p>${message}</p>
159
+ <button onclick="this.closest('.modal').remove()" style="
160
+ background-color: #007bff;
161
+ color: white;
162
+ border: none;
163
+ padding: 8px 16px;
164
+ border-radius: 4px;
165
+ margin-top: 10px;
166
+ cursor: pointer;
167
+ ">确定</button>
168
+ `;
169
+
170
+ modal.className = 'modal';
171
+ modal.appendChild(modalContent);
172
+ document.body.appendChild(modal);
173
+
174
+ // 点击背景关闭
175
+ modal.addEventListener('click', function(e) {
176
+ if (e.target === modal) {
177
+ modal.remove();
178
+ }
179
+ });
180
+ }"""
181
+
182
+ try:
183
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
184
+ with open(file_path, "w", encoding="utf-8") as f:
185
+ f.write(js_content)
186
+ return f"简单JavaScript文件创建成功: {file_path}"
187
+ except Exception as exc:
188
+ raise RuntimeError(f"创建JavaScript文件失败: {str(exc)}")
189
+
190
+
191
+ def create_minimal_js_file(file_path: str) -> str:
192
+ """创建极简JavaScript文件"""
193
+
194
+ js_content = """// 极简JavaScript功能
195
+
196
+ // 平滑滚动
197
+ document.querySelectorAll('a[href^="#"]').forEach(link => {
198
+ link.addEventListener('click', function(e) {
199
+ e.preventDefault();
200
+ const target = document.querySelector(this.getAttribute('href'));
201
+ if (target) {
202
+ target.scrollIntoView({ behavior: 'smooth' });
203
+ }
204
+ });
205
+ });
206
+
207
+ // 简单表单验证
208
+ document.querySelectorAll('form').forEach(form => {
209
+ form.addEventListener('submit', function(e) {
210
+ const required = form.querySelectorAll('[required]');
211
+ for (let field of required) {
212
+ if (!field.value.trim()) {
213
+ e.preventDefault();
214
+ alert('请填写所有必填字段');
215
+ field.focus();
216
+ return;
217
+ }
218
+ }
219
+ });
220
+ });"""
221
+
222
+ try:
223
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
224
+ with open(file_path, "w", encoding="utf-8") as f:
225
+ f.write(js_content)
226
+ return f"极简JavaScript文件创建成功: {file_path}"
227
+ except Exception as exc:
228
+ raise RuntimeError(f"创建JavaScript文件失败: {str(exc)}")
229
+
230
+
231
+ def create_interactive_js_file(file_path: str) -> str:
232
+ """创建交互式JavaScript文件"""
233
+
234
+ js_content = """// 交互式JavaScript功能
235
+
236
+ document.addEventListener('DOMContentLoaded', function() {
237
+ // 菜单切换
238
+ setupMobileMenu();
239
+
240
+ // 图片懒加载
241
+ setupLazyLoading();
242
+
243
+ // 简单动画
244
+ setupScrollAnimations();
245
+
246
+ // 表单增强
247
+ setupEnhancedForms();
248
+ });
249
+
250
+ // 移动端菜单切换
251
+ function setupMobileMenu() {
252
+ const menuToggle = document.querySelector('.menu-toggle');
253
+ const navMenu = document.querySelector('nav');
254
+
255
+ if (menuToggle && navMenu) {
256
+ menuToggle.addEventListener('click', function() {
257
+ navMenu.classList.toggle('active');
258
+ });
259
+ }
260
+ }
261
+
262
+ // 图片懒加载
263
+ function setupLazyLoading() {
264
+ const images = document.querySelectorAll('img[data-src]');
265
+
266
+ const imageObserver = new IntersectionObserver((entries) => {
267
+ entries.forEach(entry => {
268
+ if (entry.isIntersecting) {
269
+ const img = entry.target;
270
+ img.src = img.dataset.src;
271
+ img.removeAttribute('data-src');
272
+ imageObserver.unobserve(img);
273
+ }
274
+ });
275
+ });
276
+
277
+ images.forEach(img => imageObserver.observe(img));
278
+ }
279
+
280
+ // 滚动动画
281
+ function setupScrollAnimations() {
282
+ const animatedElements = document.querySelectorAll('.animate-on-scroll');
283
+
284
+ const animationObserver = new IntersectionObserver((entries) => {
285
+ entries.forEach(entry => {
286
+ if (entry.isIntersecting) {
287
+ entry.target.classList.add('animated');
288
+ }
289
+ });
290
+ });
291
+
292
+ animatedElements.forEach(el => animationObserver.observe(el));
293
+ }
294
+
295
+ // 表单增强
296
+ function setupEnhancedForms() {
297
+ // 实时验证
298
+ const inputs = document.querySelectorAll('input, textarea');
299
+
300
+ inputs.forEach(input => {
301
+ input.addEventListener('blur', function() {
302
+ validateField(this);
303
+ });
304
+
305
+ input.addEventListener('input', function() {
306
+ clearFieldError(this);
307
+ });
308
+ });
309
+ }
310
+
311
+ function validateField(field) {
312
+ const value = field.value.trim();
313
+ const type = field.type;
314
+
315
+ // 清除之前的错误
316
+ clearFieldError(field);
317
+
318
+ // 必填字段验证
319
+ if (field.hasAttribute('required') && !value) {
320
+ showFieldError(field, '此字段为必填项');
321
+ return false;
322
+ }
323
+
324
+ // 邮箱验证
325
+ if (type === 'email' && value) {
326
+ const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;
327
+ if (!emailRegex.test(value)) {
328
+ showFieldError(field, '请输入有效的邮箱地址');
329
+ return false;
330
+ }
331
+ }
332
+
333
+ // 电话验证
334
+ if (type === 'tel' && value) {
335
+ const phoneRegex = /^[\\d\\s\\-\\+\\(\\)]+$/;
336
+ if (!phoneRegex.test(value)) {
337
+ showFieldError(field, '请输入有效的电话号码');
338
+ return false;
339
+ }
340
+ }
341
+
342
+ return true;
343
+ }
344
+
345
+ function showFieldError(field, message) {
346
+ field.classList.add('error');
347
+
348
+ // 创建错误消息
349
+ const errorElement = document.createElement('span');
350
+ errorElement.className = 'error-message';
351
+ errorElement.textContent = message;
352
+ errorElement.style.cssText = `
353
+ color: #dc3545;
354
+ font-size: 0.875rem;
355
+ display: block;
356
+ margin-top: 4px;
357
+ `;
358
+
359
+ field.parentNode.appendChild(errorElement);
360
+ }
361
+
362
+ function clearFieldError(field) {
363
+ field.classList.remove('error');
364
+ const errorMessage = field.parentNode.querySelector('.error-message');
365
+ if (errorMessage) {
366
+ errorMessage.remove();
367
+ }
368
+ }
369
+
370
+ // 简单的图片轮播
371
+ function createSimpleSlider(containerId) {
372
+ const container = document.getElementById(containerId);
373
+ if (!container) return;
374
+
375
+ const images = container.querySelectorAll('img');
376
+ if (images.length <= 1) return;
377
+
378
+ let currentIndex = 0;
379
+
380
+ // 隐藏所有图片
381
+ images.forEach((img, index) => {
382
+ img.style.display = index === 0 ? 'block' : 'none';
383
+ });
384
+
385
+ // 创建控制按钮
386
+ const prevBtn = document.createElement('button');
387
+ prevBtn.textContent = '‹';
388
+ prevBtn.style.cssText = `
389
+ position: absolute;
390
+ left: 10px;
391
+ top: 50%;
392
+ transform: translateY(-50%);
393
+ background: rgba(0,0,0,0.5);
394
+ color: white;
395
+ border: none;
396
+ padding: 10px;
397
+ cursor: pointer;
398
+ `;
399
+
400
+ const nextBtn = document.createElement('button');
401
+ nextBtn.textContent = '›';
402
+ nextBtn.style.cssText = `
403
+ position: absolute;
404
+ right: 10px;
405
+ top: 50%;
406
+ transform: translateY(-50%);
407
+ background: rgba(0,0,0,0.5);
408
+ color: white;
409
+ border: none;
410
+ padding: 10px;
411
+ cursor: pointer;
412
+ `;
413
+
414
+ container.style.position = 'relative';
415
+ container.appendChild(prevBtn);
416
+ container.appendChild(nextBtn);
417
+
418
+ function showImage(index) {
419
+ images.forEach((img, i) => {
420
+ img.style.display = i === index ? 'block' : 'none';
421
+ });
422
+ }
423
+
424
+ prevBtn.addEventListener('click', () => {
425
+ currentIndex = (currentIndex - 1 + images.length) % images.length;
426
+ showImage(currentIndex);
427
+ });
428
+
429
+ nextBtn.addEventListener('click', () => {
430
+ currentIndex = (currentIndex + 1) % images.length;
431
+ showImage(currentIndex);
432
+ });
433
+
434
+ // 自动轮播
435
+ setInterval(() => {
436
+ currentIndex = (currentIndex + 1) % images.length;
437
+ showImage(currentIndex);
438
+ }, 5000);
439
+ }"""
440
+
441
+ try:
442
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
443
+ with open(file_path, "w", encoding="utf-8") as f:
444
+ f.write(js_content)
445
+ return f"交互式JavaScript文件创建成功: {file_path}"
446
+ except Exception as exc:
447
+ raise RuntimeError(f"创建JavaScript文件失败: {str(exc)}")
448
+
449
+
450
+ __all__ = [
451
+ "create_simple_js_file",
452
+ "create_minimal_js_file",
453
+ "create_interactive_js_file"
454
+ ]
@@ -0,0 +1,220 @@
1
+ """简单网页模板工具 - 无预设内容,纯净样式"""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+
6
+
7
+ def create_simple_html_file(
8
+ file_path: str,
9
+ title: str = "新页面",
10
+ content: str = "",
11
+ style: str = "clean"
12
+ ) -> str:
13
+ """创建简单HTML文件,无预设内容,只有基础结构"""
14
+
15
+ # 如果没有提供内容,创建基础结构
16
+ if not content.strip():
17
+ content = f""" <header>
18
+ <h1>{title}</h1>
19
+ <nav>
20
+ <a href="#home">首页</a>
21
+ <a href="#about">关于</a>
22
+ <a href="#contact">联系</a>
23
+ </nav>
24
+ </header>
25
+
26
+ <main>
27
+ <section id="home">
28
+ <h2>欢迎访问</h2>
29
+ <p>这里是页面的主要内容区域。</p>
30
+ </section>
31
+
32
+ <section id="about">
33
+ <h2>关于我们</h2>
34
+ <p>在这里介绍您的内容。</p>
35
+ </section>
36
+
37
+ <section id="contact">
38
+ <h2>联系方式</h2>
39
+ <p>邮箱:your-email@example.com</p>
40
+ </section>
41
+ </main>
42
+
43
+ <footer>
44
+ <p>&copy; 2024 {title}. 保留所有权利。</p>
45
+ </footer>"""
46
+
47
+ html_template = f"""<!DOCTYPE html>
48
+ <html lang="zh-CN">
49
+ <head>
50
+ <meta charset="UTF-8">
51
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
52
+ <title>{title}</title>
53
+ <link rel="stylesheet" href="assets/css/{style}.css">
54
+ </head>
55
+ <body>
56
+ {content}
57
+ </body>
58
+ </html>"""
59
+
60
+ try:
61
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
62
+ with open(file_path, "w", encoding="utf-8") as f:
63
+ f.write(html_template)
64
+ return f"简单HTML文件创建成功: {file_path}"
65
+ except Exception as exc:
66
+ raise RuntimeError(f"创建HTML文件失败: {str(exc)}")
67
+
68
+
69
+ def create_blank_html_file(file_path: str, title: str = "空白页面") -> str:
70
+ """创建完全空白的HTML文件,只有基础结构"""
71
+
72
+ html_template = f"""<!DOCTYPE html>
73
+ <html lang="zh-CN">
74
+ <head>
75
+ <meta charset="UTF-8">
76
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
77
+ <title>{title}</title>
78
+ <link rel="stylesheet" href="assets/css/clean.css">
79
+ </head>
80
+ <body>
81
+ <h1>{title}</h1>
82
+ <p>开始编写您的内容...</p>
83
+ </body>
84
+ </html>"""
85
+
86
+ try:
87
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
88
+ with open(file_path, "w", encoding="utf-8") as f:
89
+ f.write(html_template)
90
+ return f"空白HTML文件创建成功: {file_path}"
91
+ except Exception as exc:
92
+ raise RuntimeError(f"创建HTML文件失败: {str(exc)}")
93
+
94
+
95
+ def create_landing_page(file_path: str, title: str = "着陆页", description: str = "") -> str:
96
+ """创建简单的着陆页"""
97
+
98
+ desc = description or "这是一个简洁的着陆页面"
99
+
100
+ html_template = f"""<!DOCTYPE html>
101
+ <html lang="zh-CN">
102
+ <head>
103
+ <meta charset="UTF-8">
104
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
105
+ <title>{title}</title>
106
+ <link rel="stylesheet" href="assets/css/landing.css">
107
+ </head>
108
+ <body>
109
+ <div class="container">
110
+ <header class="hero">
111
+ <h1>{title}</h1>
112
+ <p class="subtitle">{desc}</p>
113
+ <button class="cta-button">开始使用</button>
114
+ </header>
115
+
116
+ <section class="features">
117
+ <div class="feature">
118
+ <h3>特点一</h3>
119
+ <p>描述第一个特点</p>
120
+ </div>
121
+ <div class="feature">
122
+ <h3>特点二</h3>
123
+ <p>描述第二个特点</p>
124
+ </div>
125
+ <div class="feature">
126
+ <h3>特点三</h3>
127
+ <p>描述第三个特点</p>
128
+ </div>
129
+ </section>
130
+
131
+ <footer>
132
+ <p>联系我们:contact@example.com</p>
133
+ </footer>
134
+ </div>
135
+ </body>
136
+ </html>"""
137
+
138
+ try:
139
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
140
+ with open(file_path, "w", encoding="utf-8") as f:
141
+ f.write(html_template)
142
+ return f"着陆页创建成功: {file_path}"
143
+ except Exception as exc:
144
+ raise RuntimeError(f"创建着陆页失败: {str(exc)}")
145
+
146
+
147
+ def create_blog_page(file_path: str, title: str = "我的博客") -> str:
148
+ """创建简单的博客页面"""
149
+
150
+ html_template = f"""<!DOCTYPE html>
151
+ <html lang="zh-CN">
152
+ <head>
153
+ <meta charset="UTF-8">
154
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
155
+ <title>{title}</title>
156
+ <link rel="stylesheet" href="assets/css/blog.css">
157
+ </head>
158
+ <body>
159
+ <div class="container">
160
+ <header>
161
+ <h1>{title}</h1>
162
+ <nav>
163
+ <a href="#home">首页</a>
164
+ <a href="#posts">文章</a>
165
+ <a href="#about">关于</a>
166
+ </nav>
167
+ </header>
168
+
169
+ <main>
170
+ <article class="post">
171
+ <h2>第一篇文章标题</h2>
172
+ <p class="meta">发布时间:2024年1月1日</p>
173
+ <p>这里是文章的内容。您可以在这里分享您的想法、经验或故事。</p>
174
+ </article>
175
+
176
+ <article class="post">
177
+ <h2>第二篇文章标题</h2>
178
+ <p class="meta">发布时间:2024年1月2日</p>
179
+ <p>另一篇文章的内容。继续添加更多有趣的内容。</p>
180
+ </article>
181
+ </main>
182
+
183
+ <aside class="sidebar">
184
+ <div class="widget">
185
+ <h3>关于作者</h3>
186
+ <p>在这里介绍一下您自己。</p>
187
+ </div>
188
+
189
+ <div class="widget">
190
+ <h3>最近文章</h3>
191
+ <ul>
192
+ <li><a href="#">文章标题一</a></li>
193
+ <li><a href="#">文章标题二</a></li>
194
+ <li><a href="#">文章标题三</a></li>
195
+ </ul>
196
+ </div>
197
+ </aside>
198
+
199
+ <footer>
200
+ <p>&copy; 2024 {title}. 保留所有权利。</p>
201
+ </footer>
202
+ </div>
203
+ </body>
204
+ </html>"""
205
+
206
+ try:
207
+ Path(file_path).parent.mkdir(parents=True, exist_ok=True)
208
+ with open(file_path, "w", encoding="utf-8") as f:
209
+ f.write(html_template)
210
+ return f"博客页面创建成功: {file_path}"
211
+ except Exception as exc:
212
+ raise RuntimeError(f"创建博客页面失败: {str(exc)}")
213
+
214
+
215
+ __all__ = [
216
+ "create_simple_html_file",
217
+ "create_blank_html_file",
218
+ "create_landing_page",
219
+ "create_blog_page"
220
+ ]