神奇的中文字体及其他

写在前面 

当然,作为一个刚起步的 coder,我还是得说一下为了写出这么一篇平淡无奇的文章,我花费了多少时间……

首先,在经历过一次在 Squarespace 网页后台写代码却直接被重新载入连接的悲惨故事之后,我决定再也不考虑这么做了。那么,选择一个合适的编辑器用来处理 HTML 和 CSS 就摆上桌面了:难道要用自带的 Textedit?还是说用坑爹的 Word 或者 Pages 然后转换成 HTML 格式?抑或是用 Dreamweaver 或者其他的 WYSIWYG 编辑器?

于是我又一次开始去 Google 上面挖了。结果,很幸运地,找到了『异次元空间』——以前很经常去的一个个人网站——上面的一个推荐:Sublime Text 。顺便说一下,这个网站从大一开始关注,常年处于我的书签里面,眼看着它从一个个人网站慢慢做大,设立分站、请编辑、被版权问题请喝茶,上面的内容一直维持着高质量。不过不知道什么时候开始已经不怎么看了……

为什么说它很给力?在异次元上面,主要的评价是『启动速度超快』。事实上,它牛逼的地方不只是启动速度,还有很多:支持基本能见到的所有代码格式,可以自动识别;自带插件平台,可以做很多事情;虽然是收费软件,但是免费无限试用;支持各种操作系统;界面非常非常好看……等等。我在这篇文章里面贴代码框就是用的 Sublime Text 里面的一个插件做的自动格式。

我不得不吐槽自己这个新手,写这篇文章基本就是一边查着教程,一边写下来的。痛不欲生啊,记不住、学不会、用不熟。

神奇的中文字体 

昨晚上,我花了一整晚上的时间看完了 HTML.net 上面的HTML教程(虽然很多没记住)。于是我兴致勃勃地写了一个 .html 文件(当然里面有我们坑爹的中文文字),结果 Safari 显示的是乱码……当然,作为一个用英文系统的人,见到乱码已经习惯了。无非是编码问题嘛!于是,上网搜索到了一个不知道是台湾还是香港的网站的解决办法:

Untitled
 1 
<head>
 2 
    <meta charset="UTF-8">
 3 
</head>

依稀记得高中听贾骏超说过抄代码很不好 blabla ,看来我这算是开启了抄代码的大门了。

解决了编码,然后就是字体问题了。我自知现在的行文是很有光华遗风的中英文夹杂风格——特别是写这种有科技色彩的文章。于是到知乎上看了看,发现了这个

对于所有正常的浏览器 [1],CSS 的 font-family 属性 [2] 的基本能力之一就是依其列表内字体的排序(优先级)来显示文字。 
如果设定为「font-family: "Western Font", "Chinese Font", generic-family;」,就用第一项 "Western Font" 显示西文(英文字母、英文标点、阿拉伯数字……),然后遇到汉字之类不受 "Western Font" 支持的字符就用下一项 "Chinese Font"。所以通常这样就可以分别为英文和中文设定字体了。这是极其常见的手法。 

那么,对于我这个设计而言,就是这样的字体顺序了:

global.css
 279 
font-family: 'Palatino Linotype', 'Palatino LT STD', Palatino, Georgia, stxihei, stheiti, microsoft yahei, simhei, serif;

虽然看起来很简单,但是事实上解决网站的中文字体花了我可能七八个小时——大部分时间用在解读 Squarespace 的这个巨大的 CSS 文件上,以及试图把 CSS 注入到这么一个封闭加密的后台里面。

嵌入代码框

网站模板自带的代码框不能说丑到极致,但是至少是目不忍视:

<p>Hello, World!</p>

就是这么个 plain text 的水平。这让我很费解,因为 Squarespace 按理说是一群设计强迫症的啊?

总之,现实摆在面前,我必须得自己找个贴代码的方法。 

从一个老外的 blog 上面,找到了一段简单的 JS 代码,可以方便地转换出代码框。我直接把源代码嵌入到下面好了:

Source Code Formatting.html
   1 
<head>
   2 
<!-- THIS STUFF GOES IN THE HEADER TEMPLATE -->
   3 
<style type="text/css">
   4 
pre.source-code {
   5 
  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;
   6 
  color: #000000;
   7 
  background-color: #eee;
   8 
  font-size: 13px;
   9 
  border: 1px dashed #999999;
  10 
  line-height: 15px;
  11 
  padding: 5px;
  12 
  overflow: auto;
  13 
  width: 100%
  14 
}
  15 
p.warning {
  16 
  color: #000000;
  17 
  background-color: #FFB6C1;
  18 
  font-size: 13px;
  19 
  border: 3px double #333333;
  20 
  line-height: 15px;
  21 
  padding: 5px;
  22 
  overflow: auto;
  23 
  width: 100%
  24 
}
  25 
</style>
  26 
<SCRIPT LANGUAGE="JavaScript">
  27 
<!--
  28 
var Color= new Array();
  29 
Color[1] = "ff";
  30 
Color[2] = "ee";
  31 
Color[3] = "dd";
  32 
Color[4] = "cc";
  33 
Color[5] = "bb";
  34 
Color[6] = "aa";
  35 
Color[7] = "99";
  36 
 
  37 
function fadeIn(where) {
  38 
  if (where >= 1) {
  39 
      document.getElementById('fade').style.backgroundColor = "#ffff" + Color[where];
  40 
    if (where > 1) {
  41 
      where -= 1;
  42 
      setTimeout("fadeIn("+where+")", 200);
  43 
    } else {
  44 
      where -= 1;
  45 
      setTimeout("fadeIn("+where+")", 200);
  46 
      document.getElementById('fade').style.backgroundColor = "transparent";
  47 
    }
  48 
  }
  49 
}
  50 
 
  51 
function format() {
  52 
    var strIn = document.getElementById("textin").value;
  53 
    var strOut = null;
  54 
    if ( document.getElementById("embedstyle").checked ) {
  55 
        strOut = "<pre style=\"font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 13px;border: 1px dashed #999999;line-height: 15px;padding: 5px; overflow: auto; width: 100%\"><code>";
  56 
        hideElement("style");
  57 
    } else {
  58 
        strOut = "<pre class=\"source-code\"><code>";
  59 
        showElement("style");
  60 
    }
  61 
    var strOut25 = null;
  62 
    var line = 1;
  63 
    var strTab;
  64 
    var hasVerticalPipe = false;
  65 
   
  66 
    if ( document.getElementById("tab4").checked ) {
  67 
    strTab = "    ";
  68 
    } else {
  69 
        strTab = "        ";
  70 
    }
  71 
 
  72 
    for ( i = 0; i < strIn.length; i++ ) {
  73 
        var code = strIn.charCodeAt(i);
  74 
        switch( code ) {
  75 
            case 9: // tab
  76 
                strOut += strTab;
  77 
        break;
  78 
            case 10// line-feed
  79 
            case 13
  80 
                strOut += "\n";
  81 
                line += 1;
  82 
                if ( line == 26 ) {
  83 
                    strOut25 = strOut + "[only the first 25 lines shown in this example]\n\n";
  84 
                }
  85 
                if ( code == 13 && (i + 1) < strIn.length && strIn.charCodeAt(i + 1) == 10 ) {
  86 
                    i++;
  87 
                }
  88 
                break;
  89 
            case 34:
  90 
                strOut += "&quot;";
  91 
                break;
  92 
            case 38:
  93 
                strOut += "&amp;";
  94 
                break;
  95 
            case 60:
  96 
                strOut += "&lt;";
  97 
                break;
  98 
            case 62:
  99 
                strOut += "&gt;";
 100 
                break;
 101 
            case 124: // vertical pipe (blogger modifies this)
 102 
                strOut += "&#124;";
 103 
                hasVerticalPipe = true;
 104 
                break;
 105 
            default:
 106 
                if ( code >= 32 && code <= 127 ) {
 107 
                    strOut += strIn.charAt(i);
 108 
                } else {
 109 
                    strOut += "&#" + code + ";";
 110 
                }
 111 
                break;
 112 
        } // switch
 113 
    } // for
 114 
    strOut += "\n</code></pre>";
 115 
    var textoutelement = document.getElementById("textout")
 116 
    textoutelement.value = strOut;
 117 
    textoutelement.focus();
 118 
    textoutelement.select();
 119 
 
 120 
    if ( hasVerticalPipe ) {
 121 
        showElement( "vert-pipe-warning" );
 122 
    } else {
 123 
        hideElement( "vert-pipe-warning" );
 124 
    }
 125 
 
 126 
    var resultselement = document.getElementById("results");
 127 
    if ( strOut25 != null ) {
 128 
        resultselement.innerHTML = strOut25;
 129 
    } else {
 130 
        resultselement.innerHTML = strOut;
 131 
    }
 132 
 
 133 
    fadeIn(7);
 134 
}
 135 
 
 136 
function onloadEvent() {
 137 
    var textinelement = document.getElementById("textin");
 138 
    textinelement.focus();
 139 
    textinelement.select();
 140 
}
 141 
 
 142 
function showElement(strId) {
 143 
    var ref = document.getElementById(strId);
 144 
    if ( ref.style) { ref = ref.style; }
 145 
    ref.display = '';
 146 
}
 147 
 
 148 
function hideElement(strId) {
 149 
    var ref = document.getElementById(strId);
 150 
    if ( ref.style) { ref = ref.style; }
 151 
    ref.display = 'none';
 152 
}
 153 
//-->
 154 
</SCRIPT>
 155 
<!-- END STUFF GOES IN THE HEADER TEMPLATE -->
 156 
</head>
 157 
<!-- THE BODY ELEMENT NEEDS THE ONLOAD EVENT -->
 158 
<body onLoad="javascript:onloadEvent()">
 159 
<!-- THIS STUFF GOES IN POST -->
 160 
<form>
 161 
<p>
 162 
<textarea wrap="off" rows="5" cols="50" id="textin">Paste your text here.</textarea><br/>
 163 
<table>
 164 
    <tr>
 165 
        <td><button onclick="format()" type="button">Format Text</button></td>
 166 
        <td>
 167 
            Tab size: <input type="radio" name="tabsize" id="tab4" checked="true">4</input> <input type="radio" name="tabsize" id="tab8">8</input><br/>
 168 
            Embed Stylesheet: <input type="checkbox" id="embedstyle" checked="true"></input><br/>
 169 
        </td>
 170 
    </tr>
 171 
</table>
 172 
</p>
 173 
<p>
 174 
<div class="step-instr" id="fade">Copy the HTML below to your clipboard. Insert the HTML of your blog or wiki.<br/>
 175 
<textarea wrap="off" rows="12" cols="50" id="textout">formatted HTML will appear in here.</textarea></div>
 176 
</form>
 177 
</p>
 178 
<div id="vert-pipe-warning" style="display: none">
 179 
<p class="warning">
 180 
<b>Vertival Pipe Character Warning:</b><br/>
 181 
The text contains the vertical pipe character '|' which Blogger's editor may remove.  Blogger's editor on the web has two edit tabs: "Edit HTML" and "Compose".  The "Compose" tab will remove all | characters!  Use the "Edit HTML" tab only.
 182 
</p>
 183 
</div>
 184 
<div id="results"><pre class="source-code"><code>This is an example of what your text will look like.
 185 
    &#8226; Tabs are converted to spaces.
 186 
    &#8226; Quotes and other special characters are converted to HTML.
 187 
    &#8226; Everything is enclose in HTML's 'pre' and 'code' tags.
 188 
    &#8226; Style is set:
 189 
        &#8226; Fixed width font.
 190 
        &#8226; Shaded box.
 191 
        &#8226; Dotted line border.
 192 
 
 193 
</code></pre>
 194 
</div>
 195 
<p>
 196 
<div id="style" style="display: none">
 197 
Example Stylesheet:<br/>
 198 
<textarea wrap="off" rows="13" cols="50" id="textout"><style type="text/css">
 199 
pre.source-code {
 200 
  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;
 201 
  color: #000000;
 202 
  background-color: #eee;
 203 
  font-size: 13px;
 204 
  border: 1px dashed #999999;
 205 
  line-height: 15px;
 206 
  padding: 5px;
 207 
  overflow: auto;
 208 
  width: 100%
 209 
}
 210 
</style></textarea>
 211 
</div>
 212 
</p>
 213 
<!-- END STUFF IN POST -->
 214 
</body>

总得来说,这个人看起来很牛,因为代码量真的很少,当然我一句都看不懂 。

因为看不懂,所以不知道怎么把这个黑白色改成彩色的。于是我想到了神奇的 Sublime Text ,会不会有直接输出成 HTML 格式的选项?结果 Google 表示没有,但是有插件可以做到。 

然后我发现原来 Sublime 已经形成了自己的生态环境——一个叫做 package control 的插件管理器(满满的 Linux 即视感呀),以及里面的大量插件。对了,那个HTML 转换的插件叫做 ExportHTML ,安装它需要先安装 Git 这个插件。

其他发现

Adobe CC 系列原来都出来这么久了

本来打算试一试 Dreamweaver 的,结果在官网上看到一大堆 CC 版本。果断地去 Macidea 下载了它。最后事实说明 Dreamweaver 不适合我,太臃肿了,不如写代码。 

顺手把 Photoshop 和 Illustrator 都更新到了 CC 版本。当然,作为天朝子民,它们都是破解版的。

中英文混排

在考虑字体的时候,我顺便想到了这件事。网站采用的英文字体 Palatino 是很正派的『简历字体』,字之间间距很小,和中文混排比较别扭。而且我也很想遵守一下『行业规范』之类的。在知乎上看到一个回答

Adobe InDesign、Microsoft Word 等对中文与西文(这里用「西文」来泛指用空格分词的外文)混合排版支持较好的软件,都默认增大汉字和西文的间距。InDesign 的默认设置是 1/4 的全角空格宽度(遵从 JIS),也就是约等于一个半角空格。 

但大多数情况下我们没有这样专业排版软件的支持,只能手动控制。这种时候,比较在意文字设计(typography,又译「字体排印」)的团队或个人往往都在操作系统界面或网站中的汉字和西文之间插入一个半角空格。

因此,本文中的所有英文和中文之间都加了空格。

坑爹的 Safari 不给力啊 

因为 iCloud 实在是太方便了,我一直用 Safari 作为默认浏览器。直到今晚上我狠狠地压榨了一把电脑的性能,Safari 才原型毕露了:滚动和载入都各种缓慢,经常有元素加载不全。至于一些 live chat 这种东西就更是别想了,完全没有一次成功的。在挣扎了大概一百个字之后,我用 Chrome 写完了这篇文章。

To do list

打算在网站上添加这些功能:

  • 发 blog 的时候可以推送到微博(人人那坑爹的 API ,暂时不考虑);
  •  可以邮件订阅、RSS 订阅 blog ;
  • Google Adsense 的加入——目测一分钱都拿不到; 
  • 让布局『更像个摄影师』,这是雅雪建议的,可惜好像不好办到;

最后的感叹

CSS 真是太神奇了,发明它的人拯救了世界啊!