├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── example ├── blockquote.html ├── blockquote.md ├── code.html ├── code.md ├── code1.md ├── compress.html ├── django.html ├── django.md ├── git.html ├── gitbook.html ├── gitbook.md ├── gitbook1.html ├── gitbook1.md ├── gitee.html ├── gitee.md ├── github.io.html ├── github.io.md ├── hello.html ├── hello.md ├── readthedoc.html ├── readthedoc.md ├── resuite.html ├── resuite.md ├── table.html └── table.md ├── go.mod ├── go.sum ├── html2markdown.go └── html2markdown_test.go /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=go 2 | *.css linguist-language=go 3 | *.html linguist-language=go -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | # User-specific stuff: 7 | .idea/**/workspace.xml 8 | .idea/**/tasks.xml 9 | .idea/dictionaries 10 | 11 | # Sensitive or high-churn files: 12 | .idea/**/dataSources/ 13 | .idea/**/dataSources.ids 14 | .idea/**/dataSources.xml 15 | .idea/**/dataSources.local.xml 16 | .idea/**/sqlDataSources.xml 17 | .idea/**/dynamic.xml 18 | .idea/**/uiDesigner.xml 19 | 20 | # Gradle: 21 | .idea/**/gradle.xml 22 | .idea/**/libraries 23 | 24 | # CMake 25 | cmake-build-debug/ 26 | 27 | # Mongo Explorer plugin: 28 | .idea/**/mongoSettings.xml 29 | 30 | ## File-based project format: 31 | *.iws 32 | 33 | ## Plugin-specific files: 34 | 35 | # IntelliJ 36 | out/ 37 | 38 | # mpeltonen/sbt-idea plugin 39 | .idea_modules/ 40 | 41 | # JIRA plugin 42 | atlassian-ide-plugin.xml 43 | 44 | # Cursive Clojure plugin 45 | .idea/replstate.xml 46 | 47 | # Crashlytics plugin (for Android Studio and IntelliJ) 48 | com_crashlytics_export_strings.xml 49 | crashlytics.properties 50 | crashlytics-build.properties 51 | fabric.properties 52 | ### macOS template 53 | # General 54 | .DS_Store 55 | .AppleDouble 56 | .LSOverride 57 | 58 | # Icon must end with two \r 59 | Icon 60 | 61 | # Thumbnails 62 | ._* 63 | 64 | # Files that might appear in the root of a volume 65 | .DocumentRevisions-V100 66 | .fseventsd 67 | .Spotlight-V100 68 | .TemporaryItems 69 | .Trashes 70 | .VolumeIcon.icns 71 | .com.apple.timemachine.donotpresent 72 | 73 | # Directories potentially created on remote AFP share 74 | .AppleDB 75 | .AppleDesktop 76 | Network Trash Folder 77 | Temporary Items 78 | .apdisk 79 | ### Go template 80 | # Binaries for programs and plugins 81 | *.dll 82 | *.so 83 | *.dylib 84 | 85 | # Test binary, build with `go test -c` 86 | *.test 87 | 88 | # Output of the go coverage tool, specifically when used with LiteIDE 89 | *.out 90 | 91 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 92 | .glide/ 93 | ### Windows template 94 | # Windows thumbnail cache files 95 | Thumbs.db 96 | ehthumbs.db 97 | ehthumbs_vista.db 98 | 99 | # Dump file 100 | *.stackdump 101 | 102 | # Folder config file 103 | [Dd]esktop.ini 104 | 105 | # Recycle Bin used on file shares 106 | $RECYCLE.BIN/ 107 | 108 | # Windows Installer files 109 | *.cab 110 | *.msi 111 | *.msm 112 | *.msp 113 | 114 | # Windows shortcuts 115 | *.lnk 116 | 117 | 118 | .idea/ 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 进击的皇虫 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # html2md 2 | convert html to markdown 3 | 4 | 在GitHub上搜了下HTML转markdown的工具,并按照star从高到低逐个试了下,感觉不怎么符合自己的预期,索性自己写一个。 5 | 6 | 7 | ## HTML标签 8 | 并不是对所有的标签都做处理,比如`pre`、`blockquote`和`code`标签,这些没转成` ``` ` 或 `>` 或者是` ` `,因为markdown解析器解析不会有问题。 9 | 10 | ### 处理的标签 11 | - h1~h6 12 | - del 13 | - b 14 | - strong 15 | - i 16 | - em 17 | - dfn 18 | - var 19 | - cite 20 | - br 21 | - span 22 | - div 23 | - figure 24 | - p 25 | - article 26 | - nav 27 | - footer 28 | - header 29 | - section 30 | - table、thead、tbody、tr、th、td 31 | - ul、ol、li 32 | - hr 33 | 34 | ### 不作处理的标签 35 | - pre 36 | - blockquote 37 | - code 38 | 39 | 40 | ## 转化效果 41 | 为了测试转化效果,我分别从github.io、gitbook、readthedoc三个站点随便提取了个正文的HTML内容,然后并将其转成markdown,看了下效果,比较符合自己的预期。 42 | 当然,效果并不可能是100%的。 43 | 44 | ## 使用方法 45 | 46 | ### go语言使用 47 | 1. 安装 48 | `go get github.com/TruthHun/html2md` 49 | 1. 引入和调用 50 | ```go 51 | mdStr:=html2md.Convert(htmlStr) 52 | ``` 53 | 54 | ### 其他 55 | 已经编译打包了win、mac和linux的64位的可执行文件,在`bin`目录下 56 | 57 | windows使用: 58 | ``` 59 | html2md.exe input.html output.md 60 | ``` 61 | 62 | mac/linux使用: 63 | ``` 64 | html2md input.html output.md 65 | ``` 66 | 67 | 其它语言,直接使用cmd调用二进制可执行文件对文档进行处理即可 68 | 69 | ## 支持我 70 | 如果您使用了当前包或程序,遇到问题,向我反馈就是对我最好的支持;如果项目帮到了您,给当前项目一个star,也是对我莫大的认可与支持。 71 | -------------------------------------------------------------------------------- /example/blockquote.md: -------------------------------------------------------------------------------- 1 | 系统内置的验证规则如下: 2 | 3 | 4 | ## 格式验证类 5 | 6 | 7 | 8 |
9 |12 | 13 | 14 | 验证某个字段必须,例如: 15 | 16 | 17 |10 | require
11 |
'name'=>'require'
18 |
19 |
20 |
21 |
22 | 23 |26 | 27 | 28 | 验证某个字段的值是否为数字(采用24 | number 或者 integer
25 |
filter_var
验证),例如:
29 |
30 |
31 | 'num'=>'number'
32 |
33 |
34 |
35 |
36 | 37 |40 | 41 | 42 | 验证某个字段的值是否为浮点数字(采用38 | float
39 |
filter_var
验证),例如:
43 |
44 |
45 | 'num'=>'float'
46 |
47 |
48 |
49 |
50 | 51 |54 | 55 | 56 | 验证某个字段的值是否为布尔值(采用52 | boolean
53 |
filter_var
验证),例如:
57 |
58 |
59 | 'num'=>'boolean'
60 |
61 |
62 |
63 |
64 | 65 |68 | 69 | 70 | 验证某个字段的值是否为email地址(采用66 | email
67 |
filter_var
验证),例如:
71 |
72 |
73 | 'email'=>'email'
74 |
75 |
76 |
77 |
78 | 79 |82 | 83 | 84 | 验证某个字段的值是否为数组,例如: 85 | 86 | 87 |80 | array
81 |
'info'=>'array'
88 |
89 |
90 |
91 |
92 | 93 |96 | 97 | 98 | 验证某个字段是否为为 yes, on, 或是 1。这在确认"服务条款"是否同意时很有用,例如: 99 | 100 | 101 |94 | accepted
95 |
'accept'=>'accepted'
102 |
103 |
104 |
105 |
106 | 107 |110 | 111 | 112 | 验证值是否为有效的日期,例如: 113 | 114 | 115 |108 | date
109 |
'date'=>'date'
116 |
117 |
118 |
119 | 会对日期值进行strtotime
后进行判断。
120 |
121 |
122 | 123 |126 | 127 | 128 | 验证某个字段的值是否为字母,例如: 129 | 130 | 131 |124 | alpha
125 |
'name'=>'alpha'
132 |
133 |
134 |
135 |
136 | 137 |140 | 141 | 142 | 验证某个字段的值是否为字母和数字,例如: 143 | 144 | 145 |138 | alphaNum
139 |
'name'=>'alphaNum'
146 |
147 |
148 |
149 |
150 | 151 |154 | 155 | 156 | 验证某个字段的值是否为字母和数字,下划线152 | alphaDash
153 |
_
及破折号-
,例如:
157 |
158 |
159 | 'name'=>'alphaDash'
160 |
161 |
162 |
163 |
164 | 165 |168 | 169 | 170 | 验证某个字段的值只能是汉字,例如: 171 | 172 | 173 |166 | chs
167 |
'name'=>'chs'
174 |
175 |
176 |
177 |
178 | 179 |182 | 183 | 184 | 验证某个字段的值只能是汉字、字母,例如: 185 | 186 | 187 |180 | chsAlpha
181 |
'name'=>'chsAlpha'
188 |
189 |
190 |
191 |
192 | 193 |196 | 197 | 198 | 验证某个字段的值只能是汉字、字母和数字,例如: 199 | 200 | 201 |194 | chsAlphaNum
195 |
'name'=>'chsAlphaNum'
202 |
203 |
204 |
205 |
206 | 207 |210 | 211 | 212 | 验证某个字段的值只能是汉字、字母、数字和下划线_及破折号-,例如: 213 | 214 | 215 |208 | chsDash
209 |
'name'=>'chsDash'
216 |
217 |
218 |
219 |
220 | 221 |224 | 225 | 226 | 验证某个字段的值是否为有效的域名或者IP,例如: 227 | 228 | 229 |222 | activeUrl
223 |
'host'=>'activeUrl'
230 |
231 |
232 |
233 |
234 | 235 |238 | 239 | 240 | 验证某个字段的值是否为有效的URL地址(采用236 | url
237 |
filter_var
验证),例如:
241 |
242 |
243 | 'url'=>'url'
244 |
245 |
246 |
247 |
248 | 249 |252 | 253 | 254 | 验证某个字段的值是否为有效的IP地址(采用250 | ip
251 |
filter_var
验证),例如:
255 |
256 |
257 | 'ip'=>'ip'
258 |
259 |
260 |
261 | 支持验证ipv4和ipv6格式的IP地址。
262 |
263 |
264 | 265 |268 | 269 | 270 | 验证某个字段的值是否为指定格式的日期,例如: 271 | 272 | 273 |266 | dateFormat:format
267 |
'create_time'=>'dateFormat:y-m-d'
274 |
275 |
276 |
277 |
278 | ## 长度和区间验证类
279 |
280 |
281 |
282 | 283 |286 | 287 | 288 | 验证某个字段的值是否在某个范围,例如: 289 | 290 | 291 |284 | in
285 |
'num'=>'in:1,2,3'
292 |
293 |
294 |
295 |
296 | 297 |300 | 301 | 302 | 验证某个字段的值不在某个范围,例如: 303 | 304 | 305 |298 | notIn
299 |
'num'=>'notIn:1,2,3'
306 |
307 |
308 |
309 |
310 | 311 |314 | 315 | 316 | 验证某个字段的值是否在某个区间,例如: 317 | 318 | 319 |312 | between
313 |
'num'=>'between:1,10'
320 |
321 |
322 |
323 |
324 | 325 |328 | 329 | 330 | 验证某个字段的值不在某个范围,例如: 331 | 332 | 333 |326 | notBetween
327 |
'num'=>'notBetween:1,10'
334 |
335 |
336 |
337 |
338 | 339 |342 | 343 | 344 | 验证某个字段的值的长度是否在某个范围,例如: 345 | 346 | 347 |340 | length:num1,num2
341 |
'name'=>'length:4,25'
348 |
349 |
350 |
351 | 或者指定长度
352 |
353 |
354 | 'name'=>'length:4'
355 |
356 |
357 |
358 |
359 | 360 |364 | 365 | 366 | 367 |361 | 如果验证的数据是数组,则判断数组的长度。
363 |
362 | 如果验证的数据是File对象,则判断文件的大小。
368 |371 | 372 | 373 | 验证某个字段的值的最大长度,例如: 374 | 375 | 376 |369 | max:number
370 |
'name'=>'max:25'
377 |
378 |
379 |
380 |
381 | 382 |386 | 387 | 388 | 389 |383 | 如果验证的数据是数组,则判断数组的长度。
385 |
384 | 如果验证的数据是File对象,则判断文件的大小。
390 |393 | 394 | 395 | 验证某个字段的值的最小长度,例如: 396 | 397 | 398 |391 | min:number
392 |
'name'=>'min:5'
399 |
400 |
401 |
402 |
403 | 404 |408 | 409 | 410 | 411 |405 | 如果验证的数据是数组,则判断数组的长度。
407 |
406 | 如果验证的数据是File对象,则判断文件的大小。
412 |415 | 416 | 417 | 验证某个字段的值是否在某个日期之后,例如: 418 | 419 | 420 |413 | after:日期
414 |
'begin_time' => 'after:2016-3-18',
421 |
422 |
423 |
424 |
425 | 426 |429 | 430 | 431 | 验证某个字段的值是否在某个日期之前,例如: 432 | 433 | 434 |427 | before:日期
428 |
'end_time' => 'before:2016-10-01',
435 |
436 |
437 |
438 |
439 | 440 |443 | 444 | 445 | 验证当前操作(注意不是某个值)是否在某个有效日期之内,例如: 446 | 447 | 448 |441 | expire:开始时间,结束时间
442 |
'expire_time' => 'expire:2016-2-1,2016-10-01',
449 |
450 |
451 |
452 |
453 | 454 |457 | 458 | 459 | 验证当前请求的IP是否在某个范围,例如: 460 | 461 | 462 |455 | allowIp:allow1,allow2,...
456 |
'name' => 'allowIp:114.45.4.55',
463 |
464 |
465 |
466 | 该规则可以用于某个后台的访问权限
467 |
468 |
469 | 470 |473 | 474 | 475 | 验证当前请求的IP是否禁止访问,例如: 476 | 477 | 478 |471 | denyIp:allow1,allow2,...
472 |
'name' => 'denyIp:114.45.4.55',
479 |
480 |
481 |
482 |
483 | ## 字段比较类
484 |
485 |
486 |
487 | 488 |491 | 492 | 493 | 验证某个字段是否和另外一个字段的值一致,例如: 494 | 495 | 496 |489 | confirm
490 |
'repassword'=>'require|confirm:password'
497 |
498 |
499 |
500 | 5.0.4+
版本开始,增加了字段自动匹配验证规则,如password和password_confirm是自动相互验证的,只需要使用
501 |
502 |
503 | 'password'=>'require|confirm'
504 |
505 |
506 |
507 | 会自动验证和password_confirm进行字段比较是否一致,反之亦然。
508 |
509 |
510 | 511 |514 | 515 | 516 | 验证某个字段是否和另外一个字段的值不一致,例如: 517 | 518 | 519 |512 | different
513 |
'name'=>'require|different:account'
520 |
521 |
522 |
523 |
524 | 525 |528 | 529 | 530 | 验证是否等于某个值,例如: 531 | 532 | 533 |526 | eq 或者 = 或者 same
527 |
'score'=>'eq:100'
534 | 'num'=>'=:100'
535 | 'num'=>'same:100'
536 |
537 |
538 |
539 |
540 | 541 |544 | 545 | 546 | 验证是否大于等于某个值,例如: 547 | 548 | 549 |542 | egt 或者 >=
543 |
'score'=>'egt:60'
550 | 'num'=>'>=:100'
551 |
552 |
553 |
554 |
555 | 556 |559 | 560 | 561 | 验证是否大于某个值,例如: 562 | 563 | 564 |557 | gt 或者 >
558 |
'score'=>'gt:60'
565 | 'num'=>'>:100'
566 |
567 |
568 |
569 |
570 | 571 |574 | 575 | 576 | 验证是否小于等于某个值,例如: 577 | 578 | 579 |572 | elt 或者 <=
573 |
'score'=>'elt:100'
580 | 'num'=>'<=:100'
581 |
582 |
583 |
584 |
585 | 586 |589 | 590 | 591 | 验证是否小于某个值,例如: 592 | 593 | 594 |587 | lt 或者 <
588 |
'score'=>'lt:100'
595 | 'num'=>'<:100'
596 |
597 |
598 |
599 |
600 | 601 |604 | 605 | 606 | 验证对比其他字段大小(数值大小对比),例如: 607 | 608 | 609 |602 | 验证字段比较支持对比其他字段(V5.0.8+)
603 |
'price'=>'lt:market_price'
610 | 'price'=>'<:market_price'
611 |
612 |
613 |
614 |
615 | ## filter验证
616 |
617 |
618 | 支持使用filter_var进行验证,例如:
619 |
620 |
621 | 'ip'=>'filter:validate_ip'
622 |
623 |
624 |
625 |
626 | ## 正则验证
627 |
628 |
629 | 支持直接使用正则验证,例如:
630 |
631 |
632 | 'zip'=>'\d{6}',
633 | // 或者
634 | 'zip'=>'regex:\d{6}',
635 |
636 |
637 |
638 | 如果你的正则表达式中包含有|
符号的话,必须使用数组方式定义。
639 |
640 |
641 | 'accepted'=>['regex'=>'/^(yes|on|1)$/i'],
642 |
643 |
644 |
645 | 也可以实现预定义正则表达式后直接调用,例如在验证器类中定义regex
属性
646 |
647 |
648 | protected $regex = [ 'zip' => '\d{6}'];
649 |
650 |
651 |
652 | 然后就可以使用
653 |
654 |
655 | 'zip' => 'regex:zip',
656 |
657 |
658 |
659 |
660 | ## 上传验证
661 |
662 |
663 |
664 | 665 |668 | 669 | 670 | 验证是否是一个上传文件 671 | 672 | 673 |666 | file
667 |
674 |677 | 678 | 679 | 验证是否是一个图像文件,width height和type都是可选,width和height必须同时定义。 680 | 681 | 682 |675 | image:width,height,type
676 |
683 |686 | 687 | 688 | 验证上传文件后缀 689 | 690 | 691 |684 | fileExt:允许的文件后缀
685 |
692 |695 | 696 | 697 | 验证上传文件类型 698 | 699 | 700 |693 | fileMime:允许的文件类型
694 |
701 |704 | 705 | 706 | 验证上传文件大小 707 | 708 | 709 | ## 行为验证 710 | 711 | 712 | 使用行为验证数据,例如: 713 | 714 | 715 |702 | fileSize:允许的文件字节大小
703 |
'data'=>'behavior:\app\index\behavior\Check'
716 |
717 |
718 |
719 |
720 | ## 其它验证
721 |
722 |
723 |
724 | 725 |728 | 729 | 730 | 731 |726 | unique:table,field,except,pk
727 |
版本 | 调整功能 |
---|---|
5.0.5 | 支持指定完整模型类 并且默认会优先检测模型类是否存在 不存在则检测数据表 |
// 表示验证name字段的值是否在user表(不包含前缀)中唯一
738 | 'name' => 'unique:user',
739 | // 验证其他字段
740 | 'name' => 'unique:user,account',
741 | // 排除某个主键值
742 | 'name' => 'unique:user,account,10',
743 | // 指定某个主键值排除
744 | 'name' => 'unique:user,account,10,user_id',
745 |
746 |
747 |
748 | 如果需要对复杂的条件验证唯一,可以使用下面的方式:
749 |
750 |
751 | // 多个字段验证唯一验证条件
752 | 'name' => 'unique:user,status^account',
753 | // 复杂验证条件
754 | 'name' => 'unique:user,status=1&account='.$data['account'],
755 |
756 |
757 |
758 |
759 | 760 |763 | 764 | 765 | 验证某个字段的值等于某个值的时候必须,例如: 766 | 767 | 768 |761 | requireIf:field,value
762 |
// 当account的值等于1的时候 password必须
769 | 'password'=>'requireIf:account,1'
770 |
771 |
772 |
773 |
774 | 775 |778 | 779 | 780 | 验证某个字段有值的时候必须,例如: 781 | 782 | 783 |776 | requireWith:field
777 |
// 当account有值的时候password字段必须
784 | 'password'=>'requireWith:account'
785 |
786 |
--------------------------------------------------------------------------------
/example/code.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | vue-loader
是一个 webpack 的 loader,可以将用下面这个格式编写的 Vue 组件转换为 JavaScript 模块:
这里有一些 vue-loader
提供的很酷的特性:
<style>
使用 Sass 和对 <template>
使用 Jade;.vue
文件中允许自定义节点,然后使用自定义的 loader 进行处理;<style>
和 <template>
中的静态资源当作模块来对待,并使用 webpack loader 进行处理;简而言之,编写 Vue.js 应用程序时,组合使用 webpack 和 vue-loader
能带来一个现代,灵活并且非常强大的前端工作流程。
如果你已经熟悉了 webpack,随时可以跳过下面的说明。如果你没有使用过 webpack,下面是一个快速介绍:
83 |webpack 是一个模块打包工具。它将一堆文件中的每个文件都作为一个模块,找出它们的依赖关系,将它们打包为可部署的静态资源。
84 |一个基本的例子,想像我们有一些 CommonJS 模块,它们不能直接在浏览器中运行,所以我们需要打包成一个文件,这样就可以通过 <script>
标签加载。webpack 可以遵循 require()
调用的依赖关系,为我们完成这些工作。
但是 webpack 可以做的不止这些。通过“loader”,我们可以配置 webpack 以任何方式去转换所有类型的文件。包括以下例子:
87 |<style>
标签插入页面;当你理解 webpack 原理后会感觉它是如此强大,它可以大大优化你的前端工作流程。它主要的缺点是配置复杂麻烦,但是使用本指南,应该可以帮助你找到 Vue.js 和 vue-loader
使用时的最常见问题的解决方案。
vue-loader
是一个 webpack 的 loader,可以将用下面这个格式编写的 Vue 组件转换为 JavaScript 模块:
9 |
10 | 
11 |
12 | 这里有一些 vue-loader
提供的很酷的特性:
13 |
14 |
15 | - 默认支持 ES2015;
16 | - 允许对 Vue 组件的组成部分使用其它 webpack loader,比如对 <style>
使用 Sass 和对 <template>
使用 Jade;
17 | - .vue
文件中允许自定义节点,然后使用自定义的 loader 进行处理;
18 | - 把 <style>
和 <template>
中的静态资源当作模块来对待,并使用 webpack loader 进行处理;
19 | - 对每个组件模拟出 CSS 作用域;
20 | - 支持开发期组件的热重载。
21 |
22 | 简而言之,编写 Vue.js 应用程序时,组合使用 webpack 和 vue-loader
能带来一个现代,灵活并且非常强大的前端工作流程。
23 |
24 |
25 | ### webpack 是什么?
26 |
27 |
28 | 如果你已经熟悉了 webpack,随时可以跳过下面的说明。如果你没有使用过 webpack,下面是一个快速介绍:
29 |
30 | [webpack](https://webpack.github.io/) 是一个模块打包工具。它将一堆文件中的每个文件都作为一个模块,找出它们的依赖关系,将它们打包为可部署的静态资源。
31 |
32 | 
33 |
34 | 一个基本的例子,想像我们有一些 CommonJS 模块,它们不能直接在浏览器中运行,所以我们需要打包成一个文件,这样就可以通过 <script>
标签加载。webpack 可以遵循 require()
调用的依赖关系,为我们完成这些工作。
35 |
36 | 但是 webpack 可以做的不止这些。通过“loader”,我们可以配置 webpack 以任何方式去转换所有类型的文件。包括以下例子:
37 |
38 |
39 | - 转换 ES2015,CoffeeScript 或者 TypeScript 模块为普通的 ES5 CommonJS 模块;
40 | - 可以选择在编译之前检验你的源代码;
41 | - 将 Jade 模版转换为纯 HTML 并且嵌入 Javascript 字符串中;
42 | - 将 Sass 文件转换为纯 CSS,然后将其转换成 JavaScript 片段,将生成的 CSS 作为 <style>
标签插入页面;
43 | - 处理 HTML 或者 CSS 中引用的图片,移动到配置的路径中,并且使用 md5 hash 重命名。
44 |
45 | 当你理解 webpack 原理后会感觉它是如此强大,它可以大大优化你的前端工作流程。它主要的缺点是配置复杂麻烦,但是使用本指南,应该可以帮助你找到 Vue.js 和 vue-loader
使用时的最常见问题的解决方案。
46 |
47 |
--------------------------------------------------------------------------------
/example/code1.md:
--------------------------------------------------------------------------------
1 | # 介绍
2 |
3 | ### Vue Loader 是什么?
4 |
5 | vue-loader 是一个 webpack 的 loader,可以将用下面这个格式编写的 Vue 组件转换为 JavaScript 模块:
6 |
7 | 
8 |
9 | 这里有一些 vue-loader 提供的很酷的特性:
10 |
11 | - 默认支持 ES2015;
12 | - 允许对 Vue 组件的组成部分使用其它 webpack loader,比如对 使用 Sass 和对 使用 Jade;
13 | - .vue 文件中允许自定义节点,然后使用自定义的 loader 进行处理;
14 | - 把 Alert.info
信息提醒。
167 | - Alert.success
成功信息提醒。
168 | - Alert.warning
警告信息提醒。
169 | - Alert.error
错误信息提醒。
170 | - Alert.close
关闭提醒。
171 | - Alert.closeAll
关闭所有提醒。
172 |
173 |
174 | ## 获取组件
175 |
176 |
177 |
178 |
179 | import { Alert } from 'rsuite';
180 |
181 |
182 |
183 | ## 演示
184 |
185 |
186 |
187 |
188 |
189 |
190 | ### 默认
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | [](https://github.com/rsuite/rsuite.github.io/tree/master/src/pages/components/alert/basic.md)
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | xxxxxxxxxx227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 1 241 | 242 | 243 | 244 |
const instance = (
245 |
246 |
247 |
248 |
249 | 2
250 |
251 |
252 |
253 | <ButtonToolbar>
254 |
255 |
256 |
257 |
258 | 3
259 |
260 |
261 |
262 | <Button onClick={() => Alert.info('This is a informations.')}> Info </Button>
263 |
264 |
265 |
266 |
267 | 4
268 |
269 |
270 |
271 | <Button onClick={() => Alert.success('This is a successful message.')}> Success </Button>
272 |
273 |
274 |
275 |
276 | 5
277 |
278 |
279 |
280 | <Button onClick={() => Alert.warning('This is a warning notice.')}> Warning </Button>
281 |
282 |
283 |
284 |
285 | 6
286 |
287 |
288 |
289 | <Button onClick={() => Alert.error('This is an error message.')}> Error </Button>
290 |
291 |
292 |
293 |
294 | 7
295 |
296 |
297 |
298 | </ButtonToolbar>
299 |
300 |
301 |
302 |
303 | 8
304 |
305 |
306 |
307 | );
308 |
309 |
310 |
311 |
312 | 9
313 |
314 |
315 |
316 | ReactDOM.render(instance);
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | ### 延迟关闭
341 |
342 |
343 | duration 是一个可选项,当设置为 0 时,则不自动关闭。
344 |
345 |
346 |
347 | Alert.info(content: string, duration?: number, onClose?: () => void);
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 | [](https://github.com/rsuite/rsuite.github.io/tree/master/src/pages/components/alert/duration.md)
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 | xxxxxxxxxx384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 1 398 | 399 | 400 | 401 |
const instance = (
402 |
403 |
404 |
405 |
406 | 2
407 |
408 |
409 |
410 | <ButtonToolbar>
411 |
412 |
413 |
414 |
415 | 3
416 |
417 |
418 |
419 | <Button onClick={() => Alert.info('This is a informations.', 5000)}> Info </Button>
420 |
421 |
422 |
423 |
424 | 4
425 |
426 |
427 |
428 | <Button onClick={() => Alert.success('This is a successful message.', 5000)}> Success </Button>
429 |
430 |
431 |
432 |
433 | 5
434 |
435 |
436 |
437 | <Button onClick={() => Alert.warning('This is a warning notice.', 5000)}> Warning </Button>
438 |
439 |
440 |
441 |
442 | 6
443 |
444 |
445 |
446 | <Button onClick={() => Alert.error('This is an error message.', 5000)}> Error </Button>
447 |
448 |
449 |
450 |
451 | 7
452 |
453 |
454 |
455 | </ButtonToolbar>
456 |
457 |
458 |
459 |
460 | 8
461 |
462 |
463 |
464 | );
465 |
466 |
467 |
468 |
469 | 9
470 |
471 |
472 |
473 | ReactDOM.render(instance);
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 | ### 关闭
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 | [](https://github.com/rsuite/rsuite.github.io/tree/master/src/pages/components/alert/close.md)
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 | xxxxxxxxxx534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 1 548 | 549 | 550 | 551 |
const instance = (
552 |
553 |
554 |
555 |
556 | 2
557 |
558 |
559 |
560 | <ButtonToolbar>
561 |
562 |
563 |
564 |
565 | 3
566 |
567 |
568 |
569 | <Button onClick={() => Alert.info('This is a informations.')}>Open</Button>
570 |
571 |
572 |
573 |
574 | 4
575 |
576 |
577 |
578 | <Button onClick={() => Alert.close()}> Close </Button>
579 |
580 |
581 |
582 |
583 | 5
584 |
585 |
586 |
587 | <Button onClick={() => Alert.closeAll()}> Close all </Button>
588 |
589 |
590 |
591 |
592 | 6
593 |
594 |
595 |
596 | </ButtonToolbar>
597 |
598 |
599 |
600 |
601 | 7
602 |
603 |
604 |
605 | );
606 |
607 |
608 |
609 |
610 | 8
611 |
612 |
613 |
614 | ReactDOM.render(instance);
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 | ## Methods
638 |
639 |
640 |
641 | ### Alert.info
642 |
643 |
644 |
645 |
646 | Alert.info(content: string, duration?: number, onClose?: () => void);
647 |
648 |
649 |
650 | ### Alert.success
651 |
652 |
653 |
654 |
655 | Alert.success(content: string, duration?: number, onClose?: () => void);
656 |
657 |
658 |
659 | ### Alert.warning
660 |
661 |
662 |
663 |
664 | Alert.warning(content: string, duration?: number, onClose?: () => void);
665 |
666 |
667 |
668 | ### Alert.error
669 |
670 |
671 |
672 |
673 | Alert.error(content: string, duration?: number, onClose?: () => void);
674 |
675 |
676 | **参数说明**
677 |
678 |
679 | 属性名称 | 类型(默认值) | 描述 |
---|---|---|
content * | string | 信息内容 |
duration | number (2000) | 显示的时长,超过时长后自定关闭提醒框(单位:毫秒) |
onClose | ()=>void | 隐藏提醒框后的回调函数 |
Alert.close
684 |
685 |
686 |
687 |
688 | Alert.close();
689 |
690 |
691 |
692 | ### Alert.closeAll
693 |
694 |
695 |
696 |
697 | Alert.closeAll();
698 |
699 |
700 |
701 | ### Alert.config
702 |
703 |
704 | 全局配置
705 |
706 |
707 |
708 | Alert.config(options:{
709 | top?: number;
710 | duration?: number;
711 | getContainer?: () => HTMLElement;
712 | });
713 |
714 |
715 |
716 | - top - 距离页面顶部的距离 (单位 px, 默认:5)
717 | - duration - Alert 框持续时间 (默认:2000,单位: 毫秒)
718 | - getContainer - Alert 框的父级容器
719 |
720 |
721 | ## 相关组件
722 |
723 |
724 |
725 | - [<Popover>
](./popover) 弹出框
726 | - [<Tooltip>
](./tooltip) 文字提示
727 | - [<Message>
](./message) 消息框
728 | - [<Notification>
](./notification) 通知框
729 |
730 |
731 |
732 |
733 |
734 | [__](/design/default/index.html#artboard1)[](https://github.com/rsuite/rsuite.github.io/edit/master/src/pages/components/alert/index.md)[](https://github.com/rsuite/rsuite/issues/new)
735 |
736 |
737 | [获取组件](#获取组件)
738 |
739 |
740 |
741 | [演示](#演示)
742 |
743 | [默认](#默认)
744 |
745 |
746 |
747 | [延迟关闭](#延迟关闭)
748 |
749 |
750 |
751 | [关闭](#关闭)
752 |
753 |
754 |
755 |
756 |
757 | [Methods](#Methods)
758 |
759 | [Alert.info](#Alert.info)
760 |
761 |
762 |
763 | [Alert.success](#Alert.success)
764 |
765 |
766 |
767 | [Alert.warning](#Alert.warning)
768 |
769 |
770 |
771 | [Alert.error](#Alert.error)
772 |
773 |
774 |
775 | [Alert.close](#Alert.close)
776 |
777 |
778 |
779 | [Alert.closeAll](#Alert.closeAll)
780 |
781 |
782 |
783 | [Alert.config](#Alert.config)
784 |
785 |
786 |
787 |
788 |
789 | [相关组件](#相关组件)
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 | [](https://gitter.im/rsuite/rsuite)
802 |
803 |
804 |
805 |
806 |
807 | [Open Chat](https://gitter.im/rsuite/rsuite)
--------------------------------------------------------------------------------
/example/table.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | " + getInnerHtml(selection) + "
"
131 | selection.BeforeHtml(key)
132 | selection.Remove()
133 | maps[key] = cont
134 | })
135 | }
136 |
137 | if ele := doc.Find("pre"); len(ele.Nodes) > 0 {
138 | ele.Each(func(i int, selection *goquery.Selection) {
139 | key := fmt.Sprintf("{$pre%v}", i)
140 | cont := "" + getInnerHtml(selection) + "" 141 | selection.BeforeHtml(key) 142 | selection.Remove() 143 | maps[key] = cont 144 | }) 145 | } 146 | 147 | if ele := doc.Find("blockquote"); len(ele.Nodes) > 0 { 148 | ele.Each(func(i int, selection *goquery.Selection) { 149 | key := fmt.Sprintf("{$blockquote%v}", i) 150 | cont := "
" + getInnerHtml(selection) + "" 151 | selection.BeforeHtml(key) 152 | selection.Remove() 153 | maps[key] = cont 154 | }) 155 | } 156 | 157 | htmlstr, _ := doc.Html() 158 | htmlstr = strings.Replace(htmlstr, "\n", "", -1) 159 | htmlstr = strings.Replace(htmlstr, "\r", "", -1) 160 | htmlstr = strings.Replace(htmlstr, "\t", "", -1) 161 | htmlstr = strings.Replace(htmlstr, "
" + cont + "\n\n") 202 | // selection.Remove() 203 | // }) 204 | // } 205 | // 206 | // doc.Find("code").Each(func(i int, selection *goquery.Selection) { 207 | // fmt.Println(selection.Html()) 208 | // }) 209 | // 210 | // return doc 211 | //} 212 | 213 | //[ok]handle tag 214 | func handleA(doc *goquery.Document) *goquery.Document { 215 | doc.Find("a").Each(func(i int, selection *goquery.Selection) { 216 | if href, ok := selection.Attr("href"); ok { 217 | if cont, err := selection.Html(); err == nil { 218 | md := fmt.Sprintf(`[%v](%v)`, cont, href) 219 | selection.BeforeHtml(md) 220 | selection.Remove() 221 | } 222 | } 223 | }) 224 | return doc 225 | } 226 | 227 | //[ok]handle tag ul、ol、li 228 | //处理步骤: 229 | //1、先给每个li标签里面的内容加上"- "或者"\t- " 230 | //2、提取li内容 231 | func handleLi(doc *goquery.Document) *goquery.Document { 232 | var tags = []string{"ol", "ul", "li"} 233 | doc.Find("li").Each(func(i int, selection *goquery.Selection) { 234 | l := len(selection.ParentsFiltered("li").Nodes) 235 | tab := strings.Join(make([]string, l+2), "{$@$space}") 236 | selection.PrependHtml("\r$@$" + tab) 237 | }) 238 | for _, tag := range tags { 239 | doc.Find(tag).Each(func(i int, selection *goquery.Selection) { 240 | if tag == "ul" { 241 | selection.BeforeHtml("\n" + selection.Text() + "\n") 242 | } else { 243 | selection.BeforeHtml(selection.Text()) 244 | } 245 | selection.Remove() 246 | }) 247 | } 248 | htmlstr, _ := doc.Find("body").Html() 249 | for i := 10; i > 0; i-- { 250 | oldTab := "$@$" + strings.Join(make([]string, i), "{$@$space}") 251 | newTab := strings.Join(make([]string, i-1), " ") + "- " 252 | htmlstr = strings.Replace(htmlstr, oldTab, newTab, -1) 253 | } 254 | doc, _ = goquery.NewDocumentFromReader(strings.NewReader(htmlstr)) 255 | return doc 256 | } 257 | 258 | //[ok]handle tag