搬家

自从2013年申请到驿站的空间以来,就一直使用wordpress平台进行创作。 Wordpress 的确非常的优秀:友好的界面使得图文混排的编辑工作轻松不少; 丰富的插件可以满足我的所有需求:代码高亮,latex支持等等;活跃的社区经常给我们带来新的功能;自带的评论系统则可以使我及时得到读者的反馈。

所有的这些优点皆是因为它是构建在PHP+SQL平台之上的。但正是因为页面是动态生成的,而没有漏洞的代码是不存在的,wordpress作为使用人数最多的动态博客平台,受到黑客们的”青睐”。 自2015年以来,驿站受到过多次的攻击,我的博客平均每两个月瘫痪一次。我也曾尝试及时将程序升级到最新版本、安装一些安全相关的插件,然而并没有什么用。。。 这段时间里,我只能寄希望于黑客们的漏洞扫描器不要扫到我的站点,然后在每次收到攻击后徒劳的再一次恢复数据库。

终于下定决心把博客完全静态化。我选择了最为流行的Jecklly系统,然后找到了个人比较喜欢的双栏主题freshman21。 上个周末我对主题进行了修改,使之与我之前的Wordpress主题风格相近,并且优化了一下代码高亮风格、多分辨窗口适应等细节。本文主要介绍一下修改后的主题的一些特性

页宽,背景

我将页宽调的比较大,从而将更多的内容展示给读者,个人比较喜欢这种风格。

背景的话同样是从星表可视化软件mitaka中截取的一张100光年尺度的天球模拟图,告诉读者我们是在太阳系中的…

博客的配色为浅色系,很多地方都调成淡淡的白色透明风格.

多分辨率布局切换

修改前的主题支持不同分辨率下的两种布局:宽度600px以下的垂直布局和600px以上的双栏布局。 实际测试中发现在600px-800px的宽度之间,右侧边栏已经变得比较窄,排版布局显得非常难看。 如果在这个宽度区间将其变为垂直布局,那么它放到页面下端又显得太宽,同样不好看。

修改后的主题在窗口宽度600px-1000px之间将右侧边栏浮动和隐藏起来,需要将鼠标移到右上角的头像上使之激活显示。 感兴趣的同学可以调节一下窗口的宽度,浏览一下三种布局。

经测试,此博客在400px~2560px的各种屏幕上都有着良好的排版(Chrome & Safari)。

目录跟踪

比较长的文章在题头会生成目录。在最高分辨率的模式下,右侧边栏的最下方也会有一个目录,并且这个目录可以动态跟踪页面所处的位置。这个功能由bootstrap框架实现。

代码高亮

原主题的代码高亮是黑色背景的,个人不太喜欢,统统调成看起来比较舒服的灰色。如下

import os
import pdb
from collections import OrderedDict
import numpy as np

def safe_mkdir(path):
    """make dir safely"""
    if not os.path.exists(path):
        os.makedirs(path)

Jecklly原生的代码高亮功能比较少,比如无法高亮某一特定行,而且带行号的布局也不好看。 修改后使用基于javascript的通用代码高亮插件syntaxhighlighter。 插入的代码和效果如下

<pre class="brush: python highlight:'[3,5]'">
import os
import pdb
from collections import OrderedDict
import numpy as np

def safe_mkdir(path):
    """make dir safely"""
    if not os.path.exists(path):
        os.makedirs(path)
</pre>
import os
import pdb
from collections import OrderedDict
import numpy as np

def safe_mkdir(path):
    """make dir safely"""
    if not os.path.exists(path):
        os.makedirs(path)

相比之下,还是wordpress下的Crayon Syntax Highlighter插件显得更为强大和漂亮。 作为修改博客主题的最后一下折腾,我给syntaxhighlighter添加了一个顶部信息栏,左边和右边分别显示code的文件名和种类,中间的按钮可以将超长的代码显示框折叠起来。 插入的代码和显示效果如下

# 下面的{\% 和 %\} 均应没有"\", 这里如果写作没有"\"的样子则会执行这段代码...
{\% assign thisCount= thisCount|plus:1 %\}
{\% include new_highlight.html language="python" title="longCode.py" language_show="python"
    auto-link="true" gutter="true" highlight="none"
    first-line="1" html-script="false"
    smart-tab="true" tabSize="4" count=thisCount %\}
# this is a long long long code, you can ^^^^^^ try to fold it
import time
import re
import inspect
import os

class logFileClass():
    def __init__(self, filePath):
        self.newLogFlag=1
        self.filePath = filePath
....omit below.....
</pre> #用</pre>来结束代码高亮

longCode.py

Make the height to be less than 400pixel

python  


# this is a long long long code, you can ^^^^^^ try to fold it
import time
import re
import inspect
import os

class logFileClass():
    def __init__(self, filePath):
        self.newLogFlag=1
        self.filePath = filePath
        logFileDir = os.path.dirname(filePath)
        if logFileDir not in ['', '.'] and not os.path.exists(logFileDir):
            os.mkdir(logFileDir)
    def header(self):
        if self.newLogFlag==1:
            f = open(self.filePath,'a')
            f.write('============================='+time.strftime('%Y-%m-%d %H:%M:%S')+'====================================\n')
            f.close()
            self.newLogFlag=0
    def log(self, text):
        self.header()
        with open(self.filePath,'a') as f:
            if text[-1] != '\n':
                text = text+'\n'
            text = time.strftime('%Y-%m-%d %H:%M:%S ')+text
            f.write(text)
    def print(self, text):
        print(text)
        self.header()
        with open(self.filePath,'a') as f:
            if text[-1] != '\n':
                text = text+'\n'
            text = time.strftime('%Y-%m-%d %H:%M:%S ')+text
            f.write(text)

class logFunctionCallClass():
    def __init__(self, logFile=None):
        self.n=1;
        self.initDepth = len(inspect.stack())
        if logFile:
            self.logFile = logFile

    def logit(self,path=None):
        if not self.logFile:
            if not path:
                raise "no path for log file"
        else:
            if not path:
                path=self.logFile
        logFileDir = os.path.dirname(path)
        if logFileDir and not os.path.exists(logFileDir):
            os.mkdir(os.path.dirname(logFileDir))
        if self.n==1:
            f = open(path,'a')
            f.write('============================='+time.strftime('%Y-%m-%d %H:%M:%S')+'====================================\n')
            f.close()
            self.n=0

        def maxLength(inStr,maxLength=50):
            N = len(inStr)
            if N>maxLength:
                return inStr[:maxLength-6] + '......'
            else:
                return inStr

        def toPrint(u):
            us = re.findall(r'\\\w(\w{4})',unicode(u))
            uus = [unichr(int('0x'+each,16)) for each in us]
            uuus = u
            for i in uus:
                uuus = re.sub(r'\\(\w{5})',i,uuus,count=1)
            return uuus

        def _logit(func):
            def __logit(*args, **kwargs):
                depth = len(inspect.stack())-self.initDepth
                p0 = time.strftime('%H:%M:%S')
                p1 = func.func_name
                p2 = '('
                for i in args:
                    if type(i)==str:
                        p2 = p2 + '"' + maxLength(i.decode('utf8')) + '"' + ', '
                    elif type(i)==unicode:
                        p2 = p2 + '"' + maxLength(i) + '"' + ', '
                    else:
                        p2 = p2 + maxLength(unicode(i)) + ', '
                try:
                    p2 = re.findall(r'<.*>,(.*)',p2)[0]
                    p2 = '('+p2
                except:
                    pass
                p3 = ' '
                for i in kwargs:
                    if type(kwargs[i])==str:
                        p3 = p3 + i + ' = ' + '"' + maxLength(kwargs[i].decode('utf8')) + '"' + ', '
                    elif type(kwargs[i])==unicode:
                        p3 = p3 + i + ' = ' + '"' + maxLength(kwargs[i]) + '"' + ', '
                    else:
                        p3 = p3 + i + ' = ' + maxLength(unicode(kwargs[i])) + ', '

                pn = depth * "  " + p0 + '  ' + p1 + p2 + p3[0:-2] + ')\n'
                pn = toPrint(pn)
                ret = func(*args, **kwargs)
                #print pn
                f = open(path,'a')
                f.write(pn.encode('utf8'))
                f.close()
                return ret
            return __logit
        return _logit

支持

博客使用mathjax作为$\LaTeX$ 引擎,并将所有js和其他资源做了本地化处理,防止网络原因引起的排版混乱。

博文分类

本博客的博文分为3类

  • 含有较多原创成分、需要较长创作周期的博文: 之前的博文大多都是这样的。这类博文放在博客首页上,可能会成为有生之年系列。

  • 技术类博文: 现在已经逐渐习惯用Markdown语法记录工作中的技术细节。这些东西可以很容易的转化为博文,故此类博文可能更新频率会高一些,而且可以保证都是干货。这些博文放在轮子目录中。

  • 碎碎念: 我初高中的时候,网易博客、QQ空间的使用人数开始多起来,wordpress博客也刚开始在中国流行起来。我现在还能记得自己熬夜(12:00睡觉…)写完第一篇网易博文后的兴奋之情,那个时候博客都是当日记写的…..后来社交网络兴起,碎片化文字时代来临,人们热衷于向别人高频率的展示自己的生活,到处刷着存在感,却很少真正的为自己记录着些什么。 宜居带目录中将会是我的生活随笔,我为它添加了简单的图灵测试,仅仅是不想让搜索引擎收录。这部分的更新主要看心情。

To be continue…