默认
发表评论 3
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
请教大佬即时通讯网如何整理 <tcp/ip详解> Web在线阅读版的?
阅读(27546) | 评论(3 收藏 淘帖
想请教站长是如何整理的这本书,难道是一页一页手工整理?还望大佬给个提示,
谢谢!

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

标签:TCPIP详解
上一篇:不为人知的网络编程(八):从数据传输层深度解密HTTP下一篇:技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结
推荐方案
评论 3
即时通讯网的“《TCP/IP详解 卷1:协议》在线阅读版”,全网没有Web在线版,只能从网上流传的PDF版来弄,过程很繁杂。

分成了下面几步:

第一步:先一章一章将PDF导出HTML文件(用下面这个工具,经过多个版本比对,下面这个版本生成的html最有规则)
请教大佬即时通讯网如何整理 <tcp/ip详解> Web在线阅读版的?_1111.jpg

第二步:将生成的HTML,进行格式处理(因为工具生成时,里面有很多无意义的字符,比如每隔一个字都会有一个无意义的空格等。为此,我还写了个小程序,代码就像下面这样)
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.eva.epc.common.file.FileHelper;

public class Launch
{
        public final static String WEBSITE_NAME = "即时通讯网(52im.net)";
        public final static String BOOK_NAME = "TCP/IP详解卷1 协议";
        public final static String CHAPTER_NAME = "缩略语";
        
        public final static String BOOK_NAME_FOR_PAGNUM = "TCP/IP详解,卷1:协议";
        public final static String CHAPTER_NAME_FOR_PAGNUM = "缩略语";
        
        public static void main(String[] args) throws Exception
        {
//                String originalPath = "C:\\Documents and Settings\\Administrator\\桌面\\acrobat-8\\去掉回车换行+格式化后001.htm";
                String originalPath = "C:\\xampp\\htdocs\\extend\\docs\\book\\tcpip\\vol1\\h\\index.html";
                String originalText = FileHelper.readStringFromFile2(originalPath);
                String resultText = FileHelper.readStringFromFile2(originalPath);
//                System.out.println("内容是:"+originalText);
                
                originalText= resultText = truncateAndReplaceWithElementContent_P(originalText, resultText);
                
//                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
//                                , "<SPAN style=(.*?)>(.*?)</SPAN>", null, null);
                originalText= resultText = truncateAndReplaceWithElementContent_SPAN(originalText, resultText);
                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
                                , "<H4(.*?)>(.*?)</H4>", "<h4 id=\"hh_?\" class=\"net52im_h4_sectitle\">", "</h4>");
                
//                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
//                        , "<P style=(.*?)>(.*?)</P>","<P>","</P>");
                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
                                , "<ol style=(.*?)>(.*?)</ol>","<ol class=\"net52im_ol\">","</ol>");
                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
                                , "<LI style=(.*?)>(.*?)</LI>","<li><span>","</span></li>");
                originalText= resultText = truncateAndReplaceWithElementContent(originalText, resultText
                                , "<TD(.*?)>(.*?)</TD>","<td>","</td>");
//                resultText = truncateAndReplaceWithElementContent(originalText, resultText
//                                , "<TD(.*?)/>");
                
                originalText= resultText = truncateAndReplaceWithElementContent_IMG(originalText, resultText);
                
                FileHelper.writeStringToFile(resultText
                                , "C:\\Documents and Settings\\Administrator\\桌面\\"+System.currentTimeMillis()+".html");
        }
        
        // 处理SPAN元素的方法(有额外条件和特殊处理)
        private static String truncateAndReplaceWithElementContent_SPAN(String originalText
                        , String resultText)
        {
                String pattern1 = 
                                "<SPAN style=(.*?)>(.*?)</SPAN>";
//                                "<SPAN(.*?)>(.*?)</SPAN>";

                // 创建 Pattern 对象
                Pattern r = Pattern.compile(pattern1);

                // 现在创建 matcher 对象
                Matcher m = r.matcher(originalText);
                while (m.find()) 
                {
                        String line = m.group();
                        String linePurText = getElementContent(line);

                        // 代码或命令
                        if(line.contains("monospace") && line.contains("Courier"))
                        {
                                resultText = resultText.replace(line
                                                // 还要把中间每个字符间夹杂的一个空格给去掉
                                                , "<span class=\"net52im_span_code\">"+(linePurText.replace(" ", "").trim())+"</span>");
                        }
                        // 其它情况下的SPAN只取内容
                        else
                        {
                                resultText = resultText.replace(line
//                                                , linePurText.trim()
                                                // 将T C P / I P 这样的内容里的空格全去掉
                                                , processSpaceForSPAN(linePurText.trim())
                                                );
                        }
                }

                return resultText;
        }
        
        // 【本方法一定要放到各种元素处理前调用(不然会打乱特殊元素的附加处理)!!】处理P无法元素的方法(有额外条件和特殊处理)
        private static String truncateAndReplaceWithElementContent_P(String originalText
                        , String resultText)
        {
                String pattern1 = "<P style=(.*?)>(.*?)</P>";

                // 创建 Pattern 对象
                Pattern r = Pattern.compile(pattern1);

                // 现在创建 matcher 对象
                Matcher m = r.matcher(originalText);
                while (m.find()) 
                {
                        String line = m.group();
                        String linePurText = getElementContent(line);

                        // 文内配图的说明文字(pdf转成的html里可能会错误地存在正常P变成配图文字的P,到时校订时手动改吧,没其它办法)
                        if(line.contains("text-align:center;") && line.contains("text-indent:0px"))
                        {
                                resultText = resultText.replace(line
                                                , "<p class=\"net52im_p_imgdesc\">"+linePurText.trim()+"</p>");
                        }
                        else if(line.contains("text-indent:26px"))
                        {
                                resultText = resultText.replace(line
                                                , "<p class=\"net52im_p_quote\">"+linePurText.trim()+"</p>");
                        }
                        // 其它情况下的P清空各种属性
                        else
                        {
                                resultText = resultText.replace(line
                                        , "<p>"+linePurText.trim()+"</p>");
                        }
                }

                return resultText;
        }
        
        // 处理IMG无法元素的方法(有额外条件和特殊处理)
        private static String truncateAndReplaceWithElementContent_IMG(String originalText
                        , String resultText)
        {
                String pattern1 = "<IMG (.*?)>";

                // 创建 Pattern 对象
                Pattern r = Pattern.compile(pattern1);

                // 现在创建 matcher 对象
                Matcher m = r.matcher(originalText);
                while (m.find()) 
                {
                        String line = m.group();

                        // 奇数页的页码显示
                        if(line.contains("width=560") && line.contains("height=63"))
                                //
                                //
                        {
                                resultText = resultText.replace(line
                                                , "<div id=\"p\" class=\"net52im_p_pageji\">" +
                                                                "<p>"+Launch.CHAPTER_NAME_FOR_PAGNUM+"<span>-1</span>" +
                                                                "<a title=\"即时通讯网 - 即时通讯开发者社区!\" target=\"_blank\" " +
                                                                "onmouseover=\"this.className='no_opacity'\" onmouseout=\"this.className=''\" " +
                                                                "href=\"http://www.52im.net\"></a><img alt=\"____delete_this_img____\""+Launch.getImgSrc(line)+"></p></div>"
                                                );
                        }
                        // 偶数页的页码显示
                        else if(line.contains("width=563") && line.contains("height=63"))
                        {
                                resultText = resultText.replace(line
                                                , "<div id=\"p\" class=\"net52im_p_pageou\">" +
                                                                "<p><span>-2</span>"+Launch.BOOK_NAME_FOR_PAGNUM+
                                                                "<a title=\"即时通讯网 - 即时通讯开发者社区!\" target=\"_blank\" " +
                                                                "onmouseover=\"this.className='no_opacity'\" onmouseout=\"this.className=''\" " +
                                                                "href=\"http://www.52im.net\"></a><img alt=\"____delete_this_img____\""+Launch.getImgSrc(line)+"></p></div>"
                                                );
                        }
                        // 文内配图
                        else
                        {
                                resultText = resultText.replace(line
                                                , "<p class=\"net52im_p_img\"><a href=\"http://www.52im.net\" title=\"即时通讯网 - 即时通讯开发者社区!\" target=\"_blank\"><img alt=\""+Launch.CHAPTER_NAME+"_"+Launch.BOOK_NAME+"_"+Launch.WEBSITE_NAME
                                                +"\" "+Launch.getImgSrc(line)+"></a></p>");
                        }
                }

                return resultText;
        }
        
        // 通用去掉元素首尾的方法
        private static String truncateAndReplaceWithElementContent(String originalText
                        , String resultText, String pattern1
                        , String newElementStart, String newElementEnd)
        {
                // 创建 Pattern 对象
                Pattern r = Pattern.compile(pattern1);

                // 现在创建 matcher 对象
                Matcher m = r.matcher(originalText);
                while (m.find()) 
                {
                        String line = m.group();
                        String linePurText = getElementContent(line);
                        
                        resultText = resultText.replace(line
                                        , (newElementStart==null?"":newElementStart)
                                                +linePurText.trim()
                                                +(newElementEnd==null?"":newElementEnd));
                }
                
                return resultText;
        }
        
        // 返回一个文本元素的内容部分
        private static String getElementContent(String htmlElement)
        {
                String ret = "";
                if(htmlElement != null && !htmlElement.equals(""))
                {
                        int s = htmlElement.indexOf(">");
                        int e = htmlElement.lastIndexOf("<");
//                        System.out.println(htmlElement.substring(s+1, e));
                        ret = htmlElement.substring(s+1, e);
                }
                return ret;
        }
        
        private static String getImgSrc(String htmlElement)
        {
                String ret = "";
                if(htmlElement != null && !htmlElement.equals(""))
                {
                        int s = htmlElement.indexOf("src");
                        int e = htmlElement.lastIndexOf(">");
//                        System.out.println(str.substring(s, e));
                        ret = htmlElement.substring(s, e);
                }
                return ret;
        }
        
        // 处理SPAN内文本的多余空格:将诸如“机需求R F C拷贝[Braden 1989a],阅读有关应用于T C P / I P”
        // 处理成“机需求RFC拷贝[Braden 1989a],阅读有关应用于TCP/IP”,注意两个英文单词间的空格要保留
        public static String processSpaceForSPAN(String originalStr)
        {
                // 创建 Pattern 对象
                Pattern r = Pattern.compile("\\w{2} \\b");// 先找到2个字母+一个空格结尾的字符串

                // 现在创建 matcher 对象
                Matcher m = r.matcher(originalStr);
                int i = 0;
                while (m.find()) 
                {
                        i++;
                        String line = m.group();
                        System.out.println("原行:"+line);//+","+(line.replaceAll(" ", "@")));
                        // 【1】先保留两个单词间的穿格:将两个字母+一个空格的字符中的空
                        // 格替换成特殊占位字符(确保不与原文本内的正常字符碰装即可)
                        originalStr = originalStr.replaceAll(line, line.replaceAll(" ", "々ぁゅヅ"));
                        System.out.println("1次replace:"+originalStr);
                }

                System.out.println(i);
                // 完全没有匹配到两个单词的情况,简单处理即可
                if(i == 0)
                {
                        originalStr=originalStr.replaceAll(" ", "");
                        System.out.println("简单replace:"+originalStr);
                }
                else // 此步是接上面的循环,放在外面的原因是防止多于两个单词连着
                         // 时:如“Internet Protocol Suite”,会被错误地处理为“InternetProtocolSuite”
                         // ,因为循环应该作为了才进行空格的replace!
                {
                        // 【2】将第【1】步处理完的原字符串中,一个空格全部去掉
                        originalStr=originalStr.replaceAll(" ", "");
                        System.out.println("2次replace:"+originalStr);
                        // 【3】将之前单词间的空格恢复出来
                        originalStr=originalStr.replaceAll("々ぁゅヅ", " ");
                        System.out.println("3次replace:"+originalStr);
                }

                return originalStr;
        }
}

第三步:根据生成的HTML,来进行CSS样式美化,这是个主观创新的过程,因为没有可以参考的样式,只能自已凭着自已的审美能力看着办进行美化

第四步:第三步先对某个章节进行范本式美化完成后,根据生成的HTML的规律,再用Editplus这样的工具对每一章进行批量样式替换等。如此反复。

以上4步完成,一本Web版书籍就诞生了。理论上,这需要极高的耐心的,不然是搞不定的。而且,别小看这一个PDF转Web过程,它需要一些相应的技术技能,不然重复工作量更大。
谢谢大佬的无私指点!
第一步实在想不到,2、3步技术难度不小。
关键站长的前端能力也非常高。
再次感谢大佬,接下来我忙完论文的事情会实践下,
到时有问题还要麻烦大佬!
引用:vimerbf 发表于 2019-04-27 09:36
谢谢大佬的无私指点!
第一步实在想不到,2、3步技术难度不小。
关键站长的前端能力也非常高。

嗯嗯,能把这样的事情做下来,都是极有定力和耐心的人。。
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部