diff --git a/.gitignore b/.gitignore
index 5d6365ad..0226ab6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,7 +24,7 @@ _testmain.go
 mindoc
 mindoc_linux_amd64
 mindoc_linux_musl_amd64
-database
+database/mindoc.db
 *.test
 *.prof
 .idea
diff --git a/README.md b/README.md
index 97f01280..286a2b0d 100644
--- a/README.md
+++ b/README.md
@@ -268,3 +268,59 @@ docker run -p 8181:8181 --name mindoc -e DB_ADAPTER=mysql -e MYSQL_PORT_3306_TCP
 
 一个不纯粹的PHPer,一个不自由的 gopher 。
 
+
+# 部署补充
+- 若内网部署,draw.io无法使用外网,则需要用tomcat运行war包,见(https://github.com/jgraph/drawio) 从release下载,之后修改markdown.js的TODO行对应的链接即可
+- 为了护眼,简单增加了编辑界面的主题切换,见editormd.js和markdown_edit_template.tpl
+- (需重新编译项)为了对已删除文档/文档引用图片删除文字后,对悬空无引用的图片/附件进行清理,增加了清理接口,需重新编译
+     - 编译后除二进制文件外还需更新三个文件: conf/lang/en-us.ini,zh-cn.ini; attach_list.tpl
+     - 若不想重新编译,也可通过database/clean.py,手动执行对无引用图片/附件的文件清理和数据库记录双向清理。
+- 若采用nginx二级部署,以yourpath/为例,需修改
+     - conf/app.conf修改:`baseurl="/yourpath"`
+     - static/js/kancloud.js文件中`url: "/comment/xxxxx` => `url: "/yourpath" + "/comment/xxxxx`, 共两处
+
+     - nginx端口代理示例:
+     ```
+     增加
+     location  /yourpath/ {
+          rewrite ^/yourpath/(.*) /$1  break;
+          proxy_pass http://127.0.0.1:8181;
+     }
+     ```
+     注意使用的是127.0.0.1,根据自身选择替换,如果nginx是docker部署,则还需要在docker中托管运行mindoc,具体参考如下配置:
+     - docker-compose代理示例(docker-nginx代理运行mindoc)
+     ```
+     version: '3'
+     services:
+       mynginx:
+       image: nginx:latest
+       ports:
+         - "8880:80"
+       command: 
+         - bash
+         - -c
+         - |
+             service nginx start
+             cd /src/mindoc/ && ./mindoc
+       volumes:
+         - ..:/src
+         - ./nginx:/etc/nginx/conf.d
+     ```
+
+     目录结构
+     ```
+     onefolder
+     |
+       - docker
+       |
+         - docker-compose.yml
+         - nginx
+         |
+           - mynginx.conf
+       
+       - mindoc
+       |
+         - database/
+         - conf/
+         - ...
+     ```
\ No newline at end of file
diff --git a/conf/lang/en-us.ini b/conf/lang/en-us.ini
index 40ea2147..ad12463e 100644
--- a/conf/lang/en-us.ini
+++ b/conf/lang/en-us.ini
@@ -54,6 +54,7 @@ yes = yes
 no = no
 read = Read
 generate = Generate
+clean = Clean
 
 [init]
 default_proj_name = MinDoc Demo Project
diff --git a/conf/lang/zh-cn.ini b/conf/lang/zh-cn.ini
index 912e7419..bd566ccc 100644
--- a/conf/lang/zh-cn.ini
+++ b/conf/lang/zh-cn.ini
@@ -54,6 +54,7 @@ yes = 是
 no = 否
 read = 阅读
 generate = 生成
+clean = 清理
 
 [init]
 default_proj_name = MinDoc演示项目
diff --git a/controllers/ManagerController.go b/controllers/ManagerController.go
index dea3e507..8a065775 100644
--- a/controllers/ManagerController.go
+++ b/controllers/ManagerController.go
@@ -634,6 +634,41 @@ func (c *ManagerController) AttachList() {
 	c.Data["Lists"] = attachList
 }
 
+//附件清理.
+func (c *ManagerController) AttachClean() {
+	c.Prepare()
+
+	attachList, _, err := models.NewAttachment().FindToPager(0, 0)
+
+	if err != nil {
+		c.Abort("500")
+	}
+
+	for _, item := range attachList {
+
+		p := filepath.Join(conf.WorkingDirectory, item.FilePath)
+
+		item.IsExist = filetil.FileExists(p)
+		if item.IsExist {
+			// 判断
+			searchList, err := models.NewDocumentSearchResult().SearchAllDocument(item.HttpPath)
+			if err != nil {
+				c.Abort("500")
+			} else if len(searchList) == 0 {
+				logs.Info("delete file:", item.FilePath)
+				item.FilePath = p
+				if err := item.Delete(); err != nil {
+					logs.Error("AttachDelete => ", err)
+					c.JsonResult(6002, err.Error())
+					break
+				}
+			}
+		}
+	}
+
+	c.JsonResult(0, "ok")
+}
+
 //附件详情.
 func (c *ManagerController) AttachDetailed() {
 	c.Prepare()
diff --git a/database/clean.py b/database/clean.py
new file mode 100644
index 00000000..85783273
--- /dev/null
+++ b/database/clean.py
@@ -0,0 +1,34 @@
+import sqlite3
+import os, glob
+
+conn = sqlite3.connect("mindoc.db")
+cur = conn.cursor()         #通过建立数据库游标对象,准备读写操作
+
+
+cmd = """
+SELECT 
+    att.http_path
+FROM
+    md_attachment AS att
+WHERE (att.document_id != 0 OR (NOT EXISTS( SELECT 1 FROM md_documents WHERE markdown LIKE ("%" || att.http_path || "%"))))
+AND (att.document_id = 0 OR (NOT EXISTS( SELECT 1 FROM md_documents WHERE att.document_id = document_id )))
+"""
+cur.execute(cmd)
+file_list = cur.fetchall()
+for file_item in file_list:
+    item_path = file_item[0]
+    # 1. 删除os文件
+    if os.path.exists(os.path.join("..", item_path[1:])):
+        os.remove(os.path.join("..", item_path[1:]))
+    
+    # 2. 查询os是否删除成功,成功则删除附件记录
+    if not os.path.exists(os.path.join("..", item_path[1:])):
+        cmd = """
+        delete
+        from md_attachment
+        WHERE http_path = '{}'
+        """.format(item_path)
+        cur.execute(cmd)
+conn.commit()   #保存提交,确保数据保存成功
+
+conn.close()        #关闭与数据库的连接
\ No newline at end of file
diff --git a/models/AttachmentModel.go b/models/AttachmentModel.go
index 8e2d45ce..5de9fb31 100644
--- a/models/AttachmentModel.go
+++ b/models/AttachmentModel.go
@@ -102,11 +102,15 @@ func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList []*Attachm
 		return nil, 0, err
 	}
 	totalCount = int(total)
-	offset := (pageIndex - 1) * pageSize
 
 	var list []*Attachment
 
-	_, err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-attachment_id").Offset(offset).Limit(pageSize).All(&list)
+	offset := (pageIndex - 1) * pageSize
+	if pageSize == 0 {
+		_, err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-attachment_id").Offset(offset).Limit(pageSize).All(&list)
+	} else {
+		_, err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-attachment_id").All(&list)
+	}
 
 	if err != nil {
 		if err == orm.ErrNoRows {
diff --git a/models/DocumentSearchResult.go b/models/DocumentSearchResult.go
index 499bba55..8e5097f0 100644
--- a/models/DocumentSearchResult.go
+++ b/models/DocumentSearchResult.go
@@ -309,3 +309,23 @@ func (m *DocumentSearchResult) SearchDocument(keyword string, bookId int) (docs
 
 	return
 }
+
+// 所有项目搜索.
+func (m *DocumentSearchResult) SearchAllDocument(keyword string) (docs []*DocumentSearchResult, err error) {
+	o := orm.NewOrm()
+
+	sql := "SELECT * FROM md_documents WHERE (document_name LIKE ? OR `release` LIKE ?) "
+	keyword = "%" + keyword + "%"
+
+	_need_escape := need_escape(keyword)
+	escape_sql := func(sql string) string {
+		if _need_escape {
+			return escape_re.ReplaceAllString(sql, escape_replace)
+		}
+		return sql
+	}
+
+	_, err = o.Raw(escape_sql(sql), keyword, keyword).QueryRows(&docs)
+
+	return
+}
diff --git a/routers/router.go b/routers/router.go
index a6996180..8e4b773b 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -154,6 +154,7 @@ func init() {
 	web.Router("/manager/books/open", &controllers.ManagerController{}, "post:PrivatelyOwned")
 
 	web.Router("/manager/attach/list", &controllers.ManagerController{}, "*:AttachList")
+	web.Router("/manager/attach/clean", &controllers.ManagerController{}, "post:AttachClean")
 	web.Router("/manager/attach/detailed/:id", &controllers.ManagerController{}, "*:AttachDetailed")
 	web.Router("/manager/attach/delete", &controllers.ManagerController{}, "post:AttachDelete")
 	web.Router("/manager/label/list", &controllers.ManagerController{}, "get:LabelList")
diff --git a/static/editor.md/editormd.js b/static/editor.md/editormd.js
index 70013ce0..980f7cac 100755
--- a/static/editor.md/editormd.js
+++ b/static/editor.md/editormd.js
@@ -71,7 +71,7 @@
             "list-ul", "list-ol", "hr", "|",
             "link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|",
             "goto-line", "watch", "preview", "fullscreen", "clear", "search", "|",
-            "help", "info"
+            "help", "changetheme", "info"
         ],
         simple : [
             "undo", "redo", "|",
@@ -79,12 +79,12 @@
             "h1", "h2", "h3", "h4", "h5", "h6", "|",
             "list-ul", "list-ol", "hr", "|",
             "watch", "preview", "fullscreen", "|",
-            "help", "info"
+            "help", "changetheme", "info"
         ],
         mini : [
             "undo", "redo", "|",
             "watch", "preview", "|",
-            "help", "info"
+            "help", "changetheme", "info"
         ]
     };
 
@@ -94,8 +94,8 @@
         name                 : "",             // Form element name
         value                : "",             // value for CodeMirror, if mode not gfm/markdown
         theme                : "",             // Editor.md self themes, before v1.5.0 is CodeMirror theme, default empty
-        editorTheme          : "default",      // Editor area, this is CodeMirror theme at v1.5.0
-        previewTheme         : "",             // Preview area theme, default empty
+        editorTheme          : "pastel-on-dark", //"default",      // Editor area, this is CodeMirror theme at v1.5.0
+        previewTheme         : "dark", //"",             // Preview area theme, default empty
         markdown             : "",             // Markdown source code
         appendMarkdown       : "",             // if in init textarea value not empty, append markdown to textarea
         width                : "100%",
@@ -225,6 +225,7 @@
             fullscreen       : "fa-arrows-alt",
             clear            : "fa-eraser",
             help             : "fa-question-circle",
+            changetheme      : "fa-info-circle",
             info             : "fa-info-circle"
         },
         toolbarIconTexts     : {},
@@ -271,6 +272,7 @@
                 clear            : "清空",
                 search           : "搜索",
                 help             : "使用帮助",
+                changetheme      : "切换编辑主题",
                 info             : "关于" + editormd.title
             },
             buttons : {
@@ -322,7 +324,10 @@
                 },
                 help : {
                     title : "使用帮助"
-                }
+                },
+                changetheme : {
+                    title : "切换编辑主题"
+                },
             }
         }
     };
@@ -3385,6 +3390,11 @@
             this.executePlugin("helpDialog", "help-dialog/help-dialog");
         },
 
+        changetheme : function() {
+            this.setEditorTheme((this.settings.editorTheme=="default")?"pastel-on-dark":"default");
+            this.setPreviewTheme((this.settings.previewTheme=="")?"dark":"");
+        },
+
         info : function() {
             this.showInfoDialog();
         }
diff --git a/static/js/markdown.js b/static/js/markdown.js
index 5f2fff4f..c450e3ce 100644
--- a/static/js/markdown.js
+++ b/static/js/markdown.js
@@ -72,7 +72,7 @@ $(function () {
 
     drawio.show = function () {
 
-        const drawUrl = 'https://embed.diagrams.net/?embed=1&libraries=1&proto=json&spin=1&saveAndExit=1&noSaveBtn=1&noExitBtn=0';
+        const drawUrl = 'https://embed.diagrams.net/?embed=1&libraries=1&proto=json&spin=1&saveAndExit=1&noSaveBtn=1&noExitBtn=0'; // TODO: with Tomcat & https://github.com/jgraph/drawio
         this.div = document.createElement('div');
         this.div.id = 'diagram';
         this.gXml = '';
diff --git a/views/document/markdown_edit_template.tpl b/views/document/markdown_edit_template.tpl
index e22e2327..5a141376 100644
--- a/views/document/markdown_edit_template.tpl
+++ b/views/document/markdown_edit_template.tpl
@@ -80,12 +80,6 @@
         <div class="editormd-group">
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h1"}}"><i class="fa editormd-bold first" name="h1" unselectable="on">H1</i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h2"}}"><i class="fa editormd-bold item" name="h2" unselectable="on">H2</i></a>
-            <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h3"}}"><i class="fa editormd-bold item" name="h3" unselectable="on">H3</i></a>
-            <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h4"}}"><i class="fa editormd-bold item" name="h4" unselectable="on">H4</i></a>
-            <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h5"}}"><i class="fa editormd-bold item" name="h5" unselectable="on">H5</i></a>
-            <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.h6"}}"><i class="fa editormd-bold last" name="h6" unselectable="on">H6</i></a>
-        </div>
-        <div class="editormd-group">
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.unorder_list"}}"><i class="fa fa-list-ul first" name="list-ul" unselectable="on"></i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.order_list"}}"><i class="fa fa-list-ol item" name="list-ol" unselectable="on"></i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.hline"}}"><i class="fa fa-minus last" name="hr" unselectable="on"></i></a>
@@ -111,10 +105,12 @@
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.modify_history"}}"><i class="fa fa-history item" name="history" aria-hidden="true"></i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.sidebar"}}"><i class="fa fa-columns item" aria-hidden="true" name="sidebar"></i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.help"}}"><i class="fa fa-question-circle-o last" aria-hidden="true" name="help"></i></a>
+            <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.changetheme"}}"><i class="fa fa-paint-brush item" aria-hidden="true" name="changetheme"></i></a>
         </div>
 
         <div class="editormd-group pull-right">
-            <a target="_blank" href="{{urlfor "DocumentController.Read" ":key" .Model.Identify ":id" ""}}" data-toggle="tooltip" data-title="{{i18n .Lang "blog.preview"}}"><i class="fa fa-external-link" name="preview-open" aria-hidden="true"></i></a>
+            <!--<a target="_blank" href="{{urlfor "DocumentController.Read" ":key" .Model.Identify ":id" ""}}" data-toggle="tooltip" data-title="{{i18n .Lang "blog.preview"}}"><i class="fa fa-external-link" name="preview-open" aria-hidden="true"></i></a>-->
+            <a href="{{urlfor "DocumentController.Read" ":key" .Model.Identify ":id" ""}}" data-toggle="tooltip" data-title="{{i18n .Lang "blog.preview"}}"><i class="fa fa-external-link" name="preview-open" aria-hidden="true"></i></a>
             <a href="javascript:;" data-toggle="tooltip" data-title="{{i18n .Lang "doc.publish"}}"><i class="fa fa-cloud-upload" name="release" aria-hidden="true"></i></a>
         </div>
 
diff --git a/views/manager/attach_list.tpl b/views/manager/attach_list.tpl
index e8598e4a..a2aaaa79 100644
--- a/views/manager/attach_list.tpl
+++ b/views/manager/attach_list.tpl
@@ -27,8 +27,9 @@
         {{template "manager/widgets.tpl" .}}
             <div class="page-right">
                 <div class="m-box">
-                    <div class="box-head">
+                    <div class="box-head" id="attachAll">
                         <strong class="box-title">{{i18n .Lang "mgr.attachment_mgr"}}</strong>
+                        <button type="button" data-method="clean" class="btn btn-danger btn-sm" data-loading-text="{{i18n $.Lang "message.processing"}}">{{i18n $.Lang "common.clean"}}</button>
                     </div>
                 </div>
                 <div class="box-body">
@@ -104,6 +105,29 @@
                 }
             });
         });
+
+        $("#attachAll").on("click","button[data-method='clean']",function () {
+            var $this = $(this);
+            $(this).button("loading");
+            $.ajax({
+                url : "{{urlfor "ManagerController.AttachClean"}}",
+                type : "post",
+                dataType : "json",
+                success : function (res) {
+                    if(res.errcode === 0){
+                        alert("done");
+                    }else {
+                        layer.msg(res.message);
+                    }
+                },
+                error : function () {
+                    layer.msg({{i18n .Lang "message.system_error"}});
+                },
+                complete : function () {
+                    $this.button("reset");
+                }
+            });
+        });
     });
 </script>
 </body>