Blogging my blog

This blog entry is the changelog of my blog site. The content is sorted from newest to oldest.

July 2017

24: Implemented a handy chat log conversion tool. Use iPhone-SE-WeChat6 code block to generate chat history that resembles WeChat version 6 on iPhone SE. Inspired by this post on V2EX (in Chinese), the implementation is CSS-based, scalable and printing friendly (it switches to another set of styles when printing). Raymond Chen is also good at creating screenshots with CSS. Example: write

WeChat chat history with Sometwo

* 13:52
r ( S ) [ Sometwo ] Hi there!
* “Sometwo” has recalled a message.
s [ Me ] [Shocked] What did you recall?
r ( S ) [ Sometwo ] A typo.



Hi there!

“Sometwo” has recalled a message.

Shocked What did you recall?

A typo.

June 2017

8: The site builder has been rewritten (refactored). It is now more extensible and the code is more beautiful.

9: RSS 2.0 and Atom 1.0 syndication are provided. The syndications contain basic metadata (title, dates, abstract, tags, link etc.). Full-text syndication is not expected at this time.

  • Later that day: Support for Atom has been dropped. RSS feed has only one date to specify, pubDate. I put the DateModified property of a post there. For Atom feeds, there are published and updated, into which DateCreated and DateModified are popped. Some Atom feed reader (e.g., Feedly) sorts the posts by its published, which is against my design, while some other reader (e.g., Internet Explorer) sorts the posts by its updated. To avoid inconsistency, Atom feed is no longer an option offered to the users. Moreover, RSS feed allows in a consistent way to convey the link to the comments.
  • Why is full-text syndication not expected? Because certain content can only display correctly with the site’s stylesheet. Examples include KaTeX formulae, images that have High Contrast version (only one version is displayed at a time) and collapsible content. Alternative styling does not give authentic experience of the blog, which is also the reason why I discourage using Reading View (or similar features) on my site. To obtain perfect and designated static appearance, print the page, which also gives the best reading experience (if always expanding all the collapsible sections is acceptable).

23: Added a simple reference extension. Use `ref:REFNAME` to generate a link with text “[REFNAME]”. In any location of the document, put a `ref-back:REFNAME` to indicate the position of the reference. There can be multiple references to the same target. For example, the following code

Reference 1 to `ref:EXAMPLE` and reference 2 to `ref:EXAMPLE`.

- `ref-back:EXAMPLE` The source of example.


Reference 1 to [EXAMPLE] and reference 2 to [EXAMPLE].

  • [EXAMPLE] The source of example.

Clicking one of the two links will target the current document to the source with a button that allows one to return to the correct position.

May 2017

27: Added a new ‘fancy quote’ style, support for KaTeX and heading ID syntax (### heading 3 #heading-id).

  • Fancy quote: Style sheets format with a large double-quotation mark (type 66, or ‘“’) when under normal themes. This type of quotation also adds styles (italic or bold, depending on the culture set on the elements) and centers the quoted content.
  • KaTeX: Now `tex|latex|math|katex:…` are reserved for inline KaTeX formulae and `display|displaymath:…` are for display KaTeX formulae. To define a macro, use ```tex-macro, ```math-macro, ```latex-macro, ```katex-macro code block.
    • The conditional comment version of these things are <!--[blog][katex] KaTeX inline math [blog]-->, <!--[blog][katex-display] KaTeX display math [blog]--> and <!--[blog][katex-macro] \CommandName Value [blog]-->. This can be used to define a whole formula so that you can easily embed a display formula into a paragraph without a hassle.
  • Heading IDs: Formerly the automatic ID generation was removed so that they are more controllable and explicitly expressed. Now with another syntactic sugar you can easily add a predictible and permanent ID while enjoying every benefit of Markdown.

24: Improved printing experience. Improved anchor jumping experience. Upgraded to marked 0.3.6 and started to use Node.js. Added my own flavour of Markdown to the program. Improved the performance of building the blog.

  • Printing: <abbr class="obscure-abbr" title="Microsoft Developer Network">MSDN</abbr> will display as MSDN (Microsoft Developer Network) when printing. If the language of that abbr is Chinese, it will be 白骨精(白领、骨干、精英).
  • Anchor jumping: When JavaScript is enabled, after each jump, the :target element will be blinked.
  • Markdown flavour:
    • Use 4k+1 to 4k+4 numbers of ` to represent different semantics — code fragment (<code>), program output (<samp>), keyboard key (kbd) and mathematical variable / simple formula (var). They look like: 1 | Write-Output, 1, Shift and x.
    • To remember this rule, remember that longer tag uses fewer backticks, and for the same length, the order is the lexicographical order.
    • The semantics of program output include file names, paths, URIs (if not made a link) and any program output.
    • If the first (or the last) character inside an inline ` thing is a space character, it (or they) will be removed from the output, with the requirement of matching the length of opening and closing markups, one can create such inline elements with any number of preceeding/succeeding white spaces as well as the backtick itself.
    • If the language of a code block is not specified, it will become <pre><samp></samp></pre>, otherwise it is <pre><code lang="code-<lang>"></code></pre>.
  • Building tool: I have completely remove the dependency on Internet Explorer COM. Node.js is now reliable for running the JavaScript code to compile my Markdown document into HTML, which will be processed by my PowerShell script again. Now the script also holds a cache of compiled HTML. In case the content does not change, the building script simply retrieves the compiled HTML from the cache. This somehow improve the embarrassing performance impact brought by Node.js — I have to use it in an inter-process fashion (using redirect standard streams). It is naturally slower than the previous COM approach. With the cache technique, it can be expected that in the future the speed will be faster.

22: Improved theme experience (dark/light/high contrast). Implemented multi-cultural punctuation font selection. This only proves that Zhihu is pretentious on the quotation marks issue for long. See Jixin Huang’s Zhihu answer on this issue and Zhihu’s official guideline on ‘typesetting by modifying the content’. I would say that adding extra space characters between appropriate boundaries of Chinese script and Latin script is also typesetting by modifying the content. However, detecting the correct boundary to insert extra space is quite hard, and I’ll just go with it until I could make up any better method than inserting space characters manually. The problem of quotation marks (and other punctuations) is solved by adding appropriate lang attributes to alter the font-family. It is noticeable that adding lang attribute is contributing not only to automated font-family selection, but also to many more things, e.g., automatic RTL, accessibility for screen readers (it is possible to select the appropriate TTS engine, instead of the one for the system locale or the specific one chosen by the user that only reads one language, from that attribute).

  • Font selection: Now the HTML documents are extensibly marked with culture (lang attribute of elements) and for lang being zh or zh-*, the Chinese Yuan / Japanese Yen character, the quotation marks (“, ”, ‘ and ’) and the ellipsis character are rendered with a Chinese (Simplified) font so that the height and the width of the characeters are correct with the ellipsis being vertically centred. Compare:
    • 中文文本:“这是一句‘引语’……”
    • Latin script: ‘This is “quoted”…’
  • Theme experience: When the theme is changed, a dialog might appear to ask if you would like to reload Disqus.
    • Disqus is never reloaded when the theme changes to a High Contrast theme, because Disqus follows High Contrast adjust.
    • You might want to reload Disqus when you switch to the light theme or the dark theme.
    • If Disqus was never scrolled into the view since last reload, it is automatically reloaded when you switch to the light theme or the dark theme.
    • If Disqus has been scrolled into the view since last reload, there might be a chance that you have written your comment but have not posted it yet, therefore, you will be prompted.
    • A bad thing about the window.confirm method is that the initially focused button is “OK” instead of “Cancel”. This is against the principle that the default answer to every dialog box is “Cancel”.

19: New navigation design and Friends section. Improved multi-cultural support for authors and tags.

  • Navigation: The navigation links display icons now. For the best effect, use Microsoft Edge.
  • Friends section: Now you can apply for a position in the Friends section. The link you provide must direct to a fruitful web page, comply with content code and the law. Most of the time, you must also provide a link to my blog or my curriculum vitae to the website to appear here. Note that applications are subject to rejection for any reason or without a reason. To apply to be listed, go to Friends section and send me an email (see the footer).
  • Multi-cultural support for authors: Now authors (or the author) use a localised name for each entry. If a perfect match is found, that name is used; otherwise, if a partial match (matching the language, not the region) is found, that name is used; otherwise, the invariant name is used.
  • Multi-cultural support for tags: Each tag’s page is in the tag’s intrinsic culture.
  • Multi-cultural model: Each multi-cultural resource (author display name, tag display name, etc.) has a set of tuples (Culture, Value). These resources, when used, are instantiated under a chosen theme culture, which can be the culture of the blog entry, the intrinsic culture of the tag, etc.
    • When instantiating a multi-cultural resource:
      1. The program tries to find the exact matching culture; if such a match is found, the Value of the match is used;
      2. Otherwise, the program tries to find exact matches in language (e.g., in this stage, en-US and en-GB are matches, while fr-FR and da-DK are not); if such matches are found, one of them is used (tie-breaking is implementation-defined);
      3. Otherwise, the program resorts to the intrinsic culture of the resource (e.g., the intrinsic culture for OneDrive tag is en-US, because this is a word coined by Microsoft, a company in the United States, and the intrinsic culture for Tsinghua University is zh-CN, because it is located in PRC).
    • Internal representation of multi-cultural resources:
      • The code name of the resource is always in plural form (e.g., Names instead of Name);
      • The property is always an array of objects in the form { Culture: "???", Value: "???" };
      • Conventionally, the first item in the array has its Culture being "Invariant", and its Value is one of the concrete cultures in which the resource is localised; this Value, whose accompanying Culture is "Invariant", is the intrinsic culture of the resource;
        • For an author, this is the culture in which he or she prefers to write his or her name; if not explicitly specified, it is often chosen as a culture that uses Latin script;
        • For a tag, this is the origin of the words in the tag and relates to the origin of the thing the tag represents;
      • Conventionally, the second item in the array has its Culture being the intrinsic culture, and the Value is the version used for any non-matching case;
      • The following items are localised versions of the resource.

April 2017

14: Improved accessibility and clipboard-friendliness.

  • Accessibility: The comment-count links and the article items are labelled. More elements have more accurate role property.
  • Clipboard: The navigation links are empty so that they will not be copied in the HTML form. The content comes from pseudo-elements now. Previously this was only done to theme switchers.

13: Implemented social sharing components. Improved accessibility.

  • Social sharing: It is possible to share blog entries on select social networks with buttons near the title.
  • Accessibility: Added aria attributes to some elements and added localised labels.

11: Improved printing exprience, High Contrast experience and multi-culture. Began writing this meta-blog entry.

  • On listing pages, in High Contrast theme or in printing view, the ‘? 💬’ comment-count boxes (or ‘💬’ comment buttons for no-script environment) will display as text in appropriate cultures, such as ‘no comments yet’ or ‘1 条评论’ (or ‘des commentaires’ for no-script environment).
    • A technique in Disqus: I used <span data-cnt={num}><span>💬</span></span> as my plural-comment text template. It took a while for me to compress it. To display text with correct culture, use selectors looking like span:lang(fr)[data-cnt=1]::before. This enables dual for some languages. You need two spans because you want to hide the inner one when text is displayed. You cannot always use pseudo-elements for display (thus replacing the inner one with a fallback selector and ::before.content) to keep clipboard friendliness.

9: Improved responsive layout, usual layout and printing.

  • Responsive: From 700px (800px in earlier settings) the page is in wide view. From 1600px the page is columned and scrolls horizontally.
  • The title of Archive is no longer displayed on screen: it is already indicated by the navigation element.
  • The titles of Home Page, Archive and Tags are displayed when printing: the navigation element is hidden in printing view.
  • Comments are no longer printed: they are in an iframe and are subject to truncation.
  • Legal Notice link is no longer printed: it cannot be clicked when printed-out.

6: Added hero images (if there are) to listing pages. Improved multi-culture. Added HTTP 404 page in official languages of the United Nations.

  • In listing pages, each entry will have its own culture, enabling date created/modified in different cultures.

5: Improved no-script environment, multi-culture and metadata. Added another aim/ideal: no-script friendly.

  • Used <meta http-equiv=refresh … instead of JavaScript for (delayed) redirection.
  • Ensured the collapsible areas display as in printing view in no-script environment. Earlier, the intially collapsed areas will not show in no-script environment.
  • Copyright information is no longer written by JavaScript (it was to display the correct year). And it is now written in the correct culture. Moreover, the Legal Notice link will point to the legal notice in that culture.
  • Metadata: General metadata, iOS/Twitter/Facebook metadata, Live Tile metadata for Windows. From now on, pinning the homepage to Start will give you the summary of five most recent entries.

4: Implemented collapsible area.

  • In a collapsible area, there can be four types of elements, those that only show if the area is collapsed (e.g., a button to expand the area), those that only show if the area is expanded and is on screen (e.g., a button to collapse the area), those that show if the area is expanded or is being printed (this is usually the main content, or the ‘detail’ view), those that always show.
  • Automatically create event handlers for buttons to expand/collapse the area.
  • Optionally, a button might scroll the page after toggling the view state so that the user will not get lost after collapsing a long area.

2: Migrated to and kept for compatibility reasons. Started using Disqus.


16 August 2016: Started using semantic address (e.g. from /1 to /entries/hello-world) and kept /8 for compatibility reasons.

No later than 9 August 2016: Used as the domain. Implemented themes, High Contrast mode, optimisation for printing, multi-culture, responsive design.

  • Themes: Light or dark, chosen automatically depending on local time, toggleable by the user.
  • High Contrast theme: It is possible to specify a High Contrast edition of a picture; (site) themes will be disabled in High Contrast mode; block quotes display borders on all edges (for non-High Contrast mode, only left border is displayed); bolder title text in listing pages.
  • Printing: Some elements display differently for printing. For example, the ‘🔖’ emoji for tags will be text depending on the culture.
  • Multi-culture: The text for tags will be different for different entries.
  • Responsive design: From 800px the page is in wide view. Floatness and padding/margin of elements change.
  • Aims/ideals: Semantic document structure; decoupling styles and content; standard compliant and cross-browser without overwhelming logic; reduce and even remove dependency on front-end libraries; printing, clipboard, High Contrast, screen reader (e.g., Narrator) friendly.

Please enable JavaScript to view the comments powered by Disqus.