{"data":{"post":{"title":"An Introduction to Gatsblog","subtitle":"A Blog Built with Gatsby.js","isPublished":true,"createdTime":"2019-03-02T00:00:00.000Z","lastModifiedTime":null,"license":null,"tags":["Blog","Design","Programming","Gatsblog"],"category":"Showcase","file":{"childMdx":{"excerpt":"This post has been revisited with LLM technology to improve its English\nfluency. As mentioned in my…","code":{"body":"function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nconst layoutProps = {};\nreturn class MDXContent extends React.Component {\n  constructor(props) {\n    super(props);\n    this.layout = null;\n  }\n\n  render() {\n    const _this$props = this.props,\n          {\n      components\n    } = _this$props,\n          props = _objectWithoutProperties(_this$props, [\"components\"]);\n\n    return React.createElement(MDXTag, {\n      name: \"wrapper\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"blockquote\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"blockquote\"\n    }, `This post has been revisited with LLM technology to improve its English\nfluency.`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `As mentioned in my Hello World post, no existing blog system fully meets my\nneeds, especially given my deep involvement with frontend technology.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This led me to create my own solution. This post documents my journey from\ndesign to implementation, chronicling how an iOS developer with an\nindustrial design background ventured into modern frontend development.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Pseudo-Live Editing`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Gatsby.js provides a simple live editing feature. Launch Gatsby's\ndevelopment server with `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `gatsby develop -H 0.0.0.0`), ` or `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `npm run start`), `,\nthen open `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `http://localhost:8000`), ` in your browser. Your post changes will\nappear automatically when you save the edited file.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"img\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"src\": \"/pseudo-live-editing-15f283b58d3fc9db1d7265b106c09a57.gif\",\n        \"alt\": \"Pseudo-Live Editing\",\n        \"title\": \"Pseudo-Live Editing\"\n      }\n    })), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Sophisticated Grid System`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I implemented a sophisticated grid system with carefully tuned element\nsizes and spacing. While the design may not be fancy, it\nprioritizes functionality—ensuring content clarity and comfortable spacing\nbetween elements.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Responsive Image with Retina Display Support`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Most figures in my posts are original creations, making it easy to\ngenerate `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@2x`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `@3x`), ` versions alongside the original. Gatsby supports\nresolution density through file naming conventions, recognizing image\nseries like `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `xxx.png`), `, `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `xxx@2x.png`), `, and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `xxx@3x.png`), ` as 1x, 2x, and 3x\nresolution versions respectively. Simply use standard Markdown image\nsyntax:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-markdown\"\n      }\n    }, `![Image Alternative Text](xxx.png \"Image Title\")\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Gatsblog handles the responsiveness and Retina display support\nautomatically.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `For images sourced from the web or cameras, providing multiple\nresolution versions isn't always practical. Gatsblog handles this\ngracefully—any single image file named `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `xxx.png`), ` will receive responsive\nsupport without requiring additional versions.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `KaTex`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `As a mathematics enthusiast, I've integrated KaTex support. Gatsby now\nhandles both inline expressions like `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `$$a^2 + b^2 = c^2$$`), ` (rendered as\n`, React.createElement(MDXTag, {\n      name: \"inlinemath\",\n      components: components,\n      parentName: \"p\"\n    }, `{a^2 + b^2 = c^2}`), `) and block equations:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-katex\"\n      }\n    }, `$$\n\\\\frac{1}{\\\\Bigl(\\\\sqrt{\\\\phi \\\\sqrt{5}}-\\\\phi\\\\Bigr) e^{\\\\frac25 \\\\pi}} \\\\equiv 1+\\\\frac{e^{-2\\\\pi}} {1+\\\\frac{e^{-4\\\\pi}} {1+\\\\frac{e^{-6\\\\pi}} {1+\\\\frac{e^{-8\\\\pi}} {1+\\\\cdots} } } }\n$$\n`)), React.createElement(MDXTag, {\n      name: \"mathblock\",\n      components: components\n    }, `{\\\\frac{1}{\\\\Bigl(\\\\sqrt{\\\\phi \\\\sqrt{5}}-\\\\phi\\\\Bigr) e^{\\\\frac25 \\\\pi}} \\\\equiv 1+\\\\frac{e^{-2\\\\pi}} {1+\\\\frac{e^{-4\\\\pi}} {1+\\\\frac{e^{-6\\\\pi}} {1+\\\\frac{e^{-8\\\\pi}} {1+\\\\cdots} } } }}`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-katex\"\n      }\n    }, `$$\n\\\\left( \\\\sum_{k=1}^n a_k b_k \\\\right)^2 \\\\leq \\\\left( \\\\sum_{k=1}^n a_k^2 \\\\right) \\\\left( \\\\sum_{k=1}^n b_k^2 \\\\right)\n$$\n`)), React.createElement(MDXTag, {\n      name: \"mathblock\",\n      components: components\n    }, `{\\\\left( \\\\sum_{k=1}^n a_k b_k \\\\right)^2 \\\\leq \\\\left( \\\\sum_{k=1}^n a_k^2 \\\\right) \\\\left( \\\\sum_{k=1}^n b_k^2 \\\\right)}`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-katex\"\n      }\n    }, `$$\n\\\\int u \\\\frac{dv}{dx}\\\\,dx=uv-\\\\int \\\\frac{du}{dx}v\\\\,dx\n$$\n`)), React.createElement(MDXTag, {\n      name: \"mathblock\",\n      components: components\n    }, `{\\\\int u \\\\frac{dv}{dx}\\\\,dx=uv-\\\\int \\\\frac{du}{dx}v\\\\,dx}`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Enhanced with MDX`), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `React Live`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-javascript\",\n        \"metastring\": \"react-live\",\n        \"react-live\": true\n      }\n    }, `class Counter extends React.Component {\n  constructor() {\n    super();\n    this.state = { count: 0 };\n  }\n\n  componentDidMount() {\n    this.interval = setInterval(() => {\n      this.setState(state => ({ count: state.count + 1 }));\n    }, 1000);\n  }\n\n  componentWillUnmount() {\n    clearInterval(this.interval);\n  }\n\n  render() {\n    return (\n      <center>\n        <h3>{this.state.count}</h3>\n      </center>\n    );\n  }\n}\n`)), React.createElement(MDXTag, {\n      name: \"h3\",\n      components: components\n    }, `Code Block with Path Label`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Add `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `path=path_of_file`), ` after the `, React.createElement(MDXTag, {\n      name: \"em\",\n      components: components,\n      parentName: \"p\"\n    }, `language`), ` metadata in the fenced code\nblock's opening line:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-markdown\"\n      }\n    }, `\\`\\`\\`c path=src/main.c\n#include <stdio>\n\nint main(int argc, char[] * args) {\n    printf(\"Hello, world!\\\\n\");\n    return 0;\n}\n​​\\`\\`\\`\n`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `This produces a code block with a path label:`), React.createElement(MDXTag, {\n      name: \"pre\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"code\",\n      components: components,\n      parentName: \"pre\",\n      props: {\n        \"className\": \"language-c\",\n        \"metastring\": \"path=src/main.c\",\n        \"path\": \"src/main.c\"\n      }\n    }, `#include <stdio>\nint main(int argc, char[] * args) {\n    printf(\"Hello, world!\\\\n\");\n    return 0;\n}\n`)), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Statically Deployed`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `Powered by Gatsby.js, Gatsblog supports static deployment. You can deploy\nyour site with just a few clicks on `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://netlify.com\"\n      }\n    }, `Netlify`), `.`));\n  }\n\n}\nMDXContent.isMDXComponent = true;","scope":""},"headings":[{"value":"Pseudo-Live Editing","depth":2},{"value":"Sophisticated Grid System","depth":2},{"value":"Responsive Image with Retina Display Support","depth":2},{"value":"KaTex","depth":2},{"value":"Enhanced with MDX","depth":2},{"value":"React Live","depth":3},{"value":"Code Block with Path Label","depth":3},{"value":"Statically Deployed","depth":2}]}}},"earlierPostExcerpt":{"slug":"/post/2019/03/a-story-of-implementing-aspect-oriented-programming-in-objective-c-and-swift-8b92","title":"A Story of Implementing Aspect-Oriented Programming in Objective-C and Swift","subtitle":"","createdTime":"2019-03-01T00:00:00.000Z","tags":["Swift","Objective-C","Aspect-Oriented Programming"],"category":"Programming","file":{"childMdx":{"excerpt":"Case Study: Intervening UIScrollView Instances's Pan Gesture Recognizer As we known,  UIScrollView  translates pan gesture signals into\n scrollViewDidXXX:  messages and sends to its delegate, most of the time\nyou only have to understand the relationships between the pan gesture\nsignals and the…"}}},"laterPostExcerpt":{"slug":"/post/2019/03/notes-on-design-of-gatsblog-1431","title":"Notes on Design of Gatsblog","subtitle":"","createdTime":"2019-03-03T00:00:00.000Z","tags":["Blog","Design","Gatsblog"],"category":"Showcase","file":{"childMdx":{"excerpt":"This post has been revisited with LLM technology to improve its English\nfluency. I had limited time to create a modern design for the first version of Gatsblog.\nThe design is somewhat \"old school,\" but I carefully tuned the grid system to\nachieve a high-quality layout. Grid System Grid systems are…"}}}},"pageContext":{"postId":"ae21300f-a727-599f-a4f6-90375edebef3","earlierPostId":"6711bea1-42f1-543e-bb9c-8740e10314f0","laterPostId":"10d7b0ff-a57b-5ed6-8009-210fb03be8e7"}}