{"id":49796,"date":"2025-10-27T15:28:42","date_gmt":"2025-10-27T19:28:42","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=49796"},"modified":"2025-10-28T08:01:02","modified_gmt":"2025-10-28T12:01:02","slug":"line-wraps-and-the-zero-width-joiner","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2025\/10\/27\/line-wraps-and-the-zero-width-joiner\/","title":{"rendered":"Line Wraps and the Zero-Width Joiner"},"content":{"rendered":"<p>I was reminded of this post from <a href=\"https:\/\/www.linkedin.com\/in\/martin-wierschin-a868526\/\">former<\/a> Nisus developer <a href=\"https:\/\/nisus.com\/blogs\/line-wraps-and-the-zero-width-joiner\/\">Martin Wierschin<\/a>:<\/p>\n<blockquote cite=\"https:\/\/nisus.com\/blogs\/line-wraps-and-the-zero-width-joiner\/\">\n<p>How does does an emoji do that in text? By using a zero-width joiner character between its constituent characters. That way software knows to display all the codes together as a single glyph or image on screen. This joiner trick is used for a variety of purposes like skin tone and gender modifiers.<\/p>\n<p>Now to the part where we explain how the zero-width joiner character can help your writing. In certain situations you might consider inserting a joiner character to change where line wrapping occurs. The joiner acts as a signal to the text layout engine that the adjacent characters should be joined. You can think of the joiner like a glob of glue that keeps its neighbors together. The characters won&rsquo;t display a single image as with emoji, but rather they will be kept together on the same line.<\/p>\n<\/blockquote>\n<p>Nisus Writer Pro has a built-in menu command to insert the zero-width joiner. There&rsquo;s also a built-in way to insert it into any macOS text view, but it&rsquo;s not obvious:<\/p>\n\n<ol>\n<li>Open the <strong>Emoji &amp; Symbols<\/strong> inspector.<\/li>\n<li>If necessary, click the rightmost button to switch it to the full <strong><a href=\"https:\/\/nshipster.com\/character-viewer\/\">Character Viewer<\/a><\/strong>.<\/li>\n<li>From the <strong>&#8230;<\/strong> menu, choose <strong>Customize List&#8230;<\/strong>.<\/li>\n<li>At the bottom of the list, check the box next to <strong>Code Tables &#x2023; Unicode<\/strong> and click <strong>Done<\/strong>.<\/li>\n<li>Select <strong>Unicode<\/strong> at the left and then select <strong>2000 General Punctuation<\/strong> at the right.<\/li>\n<li>Zero Width Joiner (U+200D) and related characters are in the first row.<\/li>\n<\/ol>\n\n<p>You can add them as favorites. Unfortunately, even then, they do not seem to be searchable by name. For me, the easiest way to make unusual characters accessible is to add them as LaunchBar snippets. <a href=\"https:\/\/support.apple.com\/guide\/mac-help\/replace-text-punctuation-documents-mac-mh35735\/mac\">macOS text replacements<\/a> would probably work, too.<\/p>\n\n<p>Here are the characters from Wierschin&rsquo;s &ldquo;female chef&rdquo; example if you want to copy\/paste them to try it out:<\/p>\n<pre>&#x1F469; + U+200D + &#x1F373; = &#x1F469;&#x200D;&#x1F373;<\/pre>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/10\/27\/nisus-probably-moribund\/\">Nisus Probably Moribund<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2025\/02\/19\/hiding-data-in-emoji\/\">Hiding Data in Emoji<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2021\/11\/19\/unicode-and-copying-and-pasting-code\/\">Unicode and Copying and Pasting Code<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2018\/01\/04\/fingerprinting-swift-code-using-spacecrypt\/\">Fingerprinting Swift Code Using Spacecrypt<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2015\/10\/23\/dark-corners-of-unicode\/\">Dark Corners of Unicode<\/a><\/li>\n<\/ul>\n\n<p id=\"line-wraps-and-the-zero-width-joiner-update-2025-10-28\">Update (<a href=\"#line-wraps-and-the-zero-width-joiner-update-2025-10-28\">2025-10-28<\/a>): Thanks to <a href=\"https:\/\/mjtsai.com\/blog\/2025\/10\/27\/line-wraps-and-the-zero-width-joiner\/#comment-4323078\">Ralf<\/a> for helping me to realize that searching for &ldquo;joiner&rdquo; <em>does<\/em> find the character. It <em>looks<\/em> like it only finds the letters &ldquo;j,&rdquo; &ldquo;o,&rdquo; &ldquo;i,&rdquo; &ldquo;n,&rdquo; &ldquo;e,&rdquo; and &ldquo;r,&rdquo; but there are actually invisible characters after that that only show up if you click on what looks like empty space.<\/p>","protected":false},"excerpt":{"rendered":"<p>I was reminded of this post from former Nisus developer Martin Wierschin: How does does an emoji do that in text? By using a zero-width joiner character between its constituent characters. That way software knows to display all the codes together as a single glyph or image on screen. This joiner trick is used for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2025-10-27T19:28:45Z","apple_news_api_id":"7a98f88c-71fa-4662-ab89-ab339143dff9","apple_news_api_modified_at":"2025-10-28T12:01:05Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAQ==","apple_news_api_share_url":"https:\/\/apple.news\/Aepj4jHH6RmKriaszkUPf-Q","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[2],"tags":[257,467,30,2742,891,258],"class_list":["post-49796","post","type-post","status-publish","format-standard","hentry","category-technology","tag-emoji","tag-launchbar","tag-mac","tag-macos-tahoe-26","tag-nisus-writer-pro","tag-unicode"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=49796"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49796\/revisions"}],"predecessor-version":[{"id":49802,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/49796\/revisions\/49802"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=49796"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=49796"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=49796"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}