-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.json
More file actions
1 lines (1 loc) · 68.8 KB
/
Copy pathindex.json
File metadata and controls
1 lines (1 loc) · 68.8 KB
1
[{"content":"hugo-theme-zzo 主题启用了Emoji Support\nwindows 7 下使用chrome浏览器只能通过Segoe UI Symbol字体仅显示部分 黑白色 emoji\n(firefox 使用自己的字体渲染可显示彩色emoji)\n可通过安装 Chromoji - Emojis for Google Chrome 扩展使用chrome浏览器达到显示彩色emoji的效果\n右键此扩展可选择 emoji style\n EmojiOne Twitter Apple Google\n ","description":"","id":2,"section":"posts","tags":["hugo"],"title":"chrome 显示 emoji 字体","uri":"https://emacle.github.io/posts/chrome-xian-shi-emoji-zi-ti/"},{"content":"新版本的@vue/cli-service 内置了 yorkie, 见package-lock.json 不再需要额外安装husky\n在安装之后,@vue/cli-service 也会安装 yorkie,它会让你在 package.json 的 gitHooks 字段中方便地指定 Git hook:\n每次它只会在你本地 commit 之前,校验你提交的内容是否符合你本地配置的\neslint规则(这个见文档 ESLint ),如果符合规则,则会提交成功。\n如果不符合它会自动执行 eslint \u0026ndash;fix 尝试帮你自动修复, 注意 .eslintignore 如果包含则会忽略eslint校验\n如果修复成功则会帮你把修复好的代码提交,如果失败,则会提示你错误,让你修好这个错误之后才能允许你提交代码。\n安装后husky/yorkie 它会在我们项目根目录下面的.git/hooks文件夹下面创建pre-commit、pre-push等hooks。可以检查对应的hooks\n这些hooks可以让我们直接在package.json的script里运行我们想要在某个hook阶段执行的命令\n1 npm install lint-staged -D 或者 yarn add lint-staged -D\r 然后修改 package.json,增加配置\n1 2 3 4 5 6 7 8 9 \u0026#34;gitHooks\u0026#34;: {\r\u0026#34;pre-commit\u0026#34;: \u0026#34;lint-staged\u0026#34;\r},\r\u0026#34;lint-staged\u0026#34;: {\r\u0026#34;src/**/*.{js,vue}\u0026#34;: [\r\u0026#34;eslint --fix\u0026#34;,\r\u0026#34;git add\u0026#34;\r]\r}\r https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/git-hook.html#husky\n","description":"","id":3,"section":"posts","tags":["vue","npm","husky","eslint","yorkie"],"title":"Git Hooks 使用 husky/yorkie lint-staged git 提交前进行校验","uri":"https://emacle.github.io/posts/git-hooks-husky-4yorkie-lint-staged/"},{"content":" vscode 安装 vetur,eslint 插件\n使用 vetur 作为vue文件格式化程序, prettier不用安装\n注意 .eslintignore 文件一定不能忽略/src,如果包含则src下面的所有文件都不会使用eslint校验 即使用命令 eslint \u0026ndash;fix src/ 也会忽略\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {\r// 指定vue格式化程序为vetur 只安装vetur时不需要指定,安装有其他格式化插件时如 prettier时需要指定,避免冲突\r\u0026#34;[vue]\u0026#34;: {\r\u0026#34;editor.defaultFormatter\u0026#34;: \u0026#34;octref.vetur\u0026#34;\r},\r// vetur格式化js时默认使用prettier 会在语句后添加;后,最后一个对象元素添加,号\r// 指定 vscode-typescript 或 prettier-eslint可以不添加,; 与eslint保持一致\r\u0026#34;vetur.format.defaultFormatter.js\u0026#34;: \u0026#34;vscode-typescript\u0026#34;,\r\u0026#34;eslint.alwaysShowStatus\u0026#34;: true,\r// 文件保存时, eslint插件集成自动lint修复,不需要再手动执行命令,不能自动修复的代码会报红\r// 注意 .eslintignore 文件一定不能忽略,如果/src则src下面的所有文件保存时不会使用eslint校验\r// 如果不想vscode里面文件报红,可以在.eslintignore 里指定忽略文件,不建议\r\u0026#34;editor.codeActionsOnSave\u0026#34;: {\r// \u0026#34;source.fixAll\u0026#34;: true,\r\u0026#34;source.fixAll.eslint\u0026#34;: true\r}\r}\r 使用vue-element-admin的 .eslintrc.js 配置文件\n需要packages.json devDependencies字段 安装下列包(不仅限于)\n1 npm i -D eslint babel-eslint eslint-plugin-vue\r package.json 增加配置\n1 2 3 \u0026#34;scripts\u0026#34;: {\r\u0026#34;lint\u0026#34;: \u0026#34;eslint --ext .js,.vue src\u0026#34;,\r}\r 校验代码\n1 npm run lint 或 npx eslint --ext .js,.vue src\r 自动修复代码\n1 npm run lint -- --fix # 这里 -- 必须有,因为不是直接执行的eslint命令,或 npx eslint --ext .js,.vue src --fix\r 在执行npm run lint进行代码检测的时候,总是在最后出现npm报错。这个报错并不影响上面显示的lint错误\neslint exits with status 1 if there are any linting errors. npm interprets this as an error, and it\u0026rsquo;s telling you so.\n可以使用-s 参数抑制错误错误 尽量不使用该参数\n1 npm run lint -s\r https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/eslint.html#vscode-%E9%85%8D%E7%BD%AE-eslint\n ","description":"","id":4,"section":"posts","tags":["vue","npm","vscode","vetur","eslint"],"title":"vue vscode 统一代码格式","uri":"https://emacle.github.io/posts/vue-vscode-tong-yi-dai-ma-ge-shi/"},{"content":".gitignore 文件的用途,该文件只能作用于 Untracked Files,也就是那些从来没有被 Git 记录过的文件(自添加以后,从未 add 及 commit 过的文件)。\nHow to ignore files already managed with Git locally\n方法一: git update-index\n1 2 3 4 # 添加/确认/恢复\rgit update-index --skip-worktree path/to/file\rgit ls-files -v | grep ^S\rgit update-index --no-skip-worktree path/to/file\r git ls-files shows all files managed by git.\n-v check the file being ignored.\n\u0026ndash;skip-worktree is displayed with S\n\u0026ndash;skip-worktree 不会提交改动的文件了,但是切换分支的话 git 还是要抱怨你的 worktree 不够干净。此时可以用 git stash 来存取解决这个问题\n方法二: git update-index (推荐,不用管是否切换分支)\n1 2 3 4 # 添加/确认/恢复\rgit update-index --assume-unchanged path/to/file\rgit ls-files -v | grep ^h 或 grep -E \u0026#34;^h\u0026#34;\rgit update-index --no-assume-unchanged path/to/file\r Also, since it is an idea to ignore local changes, git reset - hard command will delete local changes.\n1 2 3 D:\\Q\\code\\CTSC-Vue\u0026gt;git update-index --assume-unchanged vue.config.js\rD:\\Q\\code\\CTSC-Vue\u0026gt;git ls-files -v | grep.exe -E \u0026#34;^h \u0026#34;\rh vue.config.js\r https://segmentfault.com/q/1010000000430426\n","description":"","id":5,"section":"posts","tags":["git"],"title":"git忽略已经被提交的文件","uri":"https://emacle.github.io/posts/git-ignore-file/"},{"content":"使用 base64 编码二进制图片数据,置入 \u0026lt;img\u0026gt; 标签\n1 2 3 4 5 6 7 8 9 \u0026lt;?php\rtry {\r// getDiagram 获得二进制流图片 可显示流程进度\r $diagramBinary = $serviceFactory-\u0026gt;createProcessInstanceService()-\u0026gt;getDiagram($processInstanceId);\r$base64 = \u0026#39;data:image/png\u0026#39; . \u0026#39;;base64,\u0026#39; . base64_encode($diagramBinary); // base64加密二进制图片\r echo \u0026#39;\u0026lt;img src=\u0026#34;\u0026#39; . $base64 . \u0026#39;\u0026#34; /\u0026gt;\u0026#39;; // binary image to base64 so postman can preview image\r} catch (ActivitiException\\ActivitiException $e) {\rvar_dump($e-\u0026gt;getMessage());\r}\r 效果图:\n","description":"","id":6,"section":"posts","tags":["postman"],"title":"postman预览二进制图片","uri":"https://emacle.github.io/posts/postman-preview-image/"},{"content":" 官网下载 activiti-6.0.0.zip 包解压 将wars/目录下 activiti-app.war, activiti-rest.war 包放入apache-tomcat-9.0.30/webapps目录下 1 apache-tomcat-9.0.30/bin/catalina.bat start # 启动 tomcat,stop\r 自动解压war包并布署,webapps/ 下生成两个目录 activiti-app/ , activity-rest/\n activiti-app 会创建用户 admin 密码 test activiti-rest 会创建用户 fozzie gonzo kermit 密码同用户名 测试activiti-app http://localhost:8080/activiti-app/ admin:test 测试activiti-rest http://localhost:8080/activiti-rest/docs/ swagger文档 kermit:kermit\nhttp://kermit:kermit@localhost:8080/activiti-rest/service/management/engine 必须使用用户名密码进行 basic auth 默认使用H2内存数据库,数据不能持久化,mysql库替换,这里使用的mysql库是v8.0.12\n 新建数据库名 activiti6ui\n 下载相应mysql-connector-java-8.0.12.jar包放入apache-tomcat-9.0.30/lib/, 重命名mysql-connector-java.jar 可选\n activiti-app修改mysql连接配置\ncat apache-tomcat-9.0.30\\webapps\\activiti-app\\WEB-INF\\classes\\META-INF\\activiti-app\\activiti-app.properties\n1 2 3 4 5 datasource.driver=com.mysql.jdbc.Driver\rdatasource.url=jdbc:mysql://127.0.0.1:3306/activiti6ui?useUnicode=true\u0026amp;characterEncoding=UTF-8\u0026amp;useSSL=false\u0026amp;autoReconnect=true\u0026amp;failOverReadOnly=false\u0026amp;serverTimezone=GMT%2B8\u0026amp;nullCatalogMeansCurrent=true\rdatasource.username=root\rdatasource.password=root\rhibernate.dialect=org.hibernate.dialect.MySQLDialect\r 注意: \u0026amp;nullCatalogMeansCurrent=true 参数 必须是要带的,否则创建表时会出错 大坑\n activiti-rest修改mysql连接配置\ncat apache-tomcat-9.0.30\\webapps\\activiti-rest\\WEB-INF\\classes\\db.properties\n1 2 3 4 5 db=mysql\rjdbc.driver=com.mysql.jdbc.Driver\rjdbc.url=jdbc:mysql://127.0.0.1:3306/activiti6ui?useUnicode=true\u0026amp;characterEncoding=UTF-8\u0026amp;useSSL=false\u0026amp;autoReconnect=true\u0026amp;failOverReadOnly=false\u0026amp;serverTimezone=GMT%2B8\u0026amp;nullCatalogMeansCurrent=true\rjdbc.username=root\rjdbc.password=root\r 重启 tomcat 部署war包的时候,如果有对应的表则会更新,否则会自动创建所有结构及数据\nactiviti-app 里显示流程图中文显示正常, activiti-rest 使用 \u0026lsquo;runtime/process-instances/{processInstanceId}/diagram\u0026rsquo;\n接口获取流程图状态的时候,中文显示为方框\ngithub下载 activiti-6.0.0 源码解压并使用IDEA 导入\n定位 activiti-6.0.0\\modules\\activiti-image-generator\\src\\main\\java\\org\\activitiℑ\\impl\\DefaultProcessDiagramCanvas.java\n如下图修改字体,然后重新打包成 activiti-image-generator-6.0.0.jar\n替换apache-tomcat-9.0.30\\webapps\\activiti-rest\\WEB-INF\\lib中旧jar包, 效果如下\nsystem_time_zone\ntime_zone SYSTEM\nset global time_zone='+8:00\u0026rsquo;\n","description":"","id":7,"section":"posts","tags":["activiti"],"title":"activiti使用mysql部署及中文不显示解决","uri":"https://emacle.github.io/posts/activiti-shi-yong-mysql-bu-shu-ji-zhong-wen-bu-xian-shi-jie-jue/"},{"content":" 转自 OAuth 2.0 筆記 (4.1) Authorization Code Grant Flow 細節\n在 Authorization Grant Code Flow 裡,Client 不直接向 Resource Owner 要求許可,而是把 Resource Owner 導去\nAuthorization Server 要求許可, Authorization Server 再透過轉址來告訴 Client 授權許可的代碼 (code) 。\n在轉址回去之前, Authorization Server 會先認證 Resource Owner 並取得授權。因為 Resource Owner 只跟\nAuthorization Server 認證,所以 Client 絕對不會拿到 Resource Owner 的帳號密碼。\n 註: (A), (B), (C) 這三步的線拆成兩段,因為會經過 user-agent\n其 Client 指自己的应用程序(包括前端及后端api) User-Agent 一般指流览器\n (D) 步 客户端向 authorization server 发送 auth_code 时(手工封装时) 未带有redirect_uri貌似也能成功最好还是按标准带上该参数? 使用 oauth2-client 包时应该是封装好的 authorization_code 与 前面定义的 redirect_uri 一同发向 authorization server\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \u0026lt;?php\r// composer require league/oauth2-client\r$provider = new \\League\\OAuth2\\Client\\Provider\\GenericProvider([\r\u0026#39;clientId\u0026#39; =\u0026gt; $client_id, // The client ID assigned to you by the provider\r \u0026#39;clientSecret\u0026#39; =\u0026gt; $client_secret, // The client password assigned to you by the provider\r \u0026#39;redirectUri\u0026#39; =\u0026gt; \u0026#39;http://localhost:9527/auth-redirect\u0026#39;,\r\u0026#39;urlAuthorize\u0026#39; =\u0026gt; \u0026#39;https://github.com/login/oauth/authorize\u0026#39;,\r\u0026#39;urlAccessToken\u0026#39; =\u0026gt; \u0026#39;https://github.com/login/oauth/access_token\u0026#39;,\r\u0026#39;urlResourceOwnerDetails\u0026#39; =\u0026gt; \u0026#39;https://api.github.com/user\u0026#39;\r]);\r// getAccessToken 时应该带有 redirect_uri?\r// http://localhost:9527/auth-redirect?code=8789d613d1fa9a19732a\u0026amp;state=xyz\r$accessToken = $provider-\u0026gt;getAccessToken(\u0026#39;authorization_code\u0026#39;, [\r\u0026#39;code\u0026#39; =\u0026gt; $code\r]);\r 转自 github 授权登录教程与如何设计第三方授权登录的用户表 流程图 ","description":"","id":8,"section":"posts","tags":["oauth"],"title":"OAuth 2 Authorization Code Grant Flow","uri":"https://emacle.github.io/posts/oauth-2-authorization-code-grant-flow/"},{"content":" Github 网站创建 OAuth Apps 记录 Client ID / Client Secret / Authorization Callback URL 3个参数\n此处 Authorization Callback URL 为默认回调网址,程序代码里没有明确指定的话,以此为默认值,代码里指定的话\n指定的redirect 一定要与此处一致防止提交时校验出错 ip/域名都可,在弹出子窗口进行授权确定时,三方服务器会校验\nurl里的redirect参数(程序里指定的)与创建三方应用里指定的 callback 地址,如果不一致会出错\n1 2 3 4 http://host:port/auth-redirect # 必须与创建应用时填入值一致\rhttp://localhost:9527/auth-redirect\rhttp://172.17.1.110:10000/auth-redirect\rhttp://www.vueauth.org:10000/auth-redirect # 浏览器的主机 hosts/dns 里需要解析 www.vueauth.org\r socialsignin.vue 三方登录模块里,构造弹出窗口 github 认证 url\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 githubHandleClick(thirdpart) {\r// 1. 指定授权 client_id 及 redirect_uri 的 URL\r // 如果不指定 redirect_uri, 则默认使用 gihtub =\u0026gt; Settings =\u0026gt; Developer settings =\u0026gt; OAuth Apps 里 Authorization callback URL 配置的地址\r // 为了无歧义尽量在程序代码里指定redirect_uri\r // const url = \u0026#39;https://github.com/login/oauth/authorize?client_id=94aae05609c96ffb7d3b\u0026amp;redirect_uri=http://localhost:9527/auth-redirect\u0026#39;\r githubAuth().then(response =\u0026gt; { // githubAuth() 参数 code 为空,由后端返回 authorize_url\r // 2. 弹出子窗口进行授权, 子窗口完成授权后, 子窗口地址栏URL 会是 redirect_uri 并带上 ?code= 参数与\u0026amp;state= 参数\r // 子窗口单击确定按钮授权时,会校验此时的redirect 与 创建三方应用时填写的 callback 不一致会出错\r const url = response.data.auth_url\r// console.log(\u0026#39;auth url....\u0026#39;, url)\r // =\u0026gt; https://github.com/login/oauth/authorize?state=137caabc2b409f0cccd14834fc848041\u0026amp;response_type=code\u0026amp;approval_prompt=auto\u0026amp;redirect_uri=http://localhost:9527/auth-redirect\u0026amp;client_id=94aae05609c96ffb7d3b\r openWindow(url, thirdpart, 540, 540)\r}).catch(error =\u0026gt; {\rconsole.log(error)\r})\r}\r authredirect.vue 里,即第2步url参数 redirect_uri 指定的回调地址对应的路由组件(/auth-redirect),在此弹出的子窗口里进行授权,授权完成后,调用js 的 window.opener 方法 给 父窗口 的 location.href 赋值,父窗口地址栏变为 会带有 github 返回的 ?code 参数,同时关闭子窗口,代码逻辑转至父窗口进行后续处理\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 name: \u0026#39;AuthRedirect\u0026#39;,\rcreated() {\rthis.githubLogin()\r},\rmethods: {\rgithubLogin() {\r// 1. 授权成功后, github 返回给 AuthRedirect子窗口的浏览器 回调地址 并带上 ?code=8789d613d1fa9a19732a\u0026amp;state=xyz 参数\r // 地址栏URL如 http://localhost:9527/auth-redirect?code=8789d613d1fa9a19732a\u0026amp;state=xyz\r // 其中 http://localhost:9527/auth-redirect 是定义 githubHandleClick() 里定义或服务端返回的回调地址\r // const url = \u0026#39;https://github.com/login/oauth/authorize?client_id=94aae05609c96ffb7d3b\u0026amp;redirect_uri=http://localhost:9527/auth-redirect\u0026#39;\r // 此时 window.location.href =\u0026gt; http://localhost:9527/auth-redirect?code=8789d613d1fa9a19732a\u0026amp;state=137caabc2b409f0cccd14834fc848041\r // window.location.search =\u0026gt; ?code=8789d613d1fa9a19732a\u0026amp;state=137caabc2b409f0cccd14834fc848041\r\r// 2. 调用 window.opener 方法 给 父窗口 的 location.href 赋值 =\u0026gt; http://localhost:9527/login?code=8789d613d1fa9a19732a\r window.opener.location.href = window.location.origin + \u0026#39;/login\u0026#39; + window.location.search\r// 注意:此处加入 /login 是因为 router /login 在 permission.js的whiteLis里不会发生重定向而导致href里丢失?code等参数,从而\r // 可以在login/index.vue里直接通过location或vue route 获取code,state参数,不必在permission.js里获取并保存至store里\r // ***非常关键***,不加的话默认/ 是等价于/dashboard不在白名单里路由根据permission.js逻辑会发生重定向至/login里此时会丢失?code等参数\r // 可在此 使用未定义的变量 来 debug // Error in created hook: \u0026#34;ReferenceError: hash is not defined\u0026#34; found in window.opener.location.href = window.location.origin + \u0026#39;?\u0026#39; + hash\r // 3. 关闭 AuthRedirect 子窗口。同时代码逻辑至父窗口 在 permission.js =\u0026gt; router.beforeEach 进行 code 处理\r window.close()\r}\r}\r login/index.vue 代码逻辑转至此处, created 生命周期里,判断 如果存在则为github三方登录,前端调用githubAuth 函数带code参数向后台进行认证正确后会返回给前面 token/refresh_token,前面配置token正确后却可正常登录 (与后端交互时可加入三方登录loading动画效果提示)\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 created() {\rthis.githubLogin()\r},\rmethods: {\rgithubLogin() {\r// console.log(\u0026#39;in login/index.vue....\u0026#39;, window.location, this.$route, this.$router)\r // 获取三方登录 code\r // 更可靠稳定的获取code方法 使用 vue router to 对象来获取\r // 如果路由存在code 与 state 参数,如http://localhost:9527/login?code=8789d613d1fa9a19732a\u0026amp;state=xyz\r if (this.$route.query.hasOwnProperty(\u0026#39;code\u0026#39;) \u0026amp;\u0026amp; this.$route.query.hasOwnProperty(\u0026#39;state\u0026#39;)) { // this.$route.query 如果存在 code 则为三方登录则写入store 变量\r const code = this.$route.query.code\rconst state = this.$route.query.state\rconsole.log(\u0026#39;github code: \u0026#39;, code)\rconsole.log(\u0026#39;github state: \u0026#39;, state)\r// store.state.user.code = code\r // store.state.user.code_state = state\r // console.log(store.state.user) // 该code 在store/modules/user.js 里定义有 作为第三方登录使用 参见其中 LoginByThirdparty\r\rthis.thirdLogin = true\rconst loading = this.$loading({\rlock: true,\rtext: \u0026#39;github 认证登录中...\u0026#39;,\rspinner: \u0026#39;el-icon-loading\u0026#39;,\rbackground: \u0026#39;rgba(0, 0, 0, 0.7)\u0026#39;\r})\rconst authParms = { code, state }\r// 执行 GET githubAuth 根据 code 获取 github userinfo 结合业务逻辑生成 token / refreshtoken (jwt)\r this.$store.dispatch(\u0026#39;githubAuth\u0026#39;, authParms).then(() =\u0026gt; {\rthis.$router.push({ path: \u0026#39;/\u0026#39; })\rloading.close()\r}).catch((err) =\u0026gt; {\rconsole.log(\u0026#39;this.$store.dispatchgithubAuth catch....\u0026#39;, err.response)\rthis.thirdLogin = false\rloading.close()\r}).finally((e) =\u0026gt; {\rconsole.log(\u0026#39;this.$store.dispatchgithubAuth finally....\u0026#39;, e)\rthis.thirdLogin = false\rloading.close()\r})\r}\r}\r}\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // github认证\rgithubAuth({ commit }, authParms) {\rreturn new Promise((resolve, reject) =\u0026gt; {\rgithubAuth(authParms.code, authParms.state).then(response =\u0026gt; {\rconsole.log(\u0026#39;githubAuth response...\u0026#39;, response)\rconst data = response.data\rcommit(\u0026#39;SET_TOKEN\u0026#39;, data.token)\rcommit(\u0026#39;SET_REFRESH_TOKEN\u0026#39;, data.refresh_token)\rsetToken(data.token)\rsetRefreshToken(data.refresh_token)\rresolve()\r}).catch(error =\u0026gt; {\rreject(error)\r})\r})\r},\r// github 认证api\rexport function githubAuth(code) {\rreturn request({\rurl: \u0026#39;/sys/user/githubauth\u0026#39;,\rmethod: \u0026#39;get\u0026#39;,\rparams: { code }\r})\r}\r 后端php /sys/user/githubauth 接口, 引用 league/oauth2-client 包生成 授权链接 根据code与github进行交互,主要有获取github access_token 与 获取github userinfo\n后端也可以自动封装函数来获取github交互信息 (如果是php可利用composer安装一些三方登录插件错误校验比较完善,一般需要php开启 开启php.ini中的session.auto_start配置 使用session,\n测试 league/oauth2-client 包没有开启 php session 也可以使用 $_SESSION['oauth2state'] 变量,也可以 redis 替换)\nhttps://oauth2-client.thephpleague.com/providers/league/ 可在此网站查找部分官方包及第三方封装的 leageue php 登录包\n1 2 3 4 5 # league/oauth2-client 是通用客户端 github,gitee ok!!!\r# In most cases, you\u0026#39;ll want to use a specific provider client library rather than this base library.\rcomposer require league/oauth2-github # github ok!!!\rcomposer require spoonwep/oauth2-qq # QQ OAuth 2.0 support for the PHP League\u0026#39;s OAuth 2.0 Client\rcomposer require oakhope/oauth2-wechat # 未测试\r oauth2-client 包官方 demo 捕获异常时 指定IdentityProviderException 不能捕获其依赖包 guzzlehttp 里的错误异常 使用 Exception $e 替换\n1 GuzzleHttp\\Exception\\ConnectException Message: cURL error 35: OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.github.com:443\r \r1 2 3 4 5 6 7 8 9 \u0026lt;?php\rtry{\r# getaccessToken...\r # get userinfo...\r //} catch (\\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException $e) {\r} catch (Exception $e) {\r// Failed to get the access token or user details.\r exit($e-\u0026gt;getMessage());\r}\r vue路由模式最好使用history, hash模式的话url中的#字符认证中转时不太好处理,history模式在 生产环境 中需要配置后端服务器支持(此后端为vue编译生成的静态网页面代码部署的服务器,如 apache route history mode配置参考 , 并不是后端接口的服务器 )\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @router/index.js\rexport default new Router({\rmode: \u0026#39;history\u0026#39;, // require service support 前端部署的时候 apache 需要配置文件 .htaccess\rscrollBehavior: () =\u0026gt; ({ y: 0 }),\rroutes: constantRouterMap\r})\r@dist/.htaccess // 防止直接刷新页面服务端会直接报 404 错误。\r\u0026lt;IfModule mod_rewrite.c\u0026gt;\rRewriteEngine On\rRewriteBase /\rRewriteRule ^index\\.html$ - [L]\rRewriteCond %{REQUEST_FILENAME} !-f\rRewriteCond %{REQUEST_FILENAME} !-d\rRewriteRule . /index.html [L]\r\u0026lt;/IfModule\u0026gt;\r 完整代码 https://github.com/emacle/vue-php-admin\n 其它问题\n cURL error 60: SSL certificate problem: unable to get local issuer certifica 解决\n从 https://curl.haxx.se/docs/caextract.html 上下载cacert.pem\n1 2 3 # vi php.ini 搜索curl.cainfo 与 openssl.cafile,将其配置成你自己cacert.pem文件的路径\rcurl.cainfo=\u0026#34;D:\\phpstudy_pro\\Extensions\\php\\php7.3.4nts\\extras\\ssl\\cacert.pem\u0026#34;\ropenssl.cafile=\u0026#34;D:\\phpstudy_pro\\Extensions\\php\\php7.3.4nts\\extras\\ssl\\cacert.pem\u0026#34;\r OAuth 2.0 筆記 (4.1) Authorization Code Grant Flow 細節\n github 登录报错 回调地址不一致出错提示 github 与 gitee 不太一样\n1 github 在地址栏提示\r http://localhost:9527/auth-redirect?error=redirect%5Furi%5Fmismatch\u0026amp;error%5Fdescription=The redirect_uri MUST match the registered callback URL for this application.\u0026amp; error_uri=https://developer.github.com/apps/managing-oauth-apps/troubleshooting-authorization-request-errors/#redirect-uri-mismatch%23/auth-redirect\n1 gitee 提示子窗口显示 回调地址有误\r ","description":"","id":9,"section":"posts","tags":["vue","element","github","oauth"],"title":"Vue Element-ui Github oAuth 三方登录","uri":"https://emacle.github.io/posts/vue-element-ui-github-oauth-san-fang-deng-lu/"},{"content":"Markdownify box This is boxmd shortcode Simple box This is **box** shortcode\r Code tabs Make it easy to switch between different code\njava\rjavascript\r\r1 System.out.println(\u0026#39;Hello World!\u0026#39;);\r \r\r1 console.log(\u0026#39;Hello World!\u0026#39;);\r \r\r\r\r'use strict';\rvar containerId = JSON.parse(\"\\\"c3a7395d19726e47\\\"\");\rvar containerElem = document.getElementById(containerId);\rvar codetabLinks = null;\rvar codetabContents = null;\rvar ids = [];\rif (containerElem) {\rcodetabLinks = containerElem.querySelectorAll('.codetab__link');\rcodetabContents = containerElem.querySelectorAll('.codetab__content');\r}\rfor (var i = 0; i 0) {\rcodetabContents[0].style.display = 'block';\r}\r Tabs for general purpose Windows\rMacOS\rUbuntu\r\rWindows section 1 console.log(\u0026#39;Hello World!\u0026#39;);\r ⚠️Becareful that the content in the tab should be different from each other. The tab makes unique id hashes depending on the tab contents. So, If you just copy-paste the tabs with multiple times, since it has the same contents, the tab will not work.\n\rMacOS section Hello world!\r\rUbuntu section Great!\r\r\r\r'use strict';\rvar containerId = JSON.parse(\"\\\"5c92b60c8ec7870a\\\"\");\rvar containerElem = document.getElementById(containerId);\rvar tabLinks = null;\rvar tabContents = null;\rvar ids = [];\rif (containerElem) {\rtabLinks = containerElem.querySelectorAll('.tab__link');\rtabContents = containerElem.querySelectorAll('.tab__content');\r}\rfor (var i = 0; i 0) {\rtabContents[0].style.display = 'block';\r}\r Expand \r\rExpand me\r\rTitle contents\r\r \r\rExpand me2\r\rTitle2 contents2\r\r Alert Colored box\nthis is a text\rthis is a text\rthis is a text\rthis is a text\rNotice success text\r info text\r warning text\r error text\r ","description":"tabs, code-tabs, expand, alert, warning, notice, img, box","id":10,"section":"posts","tags":["shortcode"],"title":"Shortcodes","uri":"https://emacle.github.io/posts/shortcodes/"},{"content":"过期刷新流程图:\n思路:\n 登录时, 后端生成 access_token, refresh_token 返回前端, 前端保存两个token在 cookie或localstorge中\n 当前端发送正常请求时,请求头字段携带 access_token , 后端提取该 access_token\n 判断是否过期, 不过期则返回 HTTP 200 OK 过期返回 HTTP_UNAUTHORIZED 401, 并且加上自定义响应数据 code = 50014 表示access_token 过期 VUE前端使用 响应拦截器 , 对收到的 HTTP 401 进行拦截, 如果 http 401 且 code =50014 则先以 refresh_token\n去获取新 access_token\n 如果正常获得 access_token, 则再次以新 access_token 发送原请求, 即可实现无缝刷新 如果 refresh_token 也过期, 则服务器也返回 401, 但是加上了自定义响应数据 code= 50015, 前端的响应拦截器\n再次捕获到 error , 校验code =50015后, 则强制退出需要重新登录 \r1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 // response interceptor\rservice.interceptors.response.use(\rresponse =\u0026gt; {\rconst res = response.data\r// 一些处理...\r return response.data\r},\rerror =\u0026gt; {\r// http 401 只能在 error 里被截获\r // console.log(error) *** 控制台不能输出返回的响应数据 ***\r // console.log(error.response) *** 可使用此命令进行调试 ***\r if (error.response.status === 401 \u0026amp;\u0026amp; error.response.data.code === 50014) {\r// message: \u0026#39;access_token过期,自动续期\u0026#39;, code = 50014 access_token 过期\r return againRequest(error) // 此函数先以refresh_token 去获取新access_token, 然后再次以新 access_token 发送原请求\r }\r// 这里是 code = 50015 refresh_token 也过期的情况\r if (error.response.status === 401 \u0026amp;\u0026amp; error.response.data.code === 50015) {\r// message: \u0026#39;refresh_token过期,重定向登录\u0026#39;, code = 50015 refresh_token 过期\r console.log(\u0026#39;refresh_token过期 超时......\u0026#39;)\rMessageBox.confirm(\u0026#39;你已被登出,可以取消继续留在该页面,或者重新登录\u0026#39;, \u0026#39;确定登出\u0026#39;, {\rconfirmButtonText: \u0026#39;重新登录\u0026#39;,\rcancelButtonText: \u0026#39;取消\u0026#39;,\rtype: \u0026#39;warning\u0026#39;\r}).then(() =\u0026gt; {\rstore.dispatch(\u0026#39;FedLogOut\u0026#39;).then(() =\u0026gt; {\rlocation.reload() // 为了重新实例化vue-router对象 避免bug\r })\r})\r}\rreturn Promise.reject(error)\r}\r) // response 拦截结束\r\rasync function againRequest(error) {\rawait store.dispatch(\u0026#39;handleCheckRefreshToken\u0026#39;) // 同步以获取刷新 access_token 并且保存在 cookie/localstorage\r const config = error.response.config\rconfig.headers[\u0026#39;X-Token\u0026#39;] = getToken() // 以新的 access_token\r const res = await axios.request(config) // 重新进行原请求\r return res.data // 以error.response.config重新请求返回的数据包是在函数内是 被封装在data里面\r}\r 第3步以 refresh_token 去获取 access_token 时, 必须在 请求拦截器 里重新配置请求头, 以 refresh_token 作为新的 token 头\n否则后端token认证判断还是原过期的 access_token\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // request interceptor\rservice.interceptors.request.use(\rconfig =\u0026gt; {\r// Do something before request is sent\r if (store.getters.token) {\r// 让每个请求携带token-- [\u0026#39;X-Token\u0026#39;]为自定义key 请根据实际情况自行修改\r config.headers[\u0026#39;X-Token\u0026#39;] = getToken()\r}\r// 监听是否 /sys/user/refreshtoken 是则重置token为 refresh_token\r const url = config.url\rif (url.split(\u0026#39;/\u0026#39;).pop() === \u0026#39;refreshtoken\u0026#39;) {\r// console.log(\u0026#39;config.url\u0026#39;, config.url, getRefreshToken())\r config.headers[\u0026#39;X-Token\u0026#39;] = getRefreshToken() // 登录时本地 cookie/localstorage 存储的\r }\rreturn config\r},\rerror =\u0026gt; {\r// Do something with request error\r console.log(error) // for debug\r Promise.reject(error)\r}\r)\r 1 用户编辑时比较有用, 防止长时间编辑后提交时 access_token 过期, 导致编辑内容丢失\r 完整代码 https://github.com/emacle/vue-php-admin\n VUE 请求拦截器与响应拦截器代码修改自 vue-element-admin 中的 request.js\n 参考: php firebase/php-jwt token验证\n","description":"","id":11,"section":"posts","tags":["vue","jwt","token"],"title":"vue token过期无缝刷新","uri":"https://emacle.github.io/posts/vue-token-guo-qi-wu-feng-shua-xin/"},{"content":"Hugo 以 theme 中的静态模板文件来生成静态css文件\n favicon 图标\n1 2 3 4 5 [params]\r# 自定义 favicon 变量 ~/hugo/static/favicon.ico -\u0026gt; /public/favicon.ico\r# ~/hugo/static/ 目录下的东西会自动发布到时 /public 根目录 i.e. ox-hugo/ orgmode 导出的静态图片\r# 使用绝对路径 防止 /posts/ 页面404 favicon\rfavicon = \u0026#34;https://emacle.github.io/favicon.ico\u0026#34;\r head.html 模板头部加入\n1 \u0026lt;link rel=\u0026#34;icon\u0026#34; href=\u0026#34;{{ .Site.Params.favicon }}\u0026#34;\u0026gt;\r 启用 github utterances 评论, 修改.Type 变量, ox-hugo默认导出目录为 \u0026lt;HUGO_BASE_DIR\u0026gt;/content/posts/ 因此 .Type = \u0026ldquo;posts\u0026rdquo;\n1 cat ~/hugo/themes/hugo-dusk/layouts/partials/postfooter.html\r \r1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 \u0026lt;footer class=\u0026#34;post-footer\u0026#34;\u0026gt;\r\u0026lt;div class=\u0026#34;post-footer-data\u0026#34;\u0026gt;\r{{ partial \u0026#34;tags.html\u0026#34; . }}\r\u0026lt;!-- 修改默认日期显示格式 --\u0026gt;\r\u0026lt;!-- \u0026lt;div class=\u0026#34;date\u0026#34;\u0026gt; {{ .Date.Format \u0026#34;2006-01-01\u0026#34; }} \u0026lt;/div\u0026gt; --\u0026gt;\r\u0026lt;div class=\u0026#34;date\u0026#34;\u0026gt; {{ .Date.Format \u0026#34;Mon, 02 Jan 2006 15:04:05 MST\u0026#34; }} \u0026lt;/div\u0026gt;\r{{if or .Params.categories .Params.series}}\r\u0026lt;hr\u0026gt;\r{{ partial \u0026#34;categories.html\u0026#34; . }}\r{{ partial \u0026#34;series.html\u0026#34; . }}\r{{end}}\r\u0026lt;/div\u0026gt;\r\u0026lt;/footer\u0026gt;\r\u0026lt;!-- .Type 变量 自动分配或继承前端 https://gohugo.io/variables/page/ Page Variables .Type --\u0026gt;\r\u0026lt;!-- new file created at content/posts/new-post.md will automatically be assigned the type posts --\u0026gt;\r\u0026lt;!-- 测试 .Type 变量输出 以双大括号 变量输出 --\u0026gt;\r\u0026lt;!-- if eq .Type \u0026#34;post\u0026#34; --\u0026gt;\r{{ if eq .Type \u0026#34;posts\u0026#34; }}\r{{ template \u0026#34;_internal/disqus.html\u0026#34; . }}\r{{ template \u0026#34;partials/utterances.html\u0026#34; . }}\r{{ end }}\r 代码高亮\n1 2 3 4 5 6 # Configure syntax highlight\r# The Chroma php lexer doesn’t support a startinline option. You’ll have to add a starting \u0026lt;?php tag or use Pygments.\r# php 语言高亮需要加入 \u0026lt;?php 标记才能正常高亮\r[markup]\r[markup.highlight]\rstyle = \u0026#34;paraiso-dark\u0026#34; # dark themes: emacs, vi, vs, paraiso-dark,monokai, api, fruity, native, rrt, swapoff https://xyproto.github.io/splash/docs/all.html\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 \u0026lt;?php\r$provider = new \\League\\OAuth2\\Client\\Provider\\GenericProvider([\r\u0026#39;clientId\u0026#39; =\u0026gt; \u0026#39;demoapp\u0026#39;, // The client ID assigned to you by the provider\r \u0026#39;clientSecret\u0026#39; =\u0026gt; \u0026#39;demopass\u0026#39;, // The client password assigned to you by the provider\r \u0026#39;redirectUri\u0026#39; =\u0026gt; \u0026#39;http://example.com/your-redirect-url/\u0026#39;,\r\u0026#39;urlAuthorize\u0026#39; =\u0026gt; \u0026#39;http://brentertainment.com/oauth2/lockdin/authorize\u0026#39;,\r\u0026#39;urlAccessToken\u0026#39; =\u0026gt; \u0026#39;http://brentertainment.com/oauth2/lockdin/token\u0026#39;,\r\u0026#39;urlResourceOwnerDetails\u0026#39; =\u0026gt; \u0026#39;http://brentertainment.com/oauth2/lockdin/resource\u0026#39;\r]);\r// If we don\u0026#39;t have an authorization code then get one\rif (!isset($_GET[\u0026#39;code\u0026#39;])) {\r// Fetch the authorization URL from the provider; this returns the\r // urlAuthorize option and generates and applies any necessary parameters\r // (e.g. state).\r $authorizationUrl = $provider-\u0026gt;getAuthorizationUrl();\r// Get the state generated for you and store it to the session.\r $_SESSION[\u0026#39;oauth2state\u0026#39;] = $provider-\u0026gt;getState();\r// Redirect the user to the authorization URL.\r header(\u0026#39;Location: \u0026#39; . $authorizationUrl);\rexit;\r// Check given state against previously stored one to mitigate CSRF attack\r} elseif (empty($_GET[\u0026#39;state\u0026#39;]) || (isset($_SESSION[\u0026#39;oauth2state\u0026#39;]) \u0026amp;\u0026amp; $_GET[\u0026#39;state\u0026#39;] !== $_SESSION[\u0026#39;oauth2state\u0026#39;])) {\rif (isset($_SESSION[\u0026#39;oauth2state\u0026#39;])) {\runset($_SESSION[\u0026#39;oauth2state\u0026#39;]);\r}\rexit(\u0026#39;Invalid state\u0026#39;);\r} else {\rtry {\r// Try to get an access token using the authorization code grant.\r $accessToken = $provider-\u0026gt;getAccessToken(\u0026#39;authorization_code\u0026#39;, [\r\u0026#39;code\u0026#39; =\u0026gt; $_GET[\u0026#39;code\u0026#39;]\r]);\r// We have an access token, which we may use in authenticated\r // requests against the service provider\u0026#39;s API.\r echo \u0026#39;Access Token: \u0026#39; . $accessToken-\u0026gt;getToken() . \u0026#34;\u0026lt;br\u0026gt;\u0026#34;;\recho \u0026#39;Refresh Token: \u0026#39; . $accessToken-\u0026gt;getRefreshToken() . \u0026#34;\u0026lt;br\u0026gt;\u0026#34;;\recho \u0026#39;Expired in: \u0026#39; . $accessToken-\u0026gt;getExpires() . \u0026#34;\u0026lt;br\u0026gt;\u0026#34;;\recho \u0026#39;Already expired? \u0026#39; . ($accessToken-\u0026gt;hasExpired() ? \u0026#39;expired\u0026#39; : \u0026#39;not expired\u0026#39;) . \u0026#34;\u0026lt;br\u0026gt;\u0026#34;;\r// Using the access token, we may look up details about the\r // resource owner.\r $resourceOwner = $provider-\u0026gt;getResourceOwner($accessToken);\rvar_export($resourceOwner-\u0026gt;toArray());\r// The provider provides a way to get an authenticated API request for\r // the service, using the access token; it returns an object conforming\r // to Psr\\Http\\Message\\RequestInterface.\r $request = $provider-\u0026gt;getAuthenticatedRequest(\r\u0026#39;GET\u0026#39;,\r\u0026#39;http://brentertainment.com/oauth2/lockdin/resource\u0026#39;,\r$accessToken\r);\r} catch (\\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException $e) {\r// Failed to get the access token or user details.\r exit($e-\u0026gt;getMessage());\r}\r}\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (use-package magit\r:ensure t\r:about A Git porcelain inside Emacs\r:homepage https://github.com/magit/magit\r:info (info \u0026#34;(magit) Top\u0026#34;)\r:bind ((\u0026#34;C-x g\u0026#34; . magit-status))\r:hook (company-mode . company-box-mode)\r:config\r(setq-default magit-diff-refine-hunk t)\r(setq magit-save-repository-buffers \u0026#39;dontask)\r;; M-x `magit-list-repositories\u0026#39;\r (setq magit-repository-directories\r\u0026#39;((\u0026#34;~/.emacs.d\u0026#34; . 0)\r(\u0026#34;~/.emacs.d/straight/repos\u0026#34; . 1)\r(\u0026#34;~/src\u0026#34; . 1))))\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #!/bin/bash\r# 以下配置信息请自己修改\rmysql_user=\u0026#34;USER\u0026#34; #MySQL备份用户\rmysql_password=\u0026#34;PASSWORD\u0026#34; #MySQL备份用户的密码\rmysql_host=\u0026#34;localhost\u0026#34;\rmysql_port=\u0026#34;3306\u0026#34;\rmysql_charset=\u0026#34;utf8\u0026#34; #MySQL编码\rbackup_db_arr=(\u0026#34;db1\u0026#34; \u0026#34;db2\u0026#34;) #要备份的数据库名称,多个用空格分开隔开 如(\u0026#34;db1\u0026#34; \u0026#34;db2\u0026#34; \u0026#34;db3\u0026#34;)\rbackup_location=/opt/mysql #备份数据存放位置,末尾请不要带\u0026#34;/\u0026#34;,此项可以保持默认,程序会自动创建文件夹\rexpire_backup_delete=\u0026#34;ON\u0026#34; #是否开启过期备份删除 ON为开启 OFF为关闭\rexpire_days=3 #过期时间天数 默认为三天,此项只有在expire_backup_delete开启时有效\r# 连接到mysql数据库,无法连接则备份退出\rmysql -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password \u0026lt;\u0026lt;end\ruse mysql;\rselect host,user from user where user=\u0026#39;root\u0026#39; and host=\u0026#39;localhost\u0026#39;;\rexit\rend\rflag=`echo $?`\rif [ $flag != \u0026#34;0\u0026#34; ]; then\recho \u0026#34;ERROR:Can\u0026#39;t connect mysql server! backup stop!\u0026#34;\rexit\relse\recho \u0026#34;All database backup success! Thank you!\u0026#34;\rexit\rfi\r 页面底部 \u0026ldquo;Powered by\u0026rdquo; 没有参数可配置取消, 可grep定位文件位置 注释掉\n1 cat ~/hugo/themes/hugo-dusk/layouts/partials/footer.html\r copyright 部分可以 config.toml 里配置后启用\n1 copyright = \u0026#34;Copyright (c) 2020, all rights reserved.\u0026#34;\r ","description":"","id":12,"section":"posts","tags":["hugo","utterances","theme"],"title":"hugo-dusk theme 模板,utterances评论修改","uri":"https://emacle.github.io/posts/hugo-dusk-theme/"},{"content":" elpa 安装 ox-hugo\n 优先使用基于子树模式 两个必填 \u0026lt;hugo_base_dir\u0026gt; 与 EXPORT_FILE_NAME\n org 文件头 设置配置 #+hugo_base_dir 参数指向 hugo 工程目录\n1 #+hugo_base_dir: ../hugo\r subtree 属性必须要设置 EXPORT_FILE_NAME 即slug 不可重复, 作为导出的 .md 文件名\n1 :EXPORT_FILE_NAME: hugo-with-orgmode\r 导出sub-tree到 \u0026lt;HUGO_BASE_DIR\u0026gt;/content/posts/\n1 C-c e H H 或 C-c e H O\r 子树如果是 DONE 则 会直接发布, 如果是 TODO 则会做为草稿\n Sub-tree 属性 EXPORT_HUGO_TAGS 与 EXPORT_HUGO_CATEGORIES\n 多个参数以 空格 分隔\n 会覆盖 orgmode 里的 tags 属性, 留空或不设置则会继承 orgmode tags\n 以 @ 开头的 orgmode tags 可表示 CATEGORIES\n \r1 2 :EXPORT_HUGO_TAGS: hugo haha\r:EXPORT_HUGO_CATEGORIES: orgmode emacs\r 可不用使用 CATEGORIES 能与 orgmode 保持一致, 前端配置可去除该链接\nEXPORT_HUGO_TAGS 也可以留空, 只使用org tags 方式\n属性插入可编写 yasnippet , 利用自定义函数 hugoslug-to-pinyin, 插入时自动将\nhead title里的中文转换成拼音\n org本地图片可以无描述插入可直接导出正确的url格式\n1 [[file:images/80px-Heckert_GNU_white.svg.png]] 描述为空不能单击图片链接\r 1 [[desc][link]] 描述不为空 图片可单击打开,i.e. (org-store-link) 保存的链接\r 1 [[https://raw.githubusercontent.com/emacle/picgo/master/img/icon_a.png]] 远程 image url\r 1 MiniCap.exe 截图 / FastStone 简单特效/标注/绘画马赛克/文字放大镜/中心聚光模糊效果 / picpick.exe 卡\r 1 2 3 4 5 6 7 8 # 1.初始化一个hugo工程目录\rhugo new site mysite\r# 2. 必须在 mysite/themes 里 git 下载主题 如无mysite/themes目录 则手动创建\r# 3. cd mysite 测试\r# \u0026gt; hugo.exe new posts/my-first.md 生成 .md -\u0026gt; 编辑\rhugo.exe serve\r# 4. 发布, 在hugo文件夹下自动生成一个public文件夹 将public托管 -b 指定baseURL\rhugo.exe -b https://emacle.github.io/\r ","description":"","id":13,"section":"posts","tags":["hugo"],"title":"Hugo with OrgMode","uri":"https://emacle.github.io/posts/hugo-with-orgmode/"},{"content":"This article offers a sample of basic Markdown syntax that can be used in Hugo content files, also it shows whether basic HTML elements are decorated with CSS in a Hugo theme.\nHeadings The following HTML \u0026lt;h1\u0026gt;—\u0026lt;h6\u0026gt; elements represent six levels of section headings. \u0026lt;h1\u0026gt; is the highest section level while \u0026lt;h6\u0026gt; is the lowest.\nH1 H2 H3 H4 H5 H6 Paragraph Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.\nItatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.\nBlockquotes The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a footer or cite element, and optionally with in-line changes such as annotations and abbreviations.\nBlockquote without attribution Tiam, ad mint andaepu dandae nostion secatur sequo quae.\nNote that you can use Markdown syntax within a blockquote.\n Blockquote with attribution Don\u0026rsquo;t communicate by sharing memory, share memory by communicating.\n— Rob Pike1\n Tables Tables aren\u0026rsquo;t part of the core Markdown spec, but Hugo supports supports them out-of-the-box.\n Name Age Bob 27 Alice 23 Inline Markdown within tables Inline Markdown In Table italics bold strikethrough code Code Blocks Code block with backticks html\r\u0026lt;!DOCTYPE html\u0026gt;\r\u0026lt;html lang=\u0026quot;en\u0026quot;\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;meta charset=\u0026quot;UTF-8\u0026quot;\u0026gt;\r\u0026lt;title\u0026gt;Example HTML5 Document\u0026lt;/title\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;p\u0026gt;Test\u0026lt;/p\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt;\rCode block indented with four spaces \u0026lt;!DOCTYPE html\u0026gt;\r\u0026lt;html lang=\u0026quot;en\u0026quot;\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;meta charset=\u0026quot;UTF-8\u0026quot;\u0026gt;\r\u0026lt;title\u0026gt;Example HTML5 Document\u0026lt;/title\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;p\u0026gt;Test\u0026lt;/p\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt;\r Code block with Hugo\u0026rsquo;s internal highlight shortcode 1 2 3 4 5 6 7 8 9 10 \u0026lt;!DOCTYPE html\u0026gt;\r\u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt;\r\u0026lt;title\u0026gt;Example HTML5 Document\u0026lt;/title\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;p\u0026gt;Test\u0026lt;/p\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt; List Types Ordered List First item Second item Third item Unordered List List item Another item And another item Nested list Item First Sub-item Second Sub-item Other Elements — abbr, sub, sup, kbd, mark GIF is a bitmap image format.\nH2O\nXn + Yn: Zn\nPress CTRL+ALT+Delete to end the session.\nMost salamanders are nocturnal, and hunt for insects, worms, and other small creatures.\n The above quote is excerpted from Rob Pike\u0026rsquo;s talk during Gopherfest, November 18, 2015. \u0026#x21a9;\u0026#xfe0e;\n ","description":"Sample article showcasing basic Markdown syntax and formatting for HTML elements.","id":14,"section":"posts","tags":["markdown","css","html","themes"],"title":"Markdown Syntax Guide","uri":"https://emacle.github.io/posts/markdown-syntax/"},{"content":"Hugo ships with several Built-in Shortcodes for rich content, along with a Privacy Config and a set of Simple Shortcodes that enable static and no-JS versions of various social media embeds.\nInstagram Simple Shortcode YouTube Privacy Enhanced Shortcode Twitter Simple Shortcode Vimeo Simple Shortcode","description":"A brief description of Hugo Shortcodes","id":15,"section":"posts","tags":["shortcodes","privacy"],"title":"Rich Content","uri":"https://emacle.github.io/posts/rich-content/"},{"content":"Code Syntax Highlighting Verify the following code blocks render as code blocks and highlight properly.\nMore about tuning syntax highlighting is the Hugo documentation.\nDiff 1 2 3 4 5 6 7 8 9 10 *** /path/to/original\t\u0026#39;\u0026#39;timestamp\u0026#39;\u0026#39;\r--- /path/to/new\t\u0026#39;\u0026#39;timestamp\u0026#39;\u0026#39;\r***************\r*** 1 ****\r! This is a line.\r--- 1 ---\r! This is a replacement line.\rIt is important to spell\r-removed line\r+new line\r *** /path/to/original\t\u0026#39;\u0026#39;timestamp\u0026#39;\u0026#39;\r--- /path/to/new\t\u0026#39;\u0026#39;timestamp\u0026#39;\u0026#39;\r***************\r*** 1 ****\r! This is a line.\r--- 1 ---\r! This is a replacement line.\rIt is important to spell\r-removed line\r+new line\rMakefile CC=gcc\rCFLAGS=-I.\rhellomake: hellomake.o hellofunc.o\r$(CC) -o hellomake hellomake.o hellofunc.o -I.\r1 2 3 4 5 CC=gcc\rCFLAGS=-I.\rhellomake: hellomake.o hellofunc.o\r$(CC) -o hellomake hellomake.o hellofunc.o -I.\r JSON 1 2 3 {\u0026#34;employees\u0026#34;:[\r{\u0026#34;firstName\u0026#34;:\u0026#34;John\u0026#34;, \u0026#34;lastName\u0026#34;:\u0026#34;Doe\u0026#34;},\r]}\r Markdown 1 2 3 **bold** *italics* [link](www.example.com)\r JavaScript 1 document.write(\u0026#39;Hello, world!\u0026#39;);\r CSS 1 2 3 body {\rbackground-color: red;\r}\r Objective C 1 2 3 4 5 6 #import \u0026lt;stdio.h\u0026gt;\r\rint main (void)\r{\rprintf (\u0026#34;Hello world!\\n\u0026#34;);\r}\r Python 1 print \u0026#34;Hello, world!\u0026#34;\r XML 1 2 3 4 5 \u0026lt;employees\u0026gt;\r\u0026lt;employee\u0026gt;\r\u0026lt;firstName\u0026gt;John\u0026lt;/firstName\u0026gt; \u0026lt;lastName\u0026gt;Doe\u0026lt;/lastName\u0026gt;\r\u0026lt;/employee\u0026gt;\r\u0026lt;/employees\u0026gt;\r Perl 1 print \u0026#34;Hello, World!\\n\u0026#34;;\r Bash 1 echo \u0026#34;Hello World\u0026#34;\r PHP 1 \u0026lt;?php echo \u0026#39;\u0026lt;p\u0026gt;Hello World\u0026lt;/p\u0026gt;\u0026#39;; ?\u0026gt; CoffeeScript 1 console.log(“Hello world!”);\r C# 1 2 3 4 5 6 7 8 using System;\rclass Program\r{\rpublic static void Main(string[] args)\r{\rConsole.WriteLine(\u0026#34;Hello, world!\u0026#34;);\r}\r}\r C++ 1 2 3 4 5 6 7 #include \u0026lt;iostream.h\u0026gt;\r\rmain()\r{\rcout \u0026lt;\u0026lt; \u0026#34;Hello World!\u0026#34;;\rreturn 0;\r}\r SQL 1 2 SELECT column_name,column_name\rFROM table_name;\r Go 1 2 3 4 5 package main\rimport \u0026#34;fmt\u0026#34;\rfunc main() {\rfmt.Println(\u0026#34;Hello, 世界\u0026#34;)\r}\r Ruby 1 puts \u0026#34;Hello, world!\u0026#34;\r Java 1 2 3 4 5 6 7 8 9 10 11 12 import javax.swing.JFrame; //Importing class JFrame\rimport javax.swing.JLabel; //Importing class JLabel\rpublic class HelloWorld {\rpublic static void main(String[] args) {\rJFrame frame = new JFrame(); //Creating frame\r frame.setTitle(\u0026#34;Hi!\u0026#34;); //Setting title frame\r frame.add(new JLabel(\u0026#34;Hello, world!\u0026#34;));//Adding text to frame\r frame.pack(); //Setting size to smallest\r frame.setLocationRelativeTo(null); //Centering frame\r frame.setVisible(true); //Showing frame\r }\r}\r Latex Equation 1 \\frac{d}{dx}\\left( \\int_{0}^{x} f(u)\\,du\\right)=f(x).\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import {x, y} as p from \u0026#39;point\u0026#39;;\rconst ANSWER = 42;\rclass Car extends Vehicle {\rconstructor(speed, cost) {\rsuper(speed);\rvar c = Symbol(\u0026#39;cost\u0026#39;);\rthis[c] = cost;\rthis.intro = `This is a car runs at\r${speed}.`;\r}\r}\rfor (let num of [1, 2, 3]) {\rconsole.log(num + 0b111110111);\r}\rfunction $initHighlight(block, flags) {\rtry {\rif (block.className.search(/\\bno\\-highlight\\b/) != -1)\rreturn processBlock(block.function, true, 0x0F) + \u0026#39; class=\u0026#34;\u0026#34;\u0026#39;;\r} catch (e) {\r/* handle exception */\rvar e4x =\r\u0026lt;div\u0026gt;Example\r\u0026lt;p\u0026gt;1234\u0026lt;/p\u0026gt;\u0026lt;/div\u0026gt;;\r }\rfor (var i = 0 / 2; i \u0026lt; classes.length; i++) {\r// \u0026#34;0 / 2\u0026#34; should not be parsed as regexp\r if (checkCondition(classes[i]) === undefined)\rreturn /\\d+[\\s/]/g;\r}\rconsole.log(Array.every(classes, Boolean));\r}\rexport $initHighlight;\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \u0026lt;!DOCTYPE html\u0026gt;\r\u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt;\r\u0026lt;head\u0026gt;\r\u0026lt;meta charset=\u0026#34;utf-8\u0026#34;\u0026gt;\r\u0026lt;title\u0026gt;Hello world\u0026lt;/title\u0026gt;\r\u0026lt;link href=\u0026#39;http://fonts.googleapis.com/css?family=Roboto:400,400italic,700,700italic\u0026#39; rel=\u0026#39;stylesheet\u0026#39; type=\u0026#39;text/css\u0026#39;\u0026gt;\r\u0026lt;link rel=\u0026#34;stylesheet\u0026#34; href=\u0026#34;index.css\u0026#34; /\u0026gt;\r\u0026lt;/head\u0026gt;\r\u0026lt;body\u0026gt;\r\u0026lt;div id=\u0026#34;app\u0026#34;\u0026gt;\u0026lt;/div\u0026gt;\r\u0026lt;script src=\u0026#34;//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.1/less.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\r\u0026lt;script src=\u0026#34;vendor/prism.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\r\u0026lt;script src=\u0026#34;examples.bundle.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\r\u0026lt;/body\u0026gt;\r\u0026lt;/html\u0026gt;\r 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 /*********************************************************\r* General\r*/\rpre[class*=\u0026#34;language-\u0026#34;],\rcode {\rcolor: #5c6e74;\rfont-size: 13px;\rtext-shadow: none;\rfont-family: Consolas, Monaco, \u0026#39;Andale Mono\u0026#39;, \u0026#39;Ubuntu Mono\u0026#39;, monospace;\rdirection: ltr;\rtext-align: left;\rwhite-space: pre;\rword-spacing: normal;\rword-break: normal;\rline-height: 1.5;\rtab-size: 4;\rhyphens: none;\r}\rpre[class*=\u0026#34;language-\u0026#34;]::selection,\rcode::selection {\rtext-shadow: none;\rbackground: #b3d4fc;\r}\r@media print {\rpre[class*=\u0026#34;language-\u0026#34;],\rcode {\rtext-shadow: none;\r}\r}\rpre[class*=\u0026#34;language-\u0026#34;] {\rpadding: 1em;\rmargin: .5em 0;\roverflow: auto;\rbackground: #f8f5ec;\r}\r:not(pre) \u0026gt; code {\rpadding: .1em .3em;\rborder-radius: .3em;\rcolor: #db4c69;\rbackground: #f9f2f4;\r}\r ","description":"Syntax highlighting test","id":16,"section":"posts","tags":["hugo"],"title":"Syntax highlighting","uri":"https://emacle.github.io/posts/syntax-highlight/"},{"content":"We need goldmark katex entension which is not yet we have: [https://github.com/gohugoio/hugo/issues/6544](https://github.com/gohugoio/hugo/issues/6544)\r Mathematical notation in a Hugo project can be enabled by using third party JavaScript libraries.\nIn this example we will be using KaTeX\n Create a partial under /layouts/partials/math.html Within this partial reference the Auto-render Extension or host these scripts locally. Include the partial in your templates like so: {{ if or .Params.math .Site.Params.math }}\r{{ partial \u0026quot;math.html\u0026quot; . }}\r{{ end }}\r To enable KaTex globally set the parameter math to true in a project\u0026rsquo;s configuration To enable KaTex on a per page basis include the parameter math: true in content files. Note: Use the online reference of Supported TeX Functions\nExamples Inline math: $$ \\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887… $$\nBlock math:\n$$\n\\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\n","description":"A brief guide to setup KaTeX","id":17,"section":"posts","tags":null,"title":"Math Typesetting","uri":"https://emacle.github.io/posts/math-typesetting/"},{"content":"Emoji can be enabled in a Hugo project in a number of ways.\nThe emojify function can be called directly in templates or Inline Shortcodes.\nTo enable emoji globally, set enableEmoji to true in your site’s configuration and then you can type emoji shorthand codes directly in content files; e.g.\n🙈 🙈 🙉 🙉 🙊 🙊\nThe Emoji cheat sheet is a useful reference for emoji shorthand codes.\nN.B. The above steps enable Unicode Standard emoji characters and sequences in Hugo, however the rendering of these glyphs depends on the browser and the platform. To style the emoji you can either use a third party emoji font or a font stack; e.g.\n1 2 3 .emoji {\rfont-family: Apple Color Emoji,Segoe UI Emoji,NotoColorEmoji,Segoe UI Symbol,Android Emoji,EmojiSymbols;\r} ","description":"Guide to emoji usage in Hugo","id":18,"section":"posts","tags":["emoji","gamoji","namoji","bamoji","amoji"],"title":"Emoji Support","uri":"https://emacle.github.io/posts/emoji-support/"},{"content":"digraph G {\rsubgraph cluster_0 {\rstyle=filled;\rcolor=lightgrey;\rnode [style=filled,color=white];\ra0 -\u0026gt; a1 -\u0026gt; a2 -\u0026gt; a3;\rlabel = \u0026quot;process #1\u0026quot;;\r}\rsubgraph cluster_1 {\rnode [style=filled];\rb0 -\u0026gt; b1 -\u0026gt; b2 -\u0026gt; b3;\rlabel = \u0026quot;process #2\u0026quot;;\rcolor=blue\r}\rstart -\u0026gt; a0;\rstart -\u0026gt; b0;\ra1 -\u0026gt; b3;\rb2 -\u0026gt; a3;\ra3 -\u0026gt; a0;\ra3 -\u0026gt; end;\rb3 -\u0026gt; end;\rstart [shape=Mdiamond];\rend [shape=Msquare];\r}\r","description":"A hack to put Graphviz on the web.","id":19,"section":"posts","tags":[""],"title":"Viz support","uri":"https://emacle.github.io/posts/test-viz/"},{"content":"{ \u0026quot;signal\u0026quot;: [ {\u0026quot;name\u0026quot;: \u0026quot;CLK\u0026quot;, \u0026quot;wave\u0026quot;: \u0026quot;p.....|...\u0026quot;},\r{\u0026quot;name\u0026quot;:\u0026quot;DAT\u0026quot;, \u0026quot;wave\u0026quot;:\u0026quot;x.345x|=.x\u0026quot;, \u0026quot;data\u0026quot;:[\u0026quot;A\u0026quot;,\u0026quot;B\u0026quot;,\u0026quot;C\u0026quot;,\u0026quot;D\u0026quot;]},\r{\u0026quot;name\u0026quot;: \u0026quot;REQ\u0026quot;, \u0026quot;wave\u0026quot;: \u0026quot;0.1..0|1.0\u0026quot;},\r{},\r{\u0026quot;name\u0026quot;: \u0026quot;ACK\u0026quot;, \u0026quot;wave\u0026quot;: \u0026quot;1.....|01.\u0026quot;}\r]}\r","description":"WaveDrom is a Free and Open Source online digital timing diagram (waveform) rendering engine that uses javascript, HTML5 and SVG to convert a WaveJSON input text description into SVG vector graphics.","id":20,"section":"posts","tags":[""],"title":"Wavedrom support","uri":"https://emacle.github.io/posts/test-wavedrom/"},{"content":"{\r\u0026quot;type\u0026quot;: \u0026quot;bar\u0026quot;,\r\u0026quot;data\u0026quot;: {\r\u0026quot;labels\u0026quot;: [\u0026quot;One\u0026quot;, \u0026quot;Two\u0026quot;, \u0026quot;Three\u0026quot;, \u0026quot;Four\u0026quot;, \u0026quot;Five\u0026quot;, \u0026quot;Six\u0026quot;],\r\u0026quot;datasets\u0026quot;: [{\r\u0026quot;label\u0026quot;: \u0026quot;# of Votes\u0026quot;,\r\u0026quot;data\u0026quot;: [12, 19, 3, 5, 3, 8]\r}]\r}\r}\r{\r\u0026quot;type\u0026quot;: \u0026quot;line\u0026quot;,\r\u0026quot;data\u0026quot;: {\r\u0026quot;labels\u0026quot;: [\u0026quot;One\u0026quot;, \u0026quot;Two\u0026quot;, \u0026quot;Three\u0026quot;, \u0026quot;Four\u0026quot;, \u0026quot;Five\u0026quot;, \u0026quot;Six\u0026quot;],\r\u0026quot;datasets\u0026quot;: [\r{\r\u0026quot;label\u0026quot;: \u0026quot;# of Votes\u0026quot;,\r\u0026quot;data\u0026quot;: [12, 19, 3, 5, 2, 3],\r\u0026quot;backgroundColor\u0026quot;:\u0026quot;transparent\u0026quot;,\r\u0026quot;borderColor\u0026quot;:\u0026quot;orange\u0026quot;\r},\r{\r\u0026quot;label\u0026quot;: \u0026quot;Some other set\u0026quot;,\r\u0026quot;data\u0026quot;: [15, 8, 13, 5, 5, 9],\r\u0026quot;backgroundColor\u0026quot;:\u0026quot;transparent\u0026quot;,\r\u0026quot;borderColor\u0026quot;:\u0026quot;#44ccff\u0026quot;\r}\r]\r}\r}\r","description":"Simple yet flexible JavaScript charting for designers \u0026 developers","id":21,"section":"posts","tags":[""],"title":"Chart support","uri":"https://emacle.github.io/posts/test-chartjs/"},{"content":"Alice-\u0026gt;Bob: Hello Bob, how are you?\rNote right of Bob: Bob thinks\rBob--\u0026gt;Alice: I am good thanks!\rTitle: Here is a title\rA-\u0026gt;B: Normal line\rB--\u0026gt;C: Dashed line\rC-\u0026gt;\u0026gt;D: Open arrow\rD--\u0026gt;\u0026gt;A: Dashed open arrow\r","description":"Generates UML sequence diagrams from simple text","id":22,"section":"posts","tags":[""],"title":"JS Sequence Diagram support","uri":"https://emacle.github.io/posts/test-js-sequence-diagrams/"},{"content":"graph TD;\rA--\u0026gt;B;\rA--\u0026gt;C;\rB--\u0026gt;D;\rC--\u0026gt;D;\rsequenceDiagram\rparticipant Alice\rparticipant Bob\rAlice-\u0026gt;John: Hello John, how are you?\rloop Healthcheck\rJohn-\u0026gt;John: Fight against hypochondria\rend\rNote right of John: Rational thoughts \u0026lt;br/\u0026gt;prevail...\rJohn--\u0026gt;Alice: Great!\rJohn-\u0026gt;Bob: How about you?\rBob--\u0026gt;John: Jolly good!\rgraph TD\rA[Hard] --\u0026gt;|Text| B(Round)\rB --\u0026gt; C{Decision}\rC --\u0026gt;|One| D[Result 1]\rC --\u0026gt;|Two| E[Result 2]\rgantt\rsection Section\rCompleted :done, des1, 2014-01-06,2014-01-08\rActive :active, des2, 2014-01-07, 3d\rParallel 1 : des3, after des1, 1d\rParallel 2 : des4, after des1, 1d\rParallel 3 : des5, after des3, 1d\rParallel 4 : des6, after des4, 1d\rclassDiagram\rClass01 \u0026lt;|-- AveryLongClass : Cool\r\u0026lt;\u0026lt;interface\u0026gt;\u0026gt; Class01\rClass09 --\u0026gt; C2 : Where am i?\rClass09 --* C3\rClass09 --|\u0026gt; Class07\rClass07 : equals()\rClass07 : Object[] elementData\rClass01 : size()\rClass01 : int chimp\rClass01 : int gorilla\rclass Class10 {\r\u0026lt;\u0026lt;service\u0026gt;\u0026gt;\rint id\rsize()\r}\rstateDiagram\r[*] --\u0026gt; Still\rStill --\u0026gt; [*]\rStill --\u0026gt; Moving\rMoving --\u0026gt; Still\rMoving --\u0026gt; Crash\rCrash --\u0026gt; [*]\rpie\r\u0026quot;Dogs\u0026quot; : 386\r\u0026quot;Cats\u0026quot; : 85\r\u0026quot;Rats\u0026quot; : 15 ","description":"Generate diagrams, charts, graphs or flows from markdown-like text via javascript.","id":23,"section":"posts","tags":["diagram"],"title":"Mermaid support","uri":"https://emacle.github.io/posts/test-mermaid/"},{"content":"When $a \\ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are\n$$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$$\n","description":"A JavaScript display engine for mathematics that works in all browsers.No more setup for readers. It just works.","id":24,"section":"posts","tags":[""],"title":"MathJax support","uri":"https://emacle.github.io/posts/test-mathjax/"},{"content":"The following\n$$ \\int_{a}^{b} x^2 dx $$\nIs an integral\n$$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\nEnable Katex in the config file by setting the katex param to true. This will import the necessary Katex CSS/JS.\nSee the online reference of supported TeX functions.\nNote: For inline math to render correctly, your content file extension must be .mmark. See the official mmark site.\nInline math: $ \\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887… $\rInline math: $ \\varphi = \\dfrac{1+\\sqrt5}{2}= 1.6180339887… $\nBlock math:\r$$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\rBlock math:\n$$ \\varphi = 1+\\frac{1} {1+\\frac{1} {1+\\frac{1} {1+\\cdots} } } $$\n","description":"KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web.","id":25,"section":"posts","tags":[""],"title":"Katex support","uri":"https://emacle.github.io/posts/test-katex/"},{"content":"st=\u0026gt;start: Start|past:\u0026gt;http://www.google.com[blank]\re=\u0026gt;end: End|future:\u0026gt;http://www.google.com\rop1=\u0026gt;operation: My Operation|past\rop2=\u0026gt;operation: Stuff|current\rsub1=\u0026gt;subroutine: My Subroutine|invalid\rcond=\u0026gt;condition: Yes\ror No?|approved:\u0026gt;http://www.google.com\rc2=\u0026gt;condition: Good idea|rejected\rio=\u0026gt;inputoutput: catch something...|future\rst-\u0026gt;op1(right)-\u0026gt;cond\rcond(yes, right)-\u0026gt;c2\rcond(no)-\u0026gt;sub1(left)-\u0026gt;op1\rc2(yes)-\u0026gt;io-\u0026gt;e\rc2(no)-\u0026gt;op2-\u0026gt;e\r","description":"flowchart.js is a flowchart DSL and SVG render that runs in the browser and terminal. Nodes and connections are defined in separately so that nodes can be reused and connections can be quickly changed.","id":26,"section":"posts","tags":[""],"title":"Flowchart support","uri":"https://emacle.github.io/posts/test-flowchart/"},{"content":"Sample images from Pixabay\n","description":"cartoon gallery","id":27,"section":"gallery","tags":null,"title":"Cartoon","uri":"https://emacle.github.io/gallery/cartoon/"},{"content":"Sample images from Pixabay\n","description":"photo gallery","id":28,"section":"gallery","tags":null,"title":"Photo","uri":"https://emacle.github.io/gallery/photo/"},{"content":"DONE 配置 dhcpcd-run-hook dhcpcd vs /etc/network/interfaces pi 使用 dhcpcd 作为dhcp client 配置 静态IP也在这里进行配置\n必须dhcp获取到ip地址后, 执行 frpc 命令, 否则会出现 frpc不能连接自动断开退出的情况\nhttps://blog.csdn.net/yjbaobo/article/details/75146840\n这主要是由于版本差异 Debian \u0026lsquo;Jessie\u0026rsquo; in place of Debian \u0026lsquo;Wheezy\u0026rsquo;.\n我的是jessie选择修改的是 dhcpcd.conf这个。其中作者也说了如何设置usb无线的配置文件。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #!/bin/sh\r# /etc/dhcpcd.exit-hook - runs as last dhcpcd hook\r# man dhcpcd-run-hooks 查看参数 $if_up $interface $reason etc\rif [ \u0026#34;$interface\u0026#34; = eth0 ] \u0026amp;\u0026amp; [ \u0026#34;$if_up\u0026#34; = true ] ; then\r# 测试 dhcpcd 变量变化, grep reason /tmp/variables.txt, if_up interface等 测试完成需要关闭防止文件变巨大\r# echo \u0026#34;================\u0026#34; \u0026gt;\u0026gt; /tmp/variables.txt\r# echo \u0026#34;Environment Variables\u0026#34; \u0026gt;\u0026gt; /tmp/variables.txt\r# printenv \u0026gt;\u0026gt; /tmp/variables.txt\r# echo \u0026#34;===============\u0026#34; \u0026gt;\u0026gt; /tmp/variables.txt\r# echo \u0026#34;Shell Variables\u0026#34; \u0026gt;\u0026gt; /tmp/variables.txt\r# set \u0026gt;\u0026gt; /tmp/variables.txt\r# dhcpcd 每一次dhcp信息发生变化时 都会调用该脚本 $reason 每次不太相同 通过上面变量观察使用dhcp时 BOUND 只在第一次分配ip时出现\r# $reason为 BOUND 时 执行一次 frp 命令 防止重复添加/也可以判断 frp 进程存在与否来做判断\rcase \u0026#34;$reason\u0026#34; in\rBOUND)\r# logger信息 写入syslog\rlogger \u0026#39;Running frp/DYNDNS update...\u0026#39;\r# curl --stderr - -v \u0026#34;https://dynv6.com/api/update(blah)\u0026#34;\rnohup /opt/frp_0.29.0_linux_arm/frpc -c /opt/frp_0.29.0_linux_arm/frpc.ini \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 \u0026amp;\r;;\resac\rfi\r ip route add 10.11.12.0/24 via 192.168.192.5\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 # man dhcpcd-run-hooks\rBOUND | BOUND6 dhcpcd obtained a new lease from a DHCP server.\rRENEW | RENEW6 dhcpcd renewed it\u0026#39;s lease.\rREBIND | REBIND6 dhcpcd has rebound to a new DHCP server.\rROUTERADVERT dhcpcd has received an IPv6 Router Advertisement, or\rone has expired.\r$interface _the name of the interface._\r$protocol the protocol that triggered the event.\r$reason _as described above._\r$pid the pid of dhcpcd.\r$if_up true if the interface is up, otherwise\rfalse.\r /etc/dhcp/dhclient-enter-hooks.d 是 isc-dhcp-client 包的内容 也是一个dhcp 客户端, 可做为 dhcpcd 的备选\nisc-dhcp-client 与 dhcpcd一样 都可作为 dhcp client busty 默认使用 dhcpcd\nDONE 开启SSH sd卡 /boot 目录 默认不开启SSH,需要在SD卡根目录(boot中)新建 \u0026ldquo;SSH\u0026rdquo; 文件(无后缀)\nssh 进入系统后 /boot/SSH 文件应该被系统删除,但是ssh 服务是永远开启了\nDONE mdadm raid 1 2 3 4 5 6 7 apt install mdadm\r# 装配原有的磁盘阵列 组合成新的磁盘阵列 md0 此操作在里而且会自动更新 /etc/mdadm/mdadm.conf 文件\r# 同时也更新了内核映象 (update-initramfs -u) 启动时内核会自动装配md0 ,如果 sd[a-c]存在的话\rmdadm -A /dev/md0 /dev/sd[a-c]1 或 mdadm -A /dev/md0 /dev/sda1 /dev/sdb1 /dev/sdc1\r# definitions of existing MD arrays cat /etc/mdadm/mdadm.conf\rARRAY /dev/md/0 metadata=1.2 UUID=fabd24e6:e0160fe0:a0af4d3c:4498ec65 name=debian:0\r DONE fstab nofail 外部设备(/dev/md0)在插入时挂载,在未插入时忽略。\n这需要 nofail 选项,可以在启动时若设备不存在直接忽略它而不报错进入recovery mode Contrl + D\nMount an external drive at boot time only if it is plugged in\ncat /etc/fstab\n1 /dev/md0 /mnt/raid5 ext4 defaults,nofail 0 0\r DONE hdmi hdmi: 对于chuangwei_TV , pi 的/boot/config里默认参数即可,不需要做额外配置\nDONE pi未连接显示器时如果使用vnc连接出现Cannot currently show the dekstop Do not use default resolution\n1 2 3 4 5 6 7 8 9 The RPi must be set to boot to desktop (service mode).\rIf a HDMI monitor is not attached then you need to specify a screen resolution\rsudo raspi-config\rAdvanced Options \u0026gt; Resolution \u0026gt; DMT Mode 85 1280x720\rraspi-config 命令 相当于: 修改 /boot/config.txt 内容\rhdmi_force_hotplug=1\rhdmi_group=2\rhdmi_mode=85\r ","description":"","id":33,"section":"posts","tags":["pi"],"title":"raspberry pi 4","uri":"https://emacle.github.io/posts/raspberry-pi-4/"},{"content":"Hi there 👋 Thanks for visiting my profile, it\u0026rsquo;s great to meet you here! 😊\nHere are some interested things for me:\n 🐂 Emacs - a great text editor 🦄 OrgMode - Your life in plain text 🍎 Hugo - The world’s fastest framework for building websites 🍄 ox-Hugo - Org to Markdown for Hugo 🐧 Coding is my passion. Linux/php/vue/javascript/mysql \nWritten in Go, Hugo is an open source static site generator available under the Apache Licence 2.0. Hugo supports TOML, YAML and JSON data file types, Markdown and HTML content files and uses shortcodes to add rich content. Other notable features are taxonomies, multilingual mode, image processing, custom output formats, HTML/CSS/JS minification and support for Sass SCSS workflows.\nHugo makes use of a variety of open source projects including:\n https://github.com/russross/blackfriday https://github.com/alecthomas/chroma https://github.com/muesli/smartcrop https://github.com/spf13/cobra https://github.com/spf13/viper Hugo is ideal for blogs, corporate websites, creative portfolios, online magazines, single page applications or even a website with thousands of pages.\nHugo is for people who want to hand code their own website without worrying about setting up complicated runtimes, dependencies and databases.\nWebsites built with Hugo are extremelly fast, secure and can be deployed anywhere including, AWS, GitHub Pages, Heroku, Netlify and any other hosting provider.\nLearn more and contribute on GitHub.\n","description":"Hugo, the world’s fastest framework for building websites","id":34,"section":"","tags":null,"title":"About","uri":"https://emacle.github.io/about/"}]