smallow 9 anos atrás
pai
commit
b5e381031a

+ 10 - 0
common/src/github.com/luicfer/cx-extractor/doc.go

@@ -0,0 +1,10 @@
+// extractor project doc.go
+
+/*
+extractor document
+
+extractor main content from html
+
+use algorithm https://code.google.com/p/cx-extractor/
+*/
+package extractor

+ 80 - 0
common/src/github.com/luicfer/cx-extractor/extractor.go

@@ -0,0 +1,80 @@
+package extractor
+
+import (
+	"regexp"
+	"strings"
+)
+
+const blkSize int = 3
+
+//remove html tag
+func strip(src string) string {
+	src = strings.ToLower(src)
+	re, _ := regexp.Compile(`<!doctype.*?>`)
+	src = re.ReplaceAllString(src, "")
+	re, _ = regexp.Compile(`<!--.*?-->`)
+	src = re.ReplaceAllString(src, "")
+	re, _ = regexp.Compile(`<script[\S\s]+?</script>`)
+	src = re.ReplaceAllString(src, "")
+	re, _ = regexp.Compile(`<style[\S\s]+?</style>`)
+	src = re.ReplaceAllString(src, "")
+	re, _ = regexp.Compile(`<.*?>`)
+	src = re.ReplaceAllString(src, "")
+	re, _ = regexp.Compile(`&.{1,5};|&#.{1,5};`)
+	src = re.ReplaceAllString(src, "")
+	src = strings.Replace(src, "\r\n", "\n", -1)
+	src = strings.Replace(src, "\r", "\n", -1)
+	return src
+}
+
+//parse block
+func parse(src string) ([]string, []int) {
+	var (
+		lines   []string
+		blksLen []int
+	)
+	array := strings.Split(src, "\n")
+	for _, a := range array {
+		a = strings.Replace(a, " ", "", -1)
+		lines = append(lines, a)
+	}
+	blen := 0
+	for i := 0; i < blkSize; i++ {
+		blen += len(lines[i])
+	}
+	blksLen = append(blksLen, blen)
+	for i := 1; i < len(lines)-blkSize; i++ {
+		blen = blksLen[i-1] + len(lines[i-1+blkSize]) - len(lines[i-1])
+		blksLen = append(blksLen, blen)
+	}
+	return lines, blksLen
+}
+
+// Extractor main content from html
+func Extractor(html string) string {
+	lines, blksLen := parse(strip(html))
+	i, max := 0, 0
+	blkNum := len(blksLen)
+	plainText := ""
+	for i < blkNum {
+		for i < blkNum && blksLen[i] == 0 {
+			i++
+		}
+		if i > blkNum {
+			break
+		}
+		curTextLen, portion := 0, ""
+		for i < blkNum && blksLen[i] > 0 {
+			if lines[i] != "" {
+				portion += lines[i] + "\n"
+				curTextLen += len(lines[i])
+			}
+			i++
+		}
+		if curTextLen > max {
+			plainText = portion
+			max = curTextLen
+		}
+	}
+	return plainText
+}

+ 16 - 0
common/src/github.com/luicfer/cx-extractor/extractor_test.go

@@ -0,0 +1,16 @@
+package extractor
+
+import (
+	"io/ioutil"
+	"testing"
+)
+
+func Benchmark_Extractor(b *testing.B) {
+	b.StopTimer()
+	f, _ := ioutil.ReadFile("./test")
+	html := string(f)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Extractor(html)
+	}
+}

+ 352 - 0
common/src/github.com/luicfer/cx-extractor/test

@@ -0,0 +1,352 @@
+
+
+<!DOCTYPE html>
+<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
+<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
+<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <title>谈谈 React Native - 唐巧的技术博客</title>
+  <meta name="author" content="唐巧">
+
+  
+  <meta name="description" content="前言 几天前,Facebook 在 React.js Conf 2015 大会上推出了 React Native(视频链接)。我发了一条微博(地址),结果引来了 100 多次转发。为什么 React Native 会引来如此多的关注呢?我在这里谈谈我对 React Native 的理解。 &hellip;">
+  
+
+  <!-- http://t.co/dKP3o1e -->
+  <meta name="HandheldFriendly" content="True">
+  <meta name="MobileOptimized" content="320">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+
+  
+  <link rel="canonical" href="http://blog.devtang.com/blog/2015/02/01/talk-about-react-native">
+  <link href="/favicon.png" rel="icon">
+  <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
+  <link href="/stylesheets/data-table.css" media="screen, projection" rel="stylesheet" type="text/css" />
+  <link href="/atom.xml" rel="alternate" title="唐巧的技术博客" type="application/atom+xml">
+  <script src="/javascripts/modernizr-2.0.js"></script>
+  <!-- googleapis is fucked by gfw -->
+  <script src="http://cdn.staticfile.org/jquery/1.9.1/jquery.min.js"></script>
+  <script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/libs/jquery.min.js"%3E%3C/script%3E'))</script>
+  <script src="/javascripts/octopress.js" type="text/javascript"></script>
+  <script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-28029597-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+
+  
+
+</head>
+
+<body   >
+  <header role="banner"><hgroup>
+  <h1><a href="/">唐巧的技术博客</a></h1>
+  
+    <h2>记录下自己学习的点滴</h2>
+  
+</hgroup>
+
+</header>
+  <nav role="navigation"><ul class="subscription" data-subscription="rss">
+  <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
+  
+</ul>
+  
+<form action="http://google.com/search" method="get">
+  <fieldset role="search">
+    <input type="hidden" name="q" value="site:blog.devtang.com" />
+    <input class="search" type="text" name="q" results="0" placeholder="Search"/>
+  </fieldset>
+</form>
+  
+<ul class="main-navigation">
+  <li><a href="/">首页</a></li>
+  <li><a href="/blog/archives">所有文章</a></li>
+  <li><a href="/blog/categories/ios/">iOS开发专题</a></li>
+  <li><a href="http://weibo.com/tangqiaoboy" target="_blank">我的微博</a></li>
+</ul>
+
+</nav>
+  <div id="main">
+    <div id="content">
+      <div>
+<article class="hentry" role="article">
+  
+  <header>
+    
+      <h1 class="entry-title">谈谈 React Native</h1>
+    
+    
+      <p class="meta">
+        
+
+
+
+
+
+
+
+
+  
+
+
+<time datetime="2015-02-01T16:27:43+08:00" pubdate data-updated="true">Feb 1<span>st</span>, 2015</time>
+        
+      </p>
+    
+  </header>
+
+
+<div class="entry-content"><p><img src="/images/react-js.jpg"></p>
+
+<h2>前言</h2>
+
+<p>几天前,Facebook 在 React.js Conf 2015 大会上推出了 React Native(<a href="https://www.youtube.com/watch?v=7rDsRXj9-cU">视频链接</a>)。我发了一条微博(<a href="http://www.weibo.com/1708947107/C1WHHwqZv?from=page_1005051708947107_profile&amp;wvr=6&amp;mod=weibotime&amp;type=comment#_rnd1422782358309">地址</a>),结果引来了 100 多次转发。为什么 React Native 会引来如此多的关注呢?我在这里谈谈我对 React Native 的理解。</p>
+
+<p>一个新框架的出现总是为了解决现有的一些问题,那么对于现在的移动开发者来说,到底有哪些问题 React Native 能涉及呢?</p>
+
+<h3>人才稀缺的问题</h3>
+
+<p>首先的问题是:移动开发人才的稀缺。看看那些培训班出来的人吧,经过 3 个月的培训就可以拿到 8K 甚至上万的工作。在北京稍微有点工作经验的 iOS 开发,就要求 2 万一个月的工资。这说明当前移动互联网和创业的火热,已经让业界没有足够的开发人才了,所以大家都用涨工资来抢人才。而由于跨平台的框架(例如 PhoneGap,RubyMotion)都还是不太靠谱,所以对于稍微大一些的公司,都会选择针对 iOS 和 Android 平台分别做不同的定制开发。而 JavaScript 显然是一个群众基础更广的语言,这将使得相关人才更容易获得,同时由于后面提到的代码复用问题得到解决,也能节省一部分开发人员。</p>
+
+<h3>代码复用的问题</h3>
+
+<p>React Native 虽然强调自己不是 “Write once, run anywhere&#8221; 的框架,但是它至少能像 Google 的 <a href="https://github.com/google/j2objc">j2objc</a> 那样,在 Model 层实现复用。那些底层的、与界面无关的逻辑,相信 React Native 也可以实现复用。这样,虽然 UI 层的工作还是需要做 iOS 和 Android 两个平台,但如果抽象得好,Logic 和 Model 层的复用不但可以让代码复用,更可能实现底层的逻辑的单元测试。这样移动端的代码质量将更加可靠。</p>
+
+<p>其实 React Native 宣传的 &ldquo;Learning once, write anywhere&rdquo; 本身也是一种复用的思想。大家厌烦了各种各样的编程语言,如果有一种语言真的能够统一移动开发领域,对于所有人都是好事。</p>
+
+<h3>UI 排版的问题</h3>
+
+<p>我自己一直不喜欢苹果新推出的 AutoLayout 那套解决方案,其实 HTML 和 CSS 在界面布局和呈现上深耕多年,Android 也是借鉴的 HTML 的那套方案,苹果完全可以也走这套方案的。但是苹果选择发明了一个 Constraint 的东西来实现排版。在企业的开发中,其实大家很少使用 Xib 的,而手写 Constraint 其实是非常痛苦的。所以出现了 <a href="https://github.com/Masonry/Masonry">Masonry</a> 一类的开源框架来解决这类同行的痛苦。</p>
+
+<p>我一直在寻找使用类似 HTML + CSS 的排版,但是使用原生控件渲染的框架。其实之前 <a href="https://github.com/gavinkwoe/BeeFramework">BeeFramework</a> 就做了这方面的事情。所以我还专门代表 InfoQ 对他进行过采访。BeeFramework 虽然开源多年,而且有 2000 多的 star 数,但是受限于它自身的影响力以及框架的复杂性,一直没有很大的成功。至少我不知道有什么大的公司采用。</p>
+
+<p>这次 Facebook 的 React Native 做的事情相比 <a href="https://github.com/gavinkwoe/BeeFramework">BeeFramework</a> 更加激进。它不但采用了类似 HTML + CSS 的排版,还把语言也换成了 JavaScript,这下子改变可以称作巨大了。但是 Facebook 有它作为全球互联网企业的光环,相信会有不少开发者跟进采用 React Native。</p>
+
+<p>不过也说回来,Facebook 开源的也不一定都好,比如 <a href="https://github.com/facebookarchive/three20">three20</a> 就被 Facebook 放弃了,但是不可否认 <a href="https://github.com/facebookarchive/three20">three20</a> 作为一个框架,在那个时期的特定价值。所以 React Native 即使没有成功,它也将人们关注的焦点放在了移动开发的效率上了。很可能会有越来越多相关的框架因此涌现出来。</p>
+
+<h3>MVVM</h3>
+
+<p>MVVM 在 Web 开发领域相当火热,而 iOS 领域的 <a href="https://github.com/ReactiveCocoa/ReactiveCocoa">ReactiveCocoa</a> 虽然很火,但是还是非常小众。纠其原因,一方面是 ReactiveCocoa 带来的编程习惯上的改变实在太大,ReactiveCocoa 和 MVVM 的学习成本还是很高。另一方面是 ReactiveCocoa 在代码可读性、可维护性和协作上不太友好。</p>
+
+<p>而 Web 开发领域对 MVVM 编程模式的接受程度就大不相同了,在 Web 开发中有相当多的被广泛使用的 MVVM 的框架,例如 <a href="http://en.wikipedia.org/wiki/AngularJS">AngularJS</a>。相信 React Native 会推动 MVVM 应用在移动端的开发。</p>
+
+<h3>动态更新</h3>
+
+<p>终于说到最 &ldquo;鸡冻人心&rdquo; 的部分了。你受够了每次发新版本都要审核一个星期吗?苹果的审核团队在效率上的低下,使得我们这一群狠不得每天迭代更新一版的敏捷开发团队被迫每 2 周或 1 个月更新一次版本。很多团队上一个版本还没审核结束,下一个版本就做好了。</p>
+
+<p>React Native 的语言是基于 JavaScript,这必然会使得代码可以从服务器端动态更新成为可能。到时候,每天更新不再是梦想。当然,代码的安全性将更一步受到挑战,如何有效保护核心代码的安全将是一个难题。</p>
+
+<h2>总结</h2>
+
+<p>不管怎么样,这确确实实是一个移动互联网的时代,我相信随着几年的发展,移动互联网的开发生态也会积累出越来越多宝贵的框架,以支撑出更加伟大的 App 出现。作为一个移动开发者,我很高兴能够成为这个时代的主角,用移动开发技术改变人们的生活。</p>
+
+<p>愿大家珍惜这样的机会,玩得开心~</p>
+</div>
+
+
+  <footer>
+    <p class="meta">
+      
+  
+
+<span class="byline author vcard">Posted by <span class="fn">唐巧</span></span>
+
+      
+
+
+
+
+
+
+
+
+  
+
+
+<time datetime="2015-02-01T16:27:43+08:00" pubdate data-updated="true">Feb 1<span>st</span>, 2015</time>
+      
+
+<span class="categories">
+  
+    <a class='category' href='/blog/categories/ios/'>iOS</a>
+  
+</span>
+
+
+    </p>
+    <p class="meta">
+      关注我的「iOS开发」微信公众号,每天获得精选的 iOS 开发文章和创业心得:<br>
+<img src="/images/weixin-qr.jpg" />
+
+<br>原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh" id="">Creative Commons BY-NC-ND 3.0</a>
+
+    </p>
+    
+      <div class="sharing">
+  
+  
+  
+  
+    <style>
+    .flash-video{display:none;}
+</style>
+<!-- JiaThis Button BEGIN -->
+<div id="ckepop">
+<span class="jiathis_txt">分享到:</span>
+<a class="jiathis_button_tsina">新浪微博</a>
+<a class="jiathis_button_t163">网易微博</a>
+<a class="jiathis_button_tqq">腾讯微博</a>
+<a class="jiathis_button_renren">人人网</a>
+<a class="jiathis_button_douban">豆瓣</a>
+
+<a href="http://www.jiathis.com/share?uid=1574434" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank">更多</a>
+<a class="jiathis_counter_style"></a>
+</div>
+<script type="text/javascript" >
+var jiathis_config={
+    data_track_clickback:true,
+    sm:"t163,tsina,tqq,renren,douban",
+    summary:"",
+    hideMore:false
+}
+</script>
+<script type="text/javascript" src="http://v2.jiathis.com/code_mini/jia.js?uid=1574434" charset="utf-8"></script>
+<!-- JiaThis Button END -->
+
+<br />
+<!-- UY BEGIN -->
+<div id="uyan_frame"></div>
+<script type="text/javascript" id="UYScript" src="http://v1.uyan.cc/js/iframe.js?UYUserId=89581" async=""></script>
+<!-- UY END -->
+
+  
+</div>
+
+    
+    <p class="meta">
+      
+        <a class="basic-alignment left" href="/blog/2015/01/31/write-sdk-tips/" title="Previous Post: 写iOS SDK注意事项">&laquo; 写iOS SDK注意事项</a>
+      
+      
+        <a class="basic-alignment right" href="/blog/2015/02/05/ios-weekly-38/" title="Next Post: iOS移动开发周报-第38期">iOS移动开发周报-第38期 &raquo;</a>
+      
+    </p>
+  </footer>
+</article>
+
+</div>
+
+<aside class="sidebar">
+  
+    <section>
+  <h1>赞助商</h1>
+  <p>
+     <a href="http://www.pgyer.com" target="_blank"><img width="260px" src="/images/ad_pgyer.png" /></a>
+  </p>
+</section>
+<section>
+  <h1>Recent Posts</h1>
+  <ul id="recent_posts">
+    
+      <li class="post">
+        <a href="/blog/2015/11/14/charles-introduction/">Charles 从入门到精通(中国5折特惠)</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/11/02/mvc-and-mvvm/">被误解的 MVC 和被神化的 MVVM</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/10/25/one-on-one-summary/">浅析一对一沟通</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/10/22/talk-with-zm-about-ios-security/">iOS 比 Android 还不安全? - 记一次和阿里资深安全工程师蒸米的交流</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/10/07/why-fresh-wants-to-do-server-dev/">写给那些傻傻的,想做服务器开发的应届生</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/09/03/how-to-monitor-data/">数据的秘密(下)- 如何分析数据</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/09/02/why-we-need-monitor-data/">数据的秘密(上)- 为什么要关注数据</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/08/22/reverse-book-summary/">《逆转》读书心得</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/08/15/talk-about-execution/">我所理解的执行力</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/08/02/the-story-of-success-book-summary/">《异类》读书心得</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/08/01/become-a-tech-leader-summary/">《成为技术领导者》读书心得</a>
+      </li>
+    
+      <li class="post">
+        <a href="/blog/2015/07/11/ios-security-book-recommendation/">让我们再谈谈 iOS 安全</a>
+      </li>
+    
+  </ul>
+</section>
+<section>
+  <h1>About Me</h1>
+  <p>InfoQ编辑, 《<a href="http://item.jd.com/11598468.html" target="_blank">iOS开发进阶</a>》作者, 在猿题库创业。<br/>
+      <br/>Java开发工程师,曾开发网易邮箱、微博。
+      <br/>iOS开发工程师,曾开发有道云笔记、猿题库、小猿搜题。
+  </p>
+</section>
+
+  
+</aside>
+
+
+    </div>
+  </div>
+  <footer role="contentinfo"><p>
+  &copy; 2015 - 唐巧 -
+  <span class="credit">基于 <a href="http://octopress.org" target="_blank">Octopress</a></span>
+  <span class="credit">, 感谢 <a href="http://gitcafe.com/signup?invited_by=tangqiaoboy" target="_blank">GitCafe</a> 为本站提供存储空间</span>
+</p>
+
+</footer>
+  
+
+
+
+
+
+
+
+
+
+<script src=" http://tjs.sjs.sinajs.cn/open/api/js/wb.js?appkey=2351546126" type="text/javascript" charset="utf-8"></script>
+<script>
+WB2.anyWhere(function(W){
+W.widget.followButton({
+    uid: 1708947107,
+    id: "wb_follow_btn"
+    });
+});
+</script>
+
+
+</body>
+</html>