├── README.md ├── config ├── config.json ├── index ├── source.json └── tcl.css ├── example ├── config │ ├── config.json │ ├── index │ ├── source.json │ └── tcl.css ├── md │ ├── 0.md │ └── 1.md └── public │ ├── articles │ └── my_blog1 │ │ └── index.html │ ├── index.html │ └── pages │ └── 1 │ └── index.html └── py ├── deploy.py ├── gindex.py └── noteshare.py /README.md: -------------------------------------------------------------------------------- 1 | # noteblog 2 | 3 | ## Introduction 4 | This is a concise framework for [github blog](http://jmcglone.com/guides/github-pages/) writing. There exists many framworks, i.e. [Hexo](hexo.io), [Jekyll](https://jekyllrb.com/), etc.. But in my workflow, though [makrdown](https://en.wikipedia.org/wiki/Markdown) is simple enough, I usually use note software, like [Evernote](https://evernote.com/), [Wiz](http://www.wiz.cn), [Youdao Note](https://note.youdao.com/) which record my thoughts and good articles, alternatively, they are suitable for a editor. Therefore, I think that maybe I can make a software to generate static pages like Hexo, but the content is generated by note software. 5 | 6 | ## Usage 7 | ### 1. Make your own github blog page. 8 | You can Google it easily. 9 | ### 2. Deploy. 10 | Clone the repo and put it in a floder. Then run 11 | 12 | python deploy.py 13 | ### 3. Use note software to generate sharing links. 14 | Just Google the software U used. Maybe you are requested to be a paid user. 15 | ### 4. Copy the links to **source.json** file. 16 | The json file have 3 keys: url, file and delay. 17 | 18 | 1. url. url is a string or an array of strings. You put the sharing links here. 19 | 2. file. file is a string or an array of strings. You put the file names here. 20 | 3. delay. delay is an integer which shows the delay time. 21 | ### 5. Run noteshare.py. 22 | python noteshare.py 23 | The html files store in ./public/articles/. 24 | 25 | *-Note-*: 26 | 27 | The noteshare also supports arguments for single html generation. If the arguments aren't empty, the arguments first. 28 | 29 | * --mode default is 1 item generation. If --mode is not 0, it means many items generation. 30 | * --file 31 | * --url 32 | * --delay 33 | 34 | You can put your favicon in public folder. 35 | python noteshare.py --mode=2 --delay=3 36 | ### 6. Configure config.json. 37 | The json file have 3 keys: items_of_every_page, css and title. 38 | 39 | 1. items_of_every_page. The number of items shown in each main page. 40 | 2. css. The markdown css render file. [link](https://markdowncss.github.io/) 41 | 3. title. The blog title. 42 | 43 | ### 7. Copy the article links to **index** file. 44 | index file is the file written titles, descriptions and links. The format is: 45 | 46 | title1 47 | desp1 48 | /articles/my_blog1 49 | --- 50 | title2 51 | desp2 52 | /articles/my_blog2 53 | 54 | "---" is the separator or comment symbol. 55 | 56 | ### 8. Run gindex.py 57 | python gindex.py 58 | 59 | Then open browser, input localhost:8888. 60 | 61 | ### 9. git push 62 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "items_of_every_page": 3, 3 | "css": "../config/tcl.css", 4 | "title": "My Blog" 5 | 6 | } -------------------------------------------------------------------------------- /config/index: -------------------------------------------------------------------------------- 1 | title1 2 | desp1 3 | link1 4 | --- 5 | title2 6 | desp2 7 | /articles/my_blog1 8 | --- 9 | title3 10 | desp3 11 | link3 12 | --- 13 | title4 14 | desp4 15 | link4 -------------------------------------------------------------------------------- /config/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "http://e142cfe2.wiz01.com/share/s/3xgI_y2l2kVe2da2Kc0Od9sv2VvoU23QCQ5a2uQ5Uq19wKJb", 3 | "file": "my_blog1", 4 | "delay": 1 5 | } -------------------------------------------------------------------------------- /config/tcl.css: -------------------------------------------------------------------------------- 1 | /* http://markdowncss.github.io/ */ 2 | @media print { 3 | *, 4 | *:before, 5 | *:after { 6 | background: transparent !important; 7 | color: #000 !important; 8 | box-shadow: none !important; 9 | text-shadow: none !important; 10 | } 11 | 12 | a, 13 | a:visited { 14 | text-decoration: underline; 15 | } 16 | 17 | a[href]:after { 18 | content: " (" attr(href) ")"; 19 | } 20 | 21 | abbr[title]:after { 22 | content: " (" attr(title) ")"; 23 | } 24 | 25 | a[href^="#"]:after, 26 | a[href^="javascript:"]:after { 27 | content: ""; 28 | } 29 | 30 | pre, 31 | blockquote { 32 | border: 1px solid #999; 33 | page-break-inside: avoid; 34 | } 35 | 36 | thead { 37 | display: table-header-group; 38 | } 39 | 40 | tr, 41 | img { 42 | page-break-inside: avoid; 43 | } 44 | 45 | img { 46 | max-width: 100% !important; 47 | } 48 | 49 | p, 50 | h2, 51 | h3 { 52 | orphans: 3; 53 | widows: 3; 54 | } 55 | 56 | h2, 57 | h3 { 58 | page-break-after: avoid; 59 | } 60 | } 61 | 62 | html { 63 | font-size: 12px; 64 | } 65 | 66 | @media screen and (min-width: 32rem) and (max-width: 48rem) { 67 | html { 68 | font-size: 15px; 69 | } 70 | } 71 | 72 | @media screen and (min-width: 48rem) { 73 | html { 74 | font-size: 16px; 75 | } 76 | } 77 | 78 | body { 79 | line-height: 1.85; 80 | } 81 | 82 | p, 83 | .splendor-p { 84 | font-size: 1rem; 85 | margin-bottom: 1.3rem; 86 | } 87 | 88 | h1, 89 | .splendor-h1, 90 | h2, 91 | .splendor-h2, 92 | h3, 93 | .splendor-h3, 94 | h4, 95 | .splendor-h4 { 96 | margin: 1.414rem 0 .5rem; 97 | font-weight: inherit; 98 | line-height: 1.42; 99 | } 100 | 101 | h1, 102 | .splendor-h1 { 103 | margin-top: 0; 104 | font-size: 3.998rem; 105 | } 106 | 107 | h2, 108 | .splendor-h2 { 109 | font-size: 2.827rem; 110 | } 111 | 112 | h3, 113 | .splendor-h3 { 114 | font-size: 1.999rem; 115 | } 116 | 117 | h4, 118 | .splendor-h4 { 119 | font-size: 1.414rem; 120 | } 121 | 122 | h5, 123 | .splendor-h5 { 124 | font-size: 1.121rem; 125 | } 126 | 127 | h6, 128 | .splendor-h6 { 129 | font-size: .88rem; 130 | } 131 | 132 | small, 133 | .splendor-small { 134 | font-size: .707em; 135 | } 136 | 137 | /* https://github.com/mrmrs/fluidity */ 138 | 139 | img, 140 | canvas, 141 | iframe, 142 | video, 143 | svg, 144 | select, 145 | textarea { 146 | max-width: 100%; 147 | } 148 | 149 | @import url(http://fonts.googleapis.com/css?family=Merriweather:300italic,300); 150 | 151 | html { 152 | font-size: 18px; 153 | max-width: 100%; 154 | } 155 | 156 | body { 157 | color: #444; 158 | font-family: 'Merriweather', Georgia, serif; 159 | margin: 0; 160 | max-width: 100%; 161 | } 162 | 163 | /* === A bit of a gross hack so we can have bleeding divs/blockquotes. */ 164 | 165 | p, 166 | *:not(div):not(img):not(body):not(html):not(li):not(blockquote):not(p) { 167 | margin: 1rem auto 1rem; 168 | max-width: 36rem; 169 | padding: .25rem; 170 | } 171 | 172 | div { 173 | width: 100%; 174 | } 175 | 176 | div img { 177 | width: 100%; 178 | } 179 | 180 | blockquote p { 181 | font-size: 1.5rem; 182 | font-style: italic; 183 | margin: 1rem auto 1rem; 184 | max-width: 48rem; 185 | } 186 | 187 | li { 188 | margin-left: 2rem; 189 | } 190 | 191 | /* Counteract the specificity of the gross *:not() chain. */ 192 | 193 | h1 { 194 | padding: 4rem 0 !important; 195 | } 196 | 197 | /* === End gross hack */ 198 | 199 | p { 200 | color: #555; 201 | height: auto; 202 | line-height: 1.45; 203 | } 204 | 205 | pre, 206 | code { 207 | font-family: Menlo, Monaco, "Courier New", monospace; 208 | } 209 | 210 | pre { 211 | background-color: #fafafa; 212 | font-size: .8rem; 213 | overflow-x: scroll; 214 | padding: 1.125em; 215 | } 216 | 217 | a, 218 | a:visited { 219 | color: #3498db; 220 | } 221 | 222 | a:hover, 223 | a:focus, 224 | a:active { 225 | color: #2980b9; 226 | } -------------------------------------------------------------------------------- /example/config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "items_of_every_page": 3, 3 | "css": "../config/tcl.css", 4 | "title": "My Blog" 5 | 6 | } -------------------------------------------------------------------------------- /example/config/index: -------------------------------------------------------------------------------- 1 | title1 2 | desp1 3 | link1 4 | --- 5 | title2 6 | desp2 7 | /articles/my_blog1 8 | --- 9 | title3 10 | desp3 11 | link3 12 | --- 13 | title4 14 | desp4 15 | link4 -------------------------------------------------------------------------------- /example/config/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "http://e142cfe2.wiz01.com/share/s/3xgI_y2l2kVe2da2Kc0Od9sv2VvoU23QCQ5a2uQ5Uq19wKJb", 3 | "file": "my_blog1", 4 | "delay": 1 5 | } -------------------------------------------------------------------------------- /example/config/tcl.css: -------------------------------------------------------------------------------- 1 | /* http://markdowncss.github.io/ */ 2 | @media print { 3 | *, 4 | *:before, 5 | *:after { 6 | background: transparent !important; 7 | color: #000 !important; 8 | box-shadow: none !important; 9 | text-shadow: none !important; 10 | } 11 | 12 | a, 13 | a:visited { 14 | text-decoration: underline; 15 | } 16 | 17 | a[href]:after { 18 | content: " (" attr(href) ")"; 19 | } 20 | 21 | abbr[title]:after { 22 | content: " (" attr(title) ")"; 23 | } 24 | 25 | a[href^="#"]:after, 26 | a[href^="javascript:"]:after { 27 | content: ""; 28 | } 29 | 30 | pre, 31 | blockquote { 32 | border: 1px solid #999; 33 | page-break-inside: avoid; 34 | } 35 | 36 | thead { 37 | display: table-header-group; 38 | } 39 | 40 | tr, 41 | img { 42 | page-break-inside: avoid; 43 | } 44 | 45 | img { 46 | max-width: 100% !important; 47 | } 48 | 49 | p, 50 | h2, 51 | h3 { 52 | orphans: 3; 53 | widows: 3; 54 | } 55 | 56 | h2, 57 | h3 { 58 | page-break-after: avoid; 59 | } 60 | } 61 | 62 | html { 63 | font-size: 12px; 64 | } 65 | 66 | @media screen and (min-width: 32rem) and (max-width: 48rem) { 67 | html { 68 | font-size: 15px; 69 | } 70 | } 71 | 72 | @media screen and (min-width: 48rem) { 73 | html { 74 | font-size: 16px; 75 | } 76 | } 77 | 78 | body { 79 | line-height: 1.85; 80 | } 81 | 82 | p, 83 | .splendor-p { 84 | font-size: 1rem; 85 | margin-bottom: 1.3rem; 86 | } 87 | 88 | h1, 89 | .splendor-h1, 90 | h2, 91 | .splendor-h2, 92 | h3, 93 | .splendor-h3, 94 | h4, 95 | .splendor-h4 { 96 | margin: 1.414rem 0 .5rem; 97 | font-weight: inherit; 98 | line-height: 1.42; 99 | } 100 | 101 | h1, 102 | .splendor-h1 { 103 | margin-top: 0; 104 | font-size: 3.998rem; 105 | } 106 | 107 | h2, 108 | .splendor-h2 { 109 | font-size: 2.827rem; 110 | } 111 | 112 | h3, 113 | .splendor-h3 { 114 | font-size: 1.999rem; 115 | } 116 | 117 | h4, 118 | .splendor-h4 { 119 | font-size: 1.414rem; 120 | } 121 | 122 | h5, 123 | .splendor-h5 { 124 | font-size: 1.121rem; 125 | } 126 | 127 | h6, 128 | .splendor-h6 { 129 | font-size: .88rem; 130 | } 131 | 132 | small, 133 | .splendor-small { 134 | font-size: .707em; 135 | } 136 | 137 | /* https://github.com/mrmrs/fluidity */ 138 | 139 | img, 140 | canvas, 141 | iframe, 142 | video, 143 | svg, 144 | select, 145 | textarea { 146 | max-width: 100%; 147 | } 148 | 149 | @import url(http://fonts.googleapis.com/css?family=Merriweather:300italic,300); 150 | 151 | html { 152 | font-size: 18px; 153 | max-width: 100%; 154 | } 155 | 156 | body { 157 | color: #444; 158 | font-family: 'Merriweather', Georgia, serif; 159 | margin: 0; 160 | max-width: 100%; 161 | } 162 | 163 | /* === A bit of a gross hack so we can have bleeding divs/blockquotes. */ 164 | 165 | p, 166 | *:not(div):not(img):not(body):not(html):not(li):not(blockquote):not(p) { 167 | margin: 1rem auto 1rem; 168 | max-width: 36rem; 169 | padding: .25rem; 170 | } 171 | 172 | div { 173 | width: 100%; 174 | } 175 | 176 | div img { 177 | width: 100%; 178 | } 179 | 180 | blockquote p { 181 | font-size: 1.5rem; 182 | font-style: italic; 183 | margin: 1rem auto 1rem; 184 | max-width: 48rem; 185 | } 186 | 187 | li { 188 | margin-left: 2rem; 189 | } 190 | 191 | /* Counteract the specificity of the gross *:not() chain. */ 192 | 193 | h1 { 194 | padding: 4rem 0 !important; 195 | } 196 | 197 | /* === End gross hack */ 198 | 199 | p { 200 | color: #555; 201 | height: auto; 202 | line-height: 1.45; 203 | } 204 | 205 | pre, 206 | code { 207 | font-family: Menlo, Monaco, "Courier New", monospace; 208 | } 209 | 210 | pre { 211 | background-color: #fafafa; 212 | font-size: .8rem; 213 | overflow-x: scroll; 214 | padding: 1.125em; 215 | } 216 | 217 | a, 218 | a:visited { 219 | color: #3498db; 220 | } 221 | 222 | a:hover, 223 | a:focus, 224 | a:active { 225 | color: #2980b9; 226 | } -------------------------------------------------------------------------------- /example/md/0.md: -------------------------------------------------------------------------------- 1 | My Blog 2 | ## My Blog 3 | ### [title4](link4) 4 | desp4 5 | ### [title3](link3) 6 | desp3 7 | ### [title2](/articles/my_blog1) 8 | desp2 9 | 10 | * [Next](/pages/1) -------------------------------------------------------------------------------- /example/md/1.md: -------------------------------------------------------------------------------- 1 | My Blog 2 | ## My Blog 3 | ### [title1](link1) 4 | desp1 5 | 6 | * [Prev](/) -------------------------------------------------------------------------------- /example/public/articles/my_blog1/index.html: -------------------------------------------------------------------------------- 1 |


loading

-------------------------------------------------------------------------------- /example/public/index.html: -------------------------------------------------------------------------------- 1 |

My Blog

2 |

My Blog

3 |

title4

4 |

desp4

5 |

title3

6 |

desp3

7 |

title2

8 |

desp2

9 | 12 | -------------------------------------------------------------------------------- /example/public/pages/1/index.html: -------------------------------------------------------------------------------- 1 |

My Blog

2 |

My Blog

3 |

title1

4 |

desp1

5 | 8 | -------------------------------------------------------------------------------- /py/deploy.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | markdown_dir = r"../md" 4 | base_dir = r"../public" 5 | http_dir = r"../public/articles" 6 | index_dir = r"../public/pages" 7 | 8 | isExist_markdown = os.path.exists(markdown_dir) 9 | isExist_base = os.path.exists(base_dir) 10 | isExist_http = os.path.exists(http_dir) 11 | isExist_index = os.path.exists(index_dir) 12 | 13 | 14 | if not isExist_markdown: 15 | os.makedirs(markdown_dir) 16 | if not isExist_base: 17 | os.makedirs(base_dir) 18 | if not isExist_http: 19 | os.makedirs(http_dir) 20 | if not isExist_index: 21 | os.makedirs(index_dir) 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /py/gindex.py: -------------------------------------------------------------------------------- 1 | #python3 code 2 | #md2html.py 3 | import mistune 4 | import codecs 5 | from http.server import SimpleHTTPRequestHandler 6 | import socketserver 7 | import json 8 | import math 9 | import os 10 | import shutil 11 | 12 | with open('../config/config.json','r') as config_file: 13 | config = json.load(config_file) 14 | items_of_every_page = config['items_of_every_page'] 15 | css = config['css'] 16 | blog_title = config['title'] 17 | 18 | titles = [] 19 | descriptions = [] 20 | links = [] 21 | with open('../config/index','r', encoding = 'utf8') as f: 22 | n = 0 23 | while True: 24 | line = f.readline().strip('\n') 25 | if not line: 26 | break 27 | if line != '---': 28 | n += 1 29 | if (n%3) == 1: 30 | titles.append(line) 31 | elif (n%3) == 2: 32 | descriptions.append(line) 33 | else: 34 | links.append(line) 35 | else: 36 | pass 37 | 38 | if n == 0: 39 | raise Exception('No enough items in index!') 40 | if (n%3) != 0: 41 | raise Exception("The number of titles, descriptions and links mismatches!") 42 | 43 | number_of_md = math.ceil(n/(3.0*items_of_every_page)) 44 | pages, remainder = divmod(n/3, items_of_every_page) 45 | 46 | 47 | for i in range(number_of_md): 48 | with open(os.path.join('../md/',str(i)+'.md'), 'w', encoding = 'utf8') as f: 49 | f.write("%s\n"%blog_title) 50 | f.write("## %s\n"%blog_title) 51 | if i'+css_content+'') 92 | shutil.move("../public/pages/0/index.html", "../public/index.html") 93 | 94 | os.chdir('../public') 95 | PORT = 8888 96 | Handler = SimpleHTTPRequestHandler 97 | httpd = socketserver.TCPServer(("",PORT), Handler) 98 | print("Successful!") 99 | httpd.serve_forever() 100 | 101 | -------------------------------------------------------------------------------- /py/noteshare.py: -------------------------------------------------------------------------------- 1 | import json 2 | import argparse 3 | import os 4 | 5 | parser = argparse.ArgumentParser() 6 | parser.add_argument("--mode", "-m", default = 0, type = int, help = "The mode of reading sourceure file.") 7 | parser.add_argument("--file", "-f", default = None, help = "The name of the file.") 8 | parser.add_argument("--url", "-u", default = None, help = "The sharing link.") 9 | parser.add_argument("--delay", "-d", default = None, type = int, help = "The dealy time.") 10 | 11 | args = parser.parse_args() 12 | 13 | with open("../config/source.json",'r') as source_file: 14 | source = json.load(source_file) 15 | folder = "../public/articles/" 16 | if args.delay is None: 17 | delay = source['delay'] 18 | else: 19 | delay = args.delay 20 | 21 | if args.mode==0: 22 | if args.file is None: 23 | if not os.path.exists(os.path.join(r"../public/articles/",source['file'])): 24 | os.makedirs(os.path.join(r"../public/articles/",source['file'])) 25 | file = os.path.join(folder, source['file'], 'index.html') 26 | else: 27 | if not os.path.exists(os.path.join(r"../public/articles/",args.file)): 28 | os.makedirs(os.path.join(r"../public/articles/",args.file)) 29 | file = os.path.join(folder, args.file, 'index.html') 30 | if args.url is None: 31 | url = source['url'] 32 | else: 33 | url = args.url 34 | 35 | else: 36 | if (args.file is not None) or (args.url is not None): 37 | raise Exception("Invaild argument!") 38 | elif len(source['file'])!=len(source['url']): 39 | raise Exception("number of files and urls is not equal!") 40 | else: 41 | file = [] 42 | for x in source['file']: 43 | if not os.path.exists(os.path.join(r"../public/articles/",x)): 44 | os.makedirs(os.path.join(r"../public/articles/",x)) 45 | file.append(os.path.join(folder, x, 'index.html')) 46 | url = [y for y in source['url']] 47 | 48 | ''' 49 | http://www.html5tricks.com/tag/html5%E5%8A%A8%E7%94%BB 50 | ''' 51 | if args.mode==0: 52 | with open(file, 'w') as f: 53 | f.write("


loading

"%(delay, url)) 54 | else: 55 | length = len(file) 56 | for i in range(length): 57 | with open(file[i], 'w') as f: 58 | f.write("


loading

"%(delay, url[i])) --------------------------------------------------------------------------------