Monday, February 16, 2009

笑话一则

唐僧师徒一行经历九九八十一难终于见到了如来佛求取真经
如来问:"你们带U盘了么?"
唐僧师徒。。。。
如来又问:"移动硬盘呢?"
。。。。。
如来继续问:"IPOD也可以哇"
悟空挖起耳朵来
如来叹了口气:"那你们就原路回去吧,我用QQ传给你们
唐僧:靠,早知道加你QQ就完了,老子还走这么远干嘛

如来突然想起什么,
又问:你们带MP4没有? 
唐僧师徒:…… 
如来:那你们路上是怎么娱乐的? 
唐僧师徒:打怪升级

Tuesday, February 10, 2009

sqlite3 "database disk image is malformed" 错误

今天遇到 sqlite3 数据库错误 "database disk image is malformed",G 了一下,搞定,遂记录,帮人帮己。

假设原数据库名 abc.sqlite3

#bash
>>sqlite3 abc.sqlite3
然后
.output "_XB_D.tmp"
.dump
.quit

再建个新数据库 abc2.sqlite3

#bash
>>sqlite3 abc2.sqlite3
然后
.read "_XB_D.tmp"
.quit

然后修复原来的数据库名和文件权限,应该就没事了。

以上代码来自 文件 RepairUR.zip


参考 Forum of kinook

Saturday, February 7, 2009

[emeditor宏] 插入HTML标签

不知道如何解释,用过 DW 的人应该知道 Ctrl + T ,这个就是模拟那个的,不过没有自动提示就是了。
建议将这个宏也设置快捷键 Ctrl + T 。(具体设置请参见 Emeditor Macros Help)

输入(将~换成空格)输出
table <table>{原来选中的文字}</table>
table~ <table width="100%" border="0" cellpadding="0" cellspacing="0">{原来选中的文字}</table>
table~,tbody,tr,td <table width="100%" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td>{原来选中的文字}</td></tr></tbody></table>
div#abc,p <div id="abc"><p>{原来选中的文字}</p>>div>
div#abc,p,a~,img~ <div id="abc"><p><a href="#"><img src="" width="" height=""/>{原来选中的文字}</a></p>>div>
规则:
  • 将输入作为标签名,补齐开始和结束标所需
  • 如果只是签名和空格,则将空格用一些默认属性填充,具体见 autoprop
  • 遇到逗号(,),则将逗号分割的各词单独补齐成为标签,并将后面的标签添加为前面标签的子标签
  • 之前选中的文字则作为最内层标签的内容,如果最内层是自闭合标签,则之前选中的内容跟随最内层标签后面
待完善功能:
  • 是否使用其他符号替代空格来补齐默认属性
  • 可以更好的交互编辑,类似 TextMate 的 tab 模式
  • 增加同层节点,现在只能创建多层子节点
var tag, autoprop={ a: 'href="#"', div: 'class=""', style: 'type="text/css"', link: 'type="text/css" rel="stylesheet" href=""', script: 'type="text/javascript" src=""', input: 'type="" name="" value=""', img: 'src="" width="" height=""', table: 'width="100%" border="0" cellpadding="0" cellspacing="0"', iframe: 'frameborder="0" scrolling="no" width="" height="" src=""' }, sigletag={'br':1, 'link':1, 'hr':1, 'col':1, 'input':1, 'meta':1, 'img':1}; if(tag = prompt("请输入标签:", "div")){ if(tag.indexOf(',')==-1){ var t = buildTag(tag); document.selection.Text = t[1] + document.selection.Text + t[2]; }else{ var tags = tag.split(/, */), rstr = '', rstr2 = ''; for(var i=0,iM=tags.length;i<iM;i++){ tag = buildTag(tags[i]); rstr += tag[1]; rstr2 = tag[2] + rstr2; } document.selection.Text = rstr + document.selection.Text + rstr2; } } /* 返回 [标签,起始标签,结束标签] */ function buildTag(t){ var tagname=t.split(/ +/)[0]; var autoa = (t == tagname + ' ') && (tagname in autoprop); if(tagname.match(/[#\.]/)){ var id = tagname.match(/#([^\.]+)/), cls = tagname.match(/\.[^\.]+/g); t = tagname = tagname.match(/^([^#\.]+)/)[1]; if(id)t += ' id="' + id[1] + '"'; if(cls){ t += ' class="' + cls.join(' ').replace(/\./g, '').replace(/ +/g, ' ') + '"'; } if(autoa)t += ' '; } if(autoa){ t += autoprop[tagname]; } return [tagname, "<" + t + (tagname in sigletag ? ' />' : '>'), tagname in sigletag ? '' : ("</" + tagname + ">")]; }

date js

关于日期时间操作的 js 函数库 date-js 。简单实用。

/** date set() clone() fmt() Y() ~ FullYear m() ~ Month d() ~ Date H() ~ Hours M() ~ Minutes S() ~ Seconds s() ~ Milliseconds t() ~ Time [static] from() 使用示例 var d = date(), D = new Date(); D.getMonth() == d.m() D.getFullYear() == d.Y() D.setFullYear(1999) == d.Y(1999) D.setHours(8) == d.H(8) d.set('m+1') == D.setMonth(D.getMonth() + 1) d.set('Y2008m0') == (D.setFullYear(2008) && D.setMonth(0)) d.fmt('%Y-%m-%d %H:%M:%S.%s %%s') == '2009-02-04 22:23:45 %s' set() 如果带 +/- 操作,那么表示将相应的项添加或者减少(W 表示增减周.7天.)。 如果不带 +/- 操作,那么: Y 的设置将自动取当前年的前 n 位补齐 Y 不够 4 位的部分,例如 Y34 会被认为是设置 2034 年,Y123 会被认为是设置 2123 年(假设当前时间为 2009年)。 M 的操作会按照月份的数字设定,比如 M1 将设置月份为 1月,M12 设置月份为 12月,M0 则设置为上一年的最后一月(年份会自动减小)。 W 的操作会设置周几,比如,假设当前为周三,那么 W1 会将日期前移 2 天(到周一),W0 会将日期前移 3 天,到上周日,W7 会将日期后移到本周日,如果设置大于 7 也可以,不过应该比较难理解了。 其他按照字面意思进行。 示例: Q: 这个月有多少天? A: d.set('M+1D0').D() Q: 上个月有多少天? A: d.set('D0').D() Q: 5 月有多少天? A: d.set('M6D0').D() Q: 这周的第一天是哪天,最后一天呢(假设第一天是周一)? A: d.set('W1'), d.set('W7') Q: 如果要显示这个月的日历,那么第一天和最后一天是什么(假设第一天是周一)? A: d.set('D1W1'), d.set('M+1D0W7') Q: 上一个问题中,如果所有日历都显示 6 周,那么最后一天如何计算? A: d.set('D1W1'), d.set('D1W7W+5') */ var date = (function(){ function now(){return new date()} function iter(obj, fn, o){ o = o || obj; if(!(obj && typeof obj == 'object')){ return; } var i, l = obj.length; if(typeof l == 'number'){ if(l){ for(i=0;i<l;i++){ if(fn.call(o, obj[i], i, obj) === false){ break; } } } }else{ for(i in obj){ if(obj.hasOwnProperty(i)){ if(fn.call(o, obj[i], i, obj) === false){ break; } } } } return iter; } function mixin(target, source){ for (var x in source) { target[x] = source[x]; } return mixin; } function date(Y, m, d, H, M, S, s){ var r = this; if(this instanceof date){ this._d = new Date; }else{ r = new date; } if(arguments.length){ r.t(new Date(Y, m, d, H, M, S, s).getTime()); } return r; } mixin(date, { conv:{ 'Wm':10080, 'dm':1440, 'WS':604800, 'dS':86400, 'Ws':604800000, 'ds':86400000, 'Hs':3600000, 'Ms':60000, 'Ss':1000, 'ss':1 }, from:function(s){ return new date().set(s); } } ); iter( { Y: 'FullYear', m: 'Month', d: 'Date', H: 'Hours', M: 'Minutes', S: 'Seconds', s: 'Milliseconds', t: 'Time' }, function(v, k){ date.prototype[k] = (function(s,g){ return function(v) { v!==undefined && v!==null && this._d[s](v); return this._d[g](); } })('set' + v, 'get' + v); } ); mixin(date.prototype, { set: function(str){ var d= this; str.replace( /[YmdWHMSs][+-]?\d+/g, function(w){ w= w.match(/(\w)([+-]?)(\d+)/); var f=w[1], //key v= w[3], //value s= w[2]; //type(+/-) if(s==''){ if(f=='Y' && v.length < 4){ v= '' + String(now().Y()).slice(0,4-v.length) + v } if(f=='m'){ v= parseInt(v)-1; d.m(v); }else if(f=='W'){ v= parseInt(v)-d.getDay(); if(v){ d.set('d' + (v>0?'+':'') + v); } }else{ d[f](parseInt(v)) } }else{ v= parseInt(s+v, 10); if(v){ switch(f){ case 'Y': case 'm': d[f](d[f]()+v); break; default:// dWHMSs d.t(d.t() + v * date.conv[f+'s']); break; } } } return '' } ); return this }, fmt: function(str){ if(!str){ str = 'YY-mm-dd HH:MM:SS'; } var d= this; return str.replace( /%([YmdHMS%])/g, function(w, s){ return s == '%' ? s : (('' + d[s]()).replace(/^(\d)$/, '0$1')); } ); }, clone:function(s){ return new date(this.t()).set(s); }, toString: function(){ return this._d.toString.apply(this._d, arguments); }, valueOf: function(){ return this._d.valueOf.apply(this._d, arguments); } } ); //date.prototype.str = date.prototype.format = date.prototype.strfmt = date.prototype.fmt; return { iter: iter, mixin: mixin, date: date, now: now }; })().date;

电脑使用心得 之 Gmail

Gmail
特点
空间比较大(>7G),附件限制还行(<20M)。
支持快捷键,安全链接,快速回复,快捷操作,与 IM 系统整合,附件预览(word, pdf, ppt, 图片, mp3, excel 等),多附件打包下载。
操作前设置(打开快捷键,并将输入法设为英文)
我的邮件管理原则
保持 收件箱(Inbox) 里的邮件最少;
星号和收件箱只临时存放一些待处理或需要特别提醒自己的邮件,星号表示待处理很紧急或重要。真正内容重要的邮件通过标签管理;
多用快捷键可以显著提高时间利用率,平时可以多 ?(问号) 来查看各操作的快捷键;
习惯使用 搜索(Search)功能;
订阅的新闻组通过创建 过滤(filter) 规则自动标签并 存档(Archive),在想看的时候自己去看。如果新闻组提供 RSS,则通过 GReader 订阅;
常用快捷键
C 创建新邮件(shift + c 会在新窗口中创建新邮件)
g, i 查看 收件箱(Inbox) 逗号表示先按 g,然后紧接着按 逗号 后面的按键(不是同时按,加号连接的才同时按,并且按键不分大小写,只是按键而已)
g, a 查看 所有邮件
g, s 查看打星的邮件
还有很多,自己看吧 :)
邮件操作(收件箱,打星邮件,所有邮件等等)
在 收件箱里通过 J/K 键来上下选择邮件,这时候邮件前的方框应该是没有选中的,可以通过 X 键来选中(除了打开邮件外,其他操作都需要选中邮件);
  选中邮件后,虽然一般是先看看邮件内容再做操作的,但是你也可以直接:
    E 存档,把他移出收件箱,之后可以到 所有邮件里找到(说明我不用看内容就知道这个邮件的用处了,最好还是慎用,加入邮件里有你不知道的内容呢!);
    #  删除,只能在 垃圾箱里找了(如果你 30 天都没找,他就没了);
    S 打星,表示这个很重要;
    Shift + i   设置为已读;
    Shift + u  设置为未读(这 2 个有啥用?自己想想吧,我也不知道)
    .  或者 鼠标点击, 打标签或者更多操作(探索一下吧)

  如果需要看看邮件再做操作,那么 O 或者回车 打开邮件,然后:
    如果打开邮件后想返回,按 U 即可;
    如果觉得很垃圾,就 # 把它删除(会被放到 Trash 里去,给你后悔的机会,如果你在 30 天内都对他不理不睬,将自动被完全删除);
    如果觉得觉得需要稍后处理则 J 继续看下一封邮件;
    如果觉得看完即可,则直接 E 存档(把它移出收件箱<我不习惯看到 收件箱里很多邮件>);
      如果想存档并立即看下一封,可以用 y, o (我还没用过..)
    如果觉得很重要则 S 标记个星号(Star),记得及时将不再重要的邮件的星号去掉,太多星号邮件跟没有一样,慢慢的你就又懒得去管理星号了;
    如果邮件应该分类,则在 更多操作里选择相应的标签(Label),此处可以点击那个下拉列表也可以通过 .(英文句点) 调出(标签的具体分类稍后说);
    如果使用了 Gmail 实验室(labs) 里的 任务(Task) 功能,可以 Shift + T 使用当前邮件建立新的 任务;
    如果需要回复(Replay),则直接在邮件下面的输入框里输入就可以,转发也一样方便;
    如果对方也使用 Gmail 并且需要回复的内容较少或者需要回复的内容关联性不强,可以使用聊天的方式回复(ie6 不支持);
标签系统的使用
标签跟文件夹有什么区别?
没什么区别,标签可以当成文件夹使用,标签比文件夹更加灵活易用;
一封邮件可以打上多个标签,就相当于你把一封邮件放到多个文件夹里去;
Gmail 的标签不支持级别,但是你可以自己搞定,比如命名时加 / 来使得标签看起来像是有层级(有插件可以将这样命名的标签显示成树形结构,不过标签少的时候无所谓);
如果打开了 实验室 里的 Goto Label,则在界面中按 g + l 就会弹出一个框让你输入标签,且有自动提示功能,相当方便(前提是你要熟悉自己都建了哪些标签,并且起中文名字会很吃亏);
标签可以设置颜色,你可以设置一些醒目的颜色以标明某些邮件很重要、很垃圾或者很XX;
你可以创建一个过滤规则,对 邮件标题、邮件发送地址 做一些判断,然后把这些邮件打上你喜欢的标签,这样 收件箱里就会五彩斑斓,你也可以决定先看哪个后看那个了;
标签的命名
  • 各种账户(account)信息______________a/XXX
  • 各种论坛/邮件列表(maillist)/新闻组____ml/XXX
  • 工作(work)相关____________________w/XXX
  • 朋友(friend)相关____________________f/XXX
  • 家庭(home/family)相关______________h/XXX
  • 广告信息_________________________ad/XXX
  • 其他_________________________这个就自由发挥吧。
邮件过滤器(Filter)
在界面顶部搜索按钮右侧有个链接 创建过滤器(Create a filter),点击就可以开始创建过滤了,总共 2 步,
设置规则,设置动作。
都很简单,自己试试就行了。
标签、过滤器使用演示
将 "小丽" 发来的邮件都打上标签 h/Xiaoli ,并且在标签面板里将 Xiaoli 标签的颜色设置为大红色,这样以后凡是 小丽 发过来的邮件都会被红色标签打头标出来。
139 邮箱 有个功能是将新邮件以短信的形式发送到手机上,那么你在设置过滤规则的时候可以考虑将上面的邮件转发到你的 139 邮箱,这样就会获得短信通知(之所以这么做是因为 Gmail 还不支持短信通知);

OK,就这么多,
下次说说 聊天(Gtalk)功能,还有一些推荐 设置(Setting)。
希望有用。

另:
这里所说的只是我的一些使用习惯和方式,并没有什么其他意思。
如果你还没有或者不满意自己的习惯可以参考一下我的,
如果你有自己的习惯并愿意公开,欢迎分享。
:)

Friday, February 6, 2009

[Rel] JavaScript正则表达式生成器

看到写的东西,找不到留言的地方,遂自己写一个。

//原始实现 function convertToJsEsc(chars) { var result = ''; for(var i=0; i<chars.length; i++) { var code = chars.charCodeAt(i); switch (code) { case 0x20: result += "\\s"; break; case 0x22: result += "\\\""; break; case 0x27: result += "\\\'"; break; case 0x28: result += "\\("; break; case 0x29: result += "\\)"; break; case 0x2A: result += "\\*"; break; case 0x2B: result += "\\+"; break; case 0x2E: result += "\\."; break; case 0x2F: result += "\\/"; break; case 0x3F: result += "\\?"; break; case 0x5B: result += "\\["; break; case 0x5C: result += "\\\\"; break; case 0x5D: result += "\\]"; break; case 0x7B: result += "\\{"; break; case 0x7D: result += "\\}"; break; default: if(code > 0x1F && code < 0x7F) { result += chars[i]; } else { result += "\\u" + code.toString(16).toUpperCase(); } break; } } return result === "" ? "Nothing to convert" : result; } //我的修改 function convertToJsEsc(chars) { return chars && chars.replace( /([ "'\(\)\*\+\.\/\?\[\\\]\{\}])|([\x1F-\x7F])|(.)/g, function(all, a, b, c){ return a ? ('\\' + (all==' '?'s':all)) : b ? all : ('\\u' + all.charCodeAt().toString(16).toUpperCase()); } ) || 'Nothing to convert'; }

有啥区别?
优点:方便修改
缺点:难于理解。

Thursday, December 4, 2008

自定义滚动条

用法
给需要添加滚动条的 div 添加 class "autoscroller",设置模块高度。
注意,这个 div 只可以包含一个子节点。
html
<div style="height:100px;" class="autoscroller"> <div style="height:150px;"></div> </div> css
.autoscroller{position:relative;overflow:hidden;} .autoscroller .scrollcon{overflow:hidden;} .autoscroller .scrollbar{ position:absolute;right:0;top:0;width:9px; background:#fff;font-size:1px;line-height:1px;} .autoscroller .scrollbar s{ position:absolute;left:3px;top:0;height:100%;width:2px; border-left:1px solid #c3c3c3;background:#000;} .autoscroller .scrollbar i{ width:9px;position:absolute; background:url(scroller_btn.gif) repeat-y 0 0; cursor:n-resize;left:0;top:0;} .autoscroller .scrollbar i b{ background:url(scroller_btn.gif) no-repeat -9px 0; display:block;padding:4px 0 0;} .autoscroller .scrollbar i b b{background-position:-18px 100%;padding:0 0 4px;} .autoscroller .scrollbar i b b b{background-position:100% 50%;}

img

js
//require: jquery, drag, wheel function fix_scrollers(){ var j = jQuery; /* .autoscroller .scrollcon .scrollbar s i b b b*/ j('.autoscroller').each(function(idx, sc){ sc = j(sc); var con = j('<div class="scrollcon"/>').appendTo(sc), con0 = con[0]; con.append(sc.find('>*:first')); var h = [sc[0].offsetHeight, con0.scrollHeight]; if(h[0] - h[1] >= 0)return; var bar = j('<div class="scrollbar"></div>').appendTo(sc), btn = bar.find('>i'); con.css('height', h[0] + 'px'); bar.css('height', h[0] + 'px'); bar.find('>s').css('height', h[0] + 'px'); j(j.dir(btn[0], 'firstChild').pop()).css('height', Math.max(0, (h[0] * h[0] / h[1]) - 8) + 'px'); var btnYA = [0, bar[0].offsetHeight - btn[0].offsetHeight]; var sRate = Math.min(1, btnYA[1] / (h[1] - h[0])), wheelPH = -25 * sRate; var drag_posY = null, drag_top = null; btn.bind('dragstart',function(ev){ drag_posY = ev.offsetY; drag_top = parseInt(btn.css('top')) || 0; }) .bind('drag',function(ev){ var offsetY = ev.offsetY - drag_posY; var top = Math.max(btnYA[0], Math.min(btnYA[1], drag_top + offsetY)); this.style.top = top + 'px'; con0.scrollTop = top / sRate; }); sc.mousewheel(function(ev, delta){ var btnTop = parseInt(btn.css('top')) || 0; if((btnTop==btnYA[0] && delta > 0) || (btnTop==btnYA[1] && delta < 0))return true; btnTop = Math.max(btnYA[0], Math.min(btnYA[1], btnTop + delta * wheelPH)); btn[0].style.top = btnTop + 'px'; con0.scrollTop = btnTop / sRate; return false; }); }); }

Saturday, August 2, 2008

皮_我想创造客户需求,懒得满足客户自己都不知道是什么的需求_光明正大做人_懒得解释 _ 揶揄 _ 要钱没有要命一条~~~~~~~~~~~~~~~~~~~~~

标题是最近的 msn 签名。

要钱没有要命一条:
  看周星驰的介绍,然后深深喜爱的一句话。


揶揄:
  有一天在公司作了这样的事情,当即觉得做错了,就解释了一下,没有道歉。我错了。


懒得解释:
  当时有些懒得解释,就是懒得解释,直到现在都是。却忘记了到底什么事情了。


光明正大做人:
  一直以来 msn 经常隐身,所以这一句话就是以后想上线就上线,再也不要偷偷摸摸了。


我想创造客户需求,懒得满足客户自己都不知道是什么的需求:
  做产品。而不是做服务。服务总会有人喜欢做,服务不是卑躬屈膝,专业的服务,什么该做什么不该做,咨询类服务,而不仅是满足型服务。


皮:
  觉得最近有些皮。皮就是懒散。


解释完毕。