├── .gitignore ├── CHANGES.md ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README-zh_cn.md ├── README.md ├── README.rst ├── desc.png ├── markdown_css ├── __init__.py └── bin │ └── markdown-css ├── requirements.txt ├── setup.py └── themes ├── apollo.css ├── erye.css ├── infoq.css ├── less.css ├── list-writing.css ├── markdown.html ├── ocean.css ├── sanyuesha.css ├── simple.css ├── style.css ├── typing.css ├── wecatch-code.css ├── wecatch.css └── xiaolai.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | themes/public 91 | .DS_Store 92 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | markdown-css changes log 2 | ===================== 3 | 4 | ## 0.0.5 5 | 6 | - fix [#5](https://github.com/wecatch/markdown-css/issues/5) 7 | 8 | ## 0.0.4 9 | 10 | - fix important rule lost 11 | - add xiaolai.css 12 | 13 | ## 0.0.3 14 | 15 | - add support child element selector 16 | - remove log warning 17 | - add simple.css, typing.css, apollo.css 18 | 19 | ## 0.0.2 20 | 21 | fix doctopt default value error 22 | 23 | ## 0.0.1 24 | 25 | release markdown css 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 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 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include README.rst 3 | include requirements.txt 4 | include LICENSE 5 | include CHANGES.md -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean clean-test clean-pyc clean-build docs help 2 | .DEFAULT_GOAL := help 3 | define BROWSER_PYSCRIPT 4 | import os, webbrowser, sys 5 | try: 6 | from urllib import pathname2url 7 | except: 8 | from urllib.request import pathname2url 9 | 10 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 11 | endef 12 | export BROWSER_PYSCRIPT 13 | 14 | define PRINT_HELP_PYSCRIPT 15 | import re, sys 16 | 17 | for line in sys.stdin: 18 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 19 | if match: 20 | target, help = match.groups() 21 | print("%-20s %s" % (target, help)) 22 | endef 23 | export PRINT_HELP_PYSCRIPT 24 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 25 | 26 | help: 27 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 28 | 29 | clean: clean-build clean-pyc clean-test clean-log ## remove all build, test, coverage and Python artifacts 30 | 31 | define VERSION_HELP_PYSCRIPT 32 | from markdown_css import version 33 | print("v"+version) 34 | endef 35 | export VERSION_HELP_PYSCRIPT 36 | 37 | clean-build: ## remove build artifacts 38 | rm -fr build/ 39 | rm -fr dist/ 40 | rm -fr .eggs/ 41 | find . -name '*.egg-info' -exec rm -fr {} + 42 | find . -name '*.egg' -exec rm -f {} + 43 | 44 | clean-pyc: ## remove Python file artifacts 45 | find . -name '*.pyc' -exec rm -f {} + 46 | find . -name '*.pyo' -exec rm -f {} + 47 | find . -name '*~' -exec rm -f {} + 48 | find . -name '__pycache__' -exec rm -fr {} + 49 | 50 | clean-test: ## remove test and coverage artifacts 51 | rm -fr .tox/ 52 | rm -f .coverage 53 | rm -fr htmlcov/ 54 | 55 | clean-log: 56 | rm -f tests/*.log 57 | rm -f *.log 58 | 59 | release: clean ## package and upload a release 60 | python setup.py sdist bdist_wheel 61 | # python setup.py bdist_wheel 62 | twine upload dist/* 63 | 64 | dist: clean ## builds source and wheel package 65 | python setup.py sdist 66 | python setup.py bdist_wheel 67 | ls -l dist 68 | 69 | install: clean ## install the package to the active Python's site-packages 70 | python setup.py install -------------------------------------------------------------------------------- /README-zh_cn.md: -------------------------------------------------------------------------------- 1 | 2 | makrdown-css 3 | ========= 4 | 5 | Markdown-css 是一个命令行工具,用来把 css 样式转换成 html 内联样式。 6 | 7 | 8 | # 为什么是 markdown-css ? 9 | 10 | 可能吧的阿禅的在[可能吧的文章是如何排版的?](http://mp.weixin.qq.com/s?__biz=MjM5ODQwMjA4MA==&mid=2649293603&idx=1&sn=57f38200555dcba76d6358594416c089&mpshare=1&scene=1&srcid=1106ssUPcBWLZUq7D9vqXEkj#rd)中介绍了他是如何排版公众号文章的。思路就是用 markdown 写作,然后使用专门的工具导出为 html 文件,最后把自定义的样式应用到导出的文件,复制粘贴内容到微信公众号。想要自定义样式在微信公众号起作用,这些样式必须是内联的 `inline-style`,所以才有了 `markdown-css`。 11 | 12 | markdown-css 可以一键把 css 样式转换成内联样式,并输出 html 文件,就像这样: 13 | 14 | ```shell 15 | mkdir public 16 | markdown-css markdown.html --style=style.css 17 | ``` 18 | 19 | 默认生成同名的 html 文件并存放在当前目录的 public 中,双击用浏览器打开输出的文件,然后复制粘贴到公众号的编辑中,一次自定义排版就完成了。 20 | 21 | # 如何使用 22 | 23 | 24 | markdown-css 是用 Python 编写的,想要使用 markdown-css,最好在 linux 或 mac 系统下,这些系统都自带了 Python,很容易安装。 25 | 26 | 27 | ## 安装 28 | 29 | 在 macOS 中安装 30 | 31 | 32 | ```shell 33 | xcode-select --install 34 | pip install markdown-css 35 | ``` 36 | 37 | 在 Ubuntu 中安装 38 | 39 | 40 | ```shell 41 | apt-get install libxml2-dev libxslt1-dev python-dev 42 | apt-get install python-lxml 43 | pip install markdown-css 44 | ``` 45 | 46 | markdown-css 没有在 windows 下测试过,为了获得最佳体验,最好使用 macOS 和 linux。 47 | 48 | 49 | ## 使用 50 | 51 | 安装完 markdown-css,打开终端,键入 `markdown-css -h` 查看是否正确安装。虽然 markdown-css 提供一键转换的功能,但是那些漂亮的 css 还是需要自己去编写的。如果你不太懂,可以请教一下身边的程序员同学,如果你身边没有可爱的程序员,请把你的使用情况反馈给我们。 52 | 53 | 54 | # 注意事项 55 | 56 | 57 | 1. 大多数 markdown 写作工具都支持导出 html 文件,为了让自定义样式充分发挥作用,最好导出的是无样式 html 文件,[typora](http://www.typora.io/) 这款 markdown 工具就支持。 58 | 59 | 2. makrdown-css 现在只支持非常简单的 css 选择器,但对于 markdown 文件导出的 html 来说已经足够了,具体见 [Doc](https://github.com/wecatch/markdown-css#selector)。 60 | 61 | 62 | # 反馈 63 | 64 | - 在 github 提 issue 给我们反馈 [issues](https://github.com/wecatch/markdown-css/issues) 65 | - 发邮件给我们 wecatch.me@gmail.com 66 | 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | makrdown-css 2 | ========= 3 | 4 | [![pypi](https://img.shields.io/pypi/v/markdown_css.svg)](https://pypi.python.org/pypi/markdown-css) 5 | 6 | Markdown css is a command tool to convert css style into markdown inline style. 7 | 8 | [中文文档](README-zh_cn.md) 9 | [演示](http://wecatch.me/markdown-css/) 10 | 11 | ## Theme Demo 12 | 13 | [apollo.css](http://wecatch.me/markdown-css/themes/apollo.html) 14 | 15 | [ocean.css](http://wecatch.me/markdown-css/themes/ocean.html) 16 | 17 | [simple.css](http://wecatch.me/markdown-css/themes/simple.html) 18 | 19 | [style.css](http://wecatch.me/markdown-css/themes/style.html) 20 | 21 | [typing.css](http://wecatch.me/markdown-css/themes/typing.html) 22 | 23 | [xiaolai.css](http://wecatch.me/markdown-css/themes/xiaolai.html) 24 | 25 | 26 | 27 | ## Install 28 | 29 | *maxOS* 30 | 31 | ```bash 32 | xcode-select --install 33 | pip install markdown-css 34 | ``` 35 | 36 | **linux** 37 | 38 | ```bash 39 | apt-get install libxml2-dev libxslt1-dev python-dev 40 | apt-get install python-lxml 41 | pip install markdown-css 42 | ``` 43 | 44 | ## Getting started 45 | 46 | ```bash 47 | pip install markdown-css 48 | mkdir public 49 | touch style.css 50 | markdown -h 51 | markdown-css markdown.html --style=style.css --out=public 52 | ``` 53 | 54 | ### Themes 55 | 56 | https://github.com/wecatch/markdown-css/tree/master/themes 57 | 58 | ### Demo 59 | 60 | ``` 61 | git clone https://github.com/wecatch/markdown-css.git 62 | cd themes 63 | markdown-css markdown.html --style=simple.css --out=public 64 | ``` 65 | 66 | ## Selector 67 | 68 | markdown-css support css selector like these: 69 | 70 | *element selector* 71 | 72 | ```css 73 | p { 74 | margin: 10px 0; 75 | } 76 | ``` 77 | 78 | 79 | *multi element selector* 80 | 81 | ```css 82 | h1,p,h2,pre { 83 | color: #333; 84 | } 85 | ``` 86 | 87 | *all element* 88 | 89 | ```css 90 | * { 91 | font-size: 14px 92 | } 93 | ``` 94 | 95 | *pseudo-selector* 96 | 97 | ```css 98 | h1:before { 99 | content: '#' 100 | } 101 | ``` 102 | 103 | *child element seletor* 104 | 105 | ```css 106 | blockquote p { 107 | color:#888; 108 | } 109 | 110 | ``` 111 | > Pseudo-selector can't be used in inline-style, these selectos are write into \ tag 112 | 113 | ## 中文介绍 114 | 115 | markdown-css 是一个命令行工具用来为无 CSS 的 html 文档添加 CSS,渲染之后的 html 可以直接粘贴在微信公众号使用。 116 | 117 | 要使用 markdown-css ,通常你需要一款类似 typora 的编辑器,用 markdown 完成写作之后导出为不带任何 style 的 html 文档: 118 | 119 | ![](desc.png) 120 | 121 | 然后再需要提供一个主题样式,仓库里已经有了一些主题样式可以使用,用以下命令完成转换: 122 | 123 | ```shell 124 | markdown-css markdown.html --style=style.css --out=public 125 | ``` 126 | 127 | 渲染之后的文档会导出在同目录下的 public 中,用 Chrome 浏览器打开渲染之后的同名文档,复制粘贴到微信公众号编辑器即可。 128 | 129 | > 注意: 由于微信公众号对 ul 和 ol 进行了转换,markdown-css 针对这两种标签进行了特殊处理,并且提供了 render 参数来选择是否要特殊处理 ul 和 ol,默认情况为是,可以根据自己的需要不特殊处理 ul 和 ol,只要 render 不等于 wechat 即可。 -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | makrdown-css 2 | -------------- 3 | 4 | Markdown-css is a command tool to convert css style to markdown inline-style. 5 | 6 | Getting started 7 | ---------------- 8 | 9 | .. code-block:: bash 10 | 11 | pip install markdown-css 12 | mkdir public 13 | touch style.css 14 | markdown -h 15 | markdown-css pub.html --style=style.css --out=public 16 | 17 | `Doc `_ -------------------------------------------------------------------------------- /desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecatch/markdown-css/53d9d0a08f60b8cf5f91c018e0bea7710b4cd38c/desc.png -------------------------------------------------------------------------------- /markdown_css/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | # 4 | # Copyright 2016 Wecatch 5 | # 6 | # Licensed under the MIT License; you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # https://opensource.org/licenses/MIT 11 | # 12 | 13 | """Markdown css tools.""" 14 | 15 | from __future__ import ( 16 | absolute_import, division, print_function, with_statement) 17 | 18 | import logging 19 | from collections import defaultdict 20 | from cssutils import CSSParser 21 | from cssutils.css import CSSComment 22 | 23 | 24 | # version is a human-readable version number. 25 | 26 | # version_info is a four-tuple for programmatic comparison. The first 27 | # three numbers are the components of the version number. The fourth 28 | # is zero for an official release, positive for a development branch, 29 | # or negative for a release candidate or beta (after the base version 30 | # number has been incremented) 31 | version = "0.0.8" 32 | version_info = (0, 0, 8, 0) 33 | 34 | 35 | def to_inline_style(style): 36 | as_list = [] 37 | for k in style.keys(): 38 | v = style.getPropertyValue(k) 39 | p = style.getPropertyPriority(k) 40 | if p: 41 | as_list.append('%s:%s !%s' % (k, v, p)) 42 | else: 43 | as_list.append('%s:%s' % (k, v)) 44 | 45 | return ';'.join(as_list) + ';' 46 | 47 | 48 | def parse_style(cssText): 49 | element_dict = defaultdict(lambda: '') 50 | # inline style not support pseudo-selector, write into ') 103 | style('style').html('\n'.join(p_list)) 104 | html('head').append(style) 105 | 106 | out_f.write(html.html(method='html')) 107 | 108 | 109 | if __name__ == '__main__': 110 | helpdoc = """markdown-css command line. 111 | Usage: 112 | markdown-css (-h | --help) 113 | markdown-css [--out=] [--name=] [--style=