iOS MarkDown解析

1.效果展示

MarkDown組件庫地址

排版1
排版2
排版3
排版4

2.調(diào)用

2.1 NSString+WPMarkDownParse入口

WPMarkDownParse主要是提供了一個NSString的分類,方便調(diào)用;真正的入口在WPMarkDownParseFactory

2.2 WPMarkDownParseFactory

2.2.1 同步異步入口

+ (NSMutableAttributedString *)parseMarkDownWithText:(NSString *)text;
+ (NSMutableAttributedString *)parseMarkDownWithText:(NSString *)text fontSize:(CGFloat)fontSize width:(CGFloat)width猫十;
- (void)parseMarkDownWithText:(NSString *)text finishBlock:(void (^)(NSMutableAttributedString * string))block;
- (void)parseMarkDownWithText:(NSString *)text fontSize:(CGFloat)fontSize width:(CGFloat)width finishBlock:(void (^)(NSMutableAttributedString * string))block;

2.2.2 parseMarkDownWithText

+ (NSMutableAttributedString *)parseMarkDownWithText:(NSString *)text fontSize:(CGFloat)fontSize width:(CGFloat)width{
    NSArray * parseArray = [self setUpParseArray];
    for (WPMarkDownBaseParse * parseModel in parseArray) {
        [parseModel configFontSize:fontSize width:width];
        [parseModel segmentString:&text];
    }
    
    [self replaceBackslash:&text];
    NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:text];
    [self setAttributedDefaultFont:attributedString fontSize:fontSize];
    
    for (WPMarkDownBaseParse * parseModel in parseArray) {
        [parseModel setAttributedString:attributedString];
    }
    return attributedString;
}

2.2.3 setUpParseArray初始化

WPMarkDownParseImage:解析圖片
WPMarkDownParseLink:解析鏈接
WPMarkDownParseQuoteParagraph:解析段落引用
WPMarkDownParseCodeBlock:解析代碼塊
WPMarkDownParseBold:加粗
WPMarkDownParseItalic:斜體
WPMarkDownParseTitle:標(biāo)題
WPMarkDownParseDisorder:無序
WPMarkDownParseOrder:有序

所有的解析類繼承自WPMarkDownBaseParse艘儒,使用策略模式雪猪、模板模式與工廠模式結(jié)合進(jìn)行解析嘹害。

2.2.4 策略模式方法

//解析策略模式
@protocol WPMarkDownParseStrageInterface <NSObject>
- (NSString *)replace:(NSString *)text;
- (void)segmentString:(NSArray *)separatedArray text:(NSString *)text;//分割字符串
- (void)setAttributedString:(NSMutableAttributedString *)attributedString;
@end
  1. 每個類按symbol進(jìn)行分割,如果separatedArray不為空泉手,則進(jìn)行解析,判斷是否滿足條件偶器,加入self.segmentArray中斩萌。
  2. 替換掉markdown的標(biāo)識符缝裤,如鏈接[百度](https:baidu.com),只能顯示百度颊郎,字體高亮憋飞,點(diǎn)擊能跳轉(zhuǎn)到WebView.

2.2.5 replaceBackslash

替換掉轉(zhuǎn)義字符\,即出現(xiàn)反斜杠姆吭,都不解析榛做。

2.2.6 setAttributedString

attributedString 是所有都替換完,才生產(chǎn)的attributedString内狸。
策略模式使得每個類setAttributedString能夠設(shè)置對應(yīng)的屬性检眯,如圖片,高亮昆淡、斜體等锰瘸。

3. 鏈接、圖片解析過程

3.1 WPMarkDownParseLink

  1. 在setUpParseArray初始化昂灵,WPMarkDownParseLink添加到解析parseArray數(shù)組中
  2. 配置fontSize與width
for (WPMarkDownBaseParse * parseModel in parseArray) {
        [parseModel configFontSize:fontSize width:width];
        [parseModel segmentString:&text];
    }
  1. segmentString 按symbo分割获茬,如果分割separatedArray不為空,則wp_markdownParseSegmentString進(jìn)行解析倔既,解析出url于對應(yīng)的title的WPMarkDownParseLinkModel,添加到segmentArray
- (void)wp_markdownParseSegmentString:(NSArray *)separatedArray text:(NSString *)text{
    for (int i = 0; i<separatedArray.count-1; i++) {
        NSString * leftString = separatedArray[I];
        if ([self isBackslash:leftString]) {
            continue;
        }
        WPMarkDownParseLinkModel * urlModel = [[WPMarkDownParseLinkModel alloc] initWithSymbol:self.symbol];
        NSArray * leftStringSeparateArray = [leftString componentsSeparatedByString:@"["];
        if (leftStringSeparateArray.count>0) {
            urlModel.text = leftStringSeparateArray.lastObject;
        }
        NSArray * rightStringSepartedArray = [separatedArray[i+1] componentsSeparatedByString:@")"];
        if (rightStringSepartedArray.count>0) {
            urlModel.url = rightStringSepartedArray.firstObject;
        }
        if (urlModel.text.length && urlModel.url.length) {
            [self.segmentArray addObject:urlModel];//當(dāng)文字與url都不為空時恕曲,才算解析成功
        }        
    }
}
  • 遍歷separatedArray
  • isBackslash上一個字符是轉(zhuǎn)義字符,不添加urlModel
  • 左則的字符查找符號[渤涌,右側(cè)查找)
  • 當(dāng)兩者都找到時佩谣,則匹配成功
  1. 替換用[]的內(nèi)容,替換內(nèi)容实蓬。即wp_markdownParseReplace
  • 遍歷segmentArray茸俭,逐個替換。
  • willBeReplacedString安皱、replaceString用了模板模式调鬓,因?yàn)槊總€解析略有不同。
  1. replaceBackslash替換掉轉(zhuǎn)義字符\酌伊,生成NSMutableAttributedString
  2. 設(shè)置一個默認(rèn)字體大小setAttributedDefaultFont
  3. wp_markdownParseSetAttributedString為鏈接添加下劃線腾窝,和點(diǎn)擊調(diào)整事件
- (void)wp_markdownParseSetAttributedString:(NSMutableAttributedString *)attributedString{
    NSString * text = attributedString.string;
    [self.segmentArray enumerateObjectsUsingBlock:^(WPMarkDownParseLinkModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSRange range = [text rangeOfString:obj.text];
        [attributedString wp_makeAttributed:^(WPMutableAttributedStringMaker * _Nullable make) {
            make.textColor([UIColor blueColor],range);
            make.underlineStyle(NSUnderlineStyleSingle,[UIColor blueColor],range);
        }];
        [attributedString yy_setTextHighlightRange:range color:[UIColor blueColor] backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) {
            [WPWKWebViewController pushWKWebViewController:obj.url title:obj.text];
        }];
    }];
}

3.2 WPMarkDownParseImage

圖片解析或其他解析與鏈接解析大致相同,區(qū)別在于每個細(xì)節(jié)內(nèi)容都不相同居砖。

  1. WPMarkDownParseImage添加到parseArray
  2. 配置字體和寬度configFontSize:fontSize:width
  3. segmentString木模模式虹脯,分割生成segmentArray,并匹配字符
- (void)wp_markdownParseSegmentString:(NSArray *)separatedArray text:(NSString *)text{
    
    for (int i = 0; i<separatedArray.count-1; i++) {
        
        NSString * leftString = separatedArray[I];
        if ([self isBackslash:leftString]) {
            continue;
        }
        WPMarkDownParseImageModel * urlModel = [[WPMarkDownParseImageModel alloc] initWithSymbol:self.symbol];
        NSArray * leftStringSeparteds = [leftString componentsSeparatedByString:@"!["];
        if (leftStringSeparteds.count>1) {
            urlModel.text = leftStringSeparteds.lastObject;
        }
        NSArray * rightSepartedArray = [separatedArray[i+1] componentsSeparatedByString:@")"];
        if (rightSepartedArray.count>0) {
            urlModel.url = rightSepartedArray.firstObject;
        }
        if (urlModel.text.length && urlModel.url.length) {
            [self.segmentArray addObject:urlModel];//當(dāng)文字與url都不為空時奏候,才算解析成功
        }
    }
}
  • 遍歷separatedArray
  • isBackslash上一個字符是轉(zhuǎn)義字符循集,不添加urlModel
  • 左則的字符查找符號![,右側(cè)查找)
  • 當(dāng)兩者都找到時蔗草,則匹配成功

與鏈接不同的是咒彤,圖片的左邊是![,所以防止鏈接被圖片的解析覆蓋疆柔,所以需要把圖片解析放在鏈接解析前面。

  1. 設(shè)置UIImageView
- (void)wp_markdownParseSetAttributedString:(NSMutableAttributedString *)attributedString{
    NSString * text = attributedString.string;
    [self.segmentArray enumerateObjectsUsingBlock:^(WPMarkDownParseLinkModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSRange range = [text rangeOfString:obj.text];
        
        {   /*
             設(shè)置圖片,現(xiàn)在是固定寬高镶柱,可讓url后帶上寬高
             */
            UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.defaultWidth, self.defaultWidth*0.68)];
            [imageView sd_setImageWithURL:[NSURL URLWithString:obj.url] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
                
            }];
            
            imageView.backgroundColor = [UIColor whiteColor];
            NSMutableAttributedString *attachText = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeCenter attachmentSize:imageView.frame.size alignToFont:[UIFont systemFontOfSize:self.defaultFontSize] alignment:YYTextVerticalAlignmentCenter];
            [attachText appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n" attributes:nil]];
            [attributedString insertAttributedString:attachText atIndex:range.location];
        }
        
        {//處理描述文字
            range = [text rangeOfString:obj.text];
            [attributedString wp_makeAttributed:^(WPMutableAttributedStringMaker * _Nullable make) {
                make.textFont(self.defaultFontSize-2,range);
                make.textColor([UIColor grayColor],range);
                
                CGFloat width = [self calculateWidth:obj.text fontSize:self.defaultFontSize];
                WPMutableParagraphStyleModel * styleModel = [self paragraphStyleModel:width];
                make.paragraphStyle([styleModel createParagraphStyle],range);
            }];
        }
    }];
}

- (WPMutableParagraphStyleModel *)paragraphStyleModel:(CGFloat)width{
    
    WPMutableParagraphStyleModel * styleModel = [WPMutableParagraphStyleModel new];
    styleModel.headIndent =  (self.defaultWidth-width)/2;//整體縮進(jìn)(首行除外)
    styleModel.firstLineHeadIndent = (self.defaultWidth-width)/2;
    styleModel.alignment = NSTextAlignmentJustified;
    return styleModel;
}

- (CGFloat)calculateWidth:(NSString *)text fontSize:(CGFloat)fontSize{
    CGRect rect = [text boundingRectWithSize:CGSizeMake(0, 16) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil];
    return rect.size.width;
}
  • 這里借助了YYText婆硬,直接在對應(yīng)的位置插入了UIImageView,使用SDWebImage進(jìn)行下載。
  • 這里的圖片寬度是根據(jù)外面?zhèn)魅氲募槔叨缺壤潭ū蚍福瑢?shí)際情況可根據(jù)服務(wù)端在url地址上直接返回比例,解決圖片壓縮問題查吊。
  • 文字設(shè)置成了灰色谐区,字號縮小2號,位置居中

3.3 其他解析

其他解析與圖片和鏈接解析類似逻卖,細(xì)節(jié)略有不同宋列。采用統(tǒng)一模板和策略。

3.4 組裝

+ (NSMutableAttributedString *)parseMarkDownWithText:(NSString *)text fontSize:(CGFloat)fontSize width:(CGFloat)width{
    NSArray * parseArray = [self setUpParseArray];
    for (WPMarkDownBaseParse * parseModel in parseArray) {
        [parseModel configFontSize:fontSize width:width];
        [parseModel segmentString:&text];
    }
    
    [self replaceBackslash:&text];
    NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:text];
    [self setAttributedDefaultFont:attributedString fontSize:fontSize];
    
    for (WPMarkDownBaseParse * parseModel in parseArray) {
        [parseModel wp_markdownParseSetAttributedString:attributedString];
    }
    return attributedString;
}
  • 所有的字符解析完成评也,替換反斜杠炼杖,最后生成attributedString
  • setAttributedDefaultFont設(shè)置默認(rèn)字號
  • wp_markdownParseSetAttributedString統(tǒng)一設(shè)置對應(yīng)的屬性

4.鏈接與標(biāo)題單元測試

@interface WPMarkDownParseStringTest : XCTestCase
{
    WPMarkDownParseLink * parseLink;
    WPMarkDownParseTitle * parseTitle;
}
@end

@implementation WPMarkDownParseStringTest

- (void)setUp {
    // Put setup code here. This method is called before the invocation of each test method in the class.
    parseLink = [[WPMarkDownParseLink alloc] initWithSymbol:@"]("];
    parseTitle = [[WPMarkDownParseTitle alloc] initWithSymbol:@"#"];
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    parseLink = nil;
}

- (void)testExample {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}

- (void)testPerformanceExample {
    // This is an example of a performance test case.
    [self measureBlock:^{
        // Put the code you want to measure the time of here.
    }];
}

#pragma mark - 解析URL

- (void)testSpiltOneUrl{
    NSString * text = @"計(jì)劃:[事件傳遞和事件響應(yīng)](https://blog.csdn.net/suma110/article/details/99290799)";
    
    [parseLink segmentString:&text];
    
    WPMarkDownParseLinkModel * urlModel = parseLink.segmentArray.firstObject;
    XCTAssertTrue([urlModel.text isEqualToString:@"事件傳遞和事件響應(yīng)"],@"text分割正確");
    XCTAssertTrue([urlModel.url isEqualToString:@"https://blog.csdn.net/suma110/article/details/99290799"],@"url分割正確");
}

- (void)testSpiltTwoUrl{
    NSString * text = @"計(jì)劃:[事件傳遞和事件響應(yīng)](https://blog.csdn.net/suma110/article/details/99290799)中間級還有很多[事件傳遞和事件響應(yīng)2](https://blog.csdn.net/suma110/article/details/99290798)";
    
    [parseLink segmentString:&text];
        
    WPMarkDownParseLinkModel * urlModel = parseLink.segmentArray.firstObject;
    XCTAssertTrue([urlModel.text isEqualToString:@"事件傳遞和事件響應(yīng)"],@"text分割正確");
    XCTAssertTrue([urlModel.url isEqualToString:@"https://blog.csdn.net/suma110/article/details/99290799"],@"url分割正確");
    
    WPMarkDownParseLinkModel * twoUrlModel = parseLink.segmentArray[1];
    XCTAssertTrue([twoUrlModel.text isEqualToString:@"事件傳遞和事件響應(yīng)2"],@"text分割正確");
    XCTAssertTrue([twoUrlModel.url isEqualToString:@"https://blog.csdn.net/suma110/article/details/99290798"],@"url分割正確");
}

- (void)testSpiltOneUrl2{
    NSString * text = @"[事件傳遞和事件響應(yīng)](https://blog.csdn.net/suma110/article/details/99290799)";
    
    [parseLink segmentString:&text];
    
    WPMarkDownParseLinkModel * urlModel = parseLink.segmentArray.firstObject;
    XCTAssertTrue([urlModel.text isEqualToString:@"事件傳遞和事件響應(yīng)"],@"text分割正確");
    XCTAssertTrue([urlModel.url isEqualToString:@"https://blog.csdn.net/suma110/article/details/99290799"],@"url分割正確");
}

- (void)testSpiltTwoUrl2{
    NSString * text = @"1.Textview展示超鏈接,除了鏈接外盗迟,其他區(qū)域父視圖響應(yīng)\n替補(bǔ)方案:沒有超鏈接的坤邪,關(guān)閉響應(yīng)。\n2.scrollView添加tableView罚缕,scrollView支持橫向艇纺,tableView豎向滾動,在數(shù)據(jù)少時邮弹,不能下拉刷新黔衡。\n[嵌套UIScrollview的滑動沖突解決方案](http://www.reibang.com/p/040772693872)\n[iOS 嵌套UIScrollview的滑動沖突另一種解決方案](http://www.reibang.com/p/df01610b4e73)";
    
    [parseLink segmentString:&text];
    
    WPMarkDownParseLinkModel * urlModel = parseLink.segmentArray.firstObject;
    XCTAssertTrue([urlModel.text isEqualToString:@"嵌套UIScrollview的滑動沖突解決方案"],@"text分割正確");
    XCTAssertTrue([urlModel.url isEqualToString:@"http://www.reibang.com/p/040772693872"],@"url分割正確");
    
    WPMarkDownParseLinkModel * twoUrlModel = parseLink.segmentArray[1];
    XCTAssertTrue([twoUrlModel.text isEqualToString:@"iOS 嵌套UIScrollview的滑動沖突另一種解決方案"],@"text分割正確");
    XCTAssertTrue([twoUrlModel.url isEqualToString:@"http://www.reibang.com/p/df01610b4e73"],@"url分割正確");
}

#pragma mark - 解析title

- (void)testParseOneTitle{
    NSString * text = @"#1.Textview展示超鏈接\n2.scrollView添加tableView,scrollView支持橫向腌乡,tableView豎向滾動盟劫,在數(shù)據(jù)少時,不能下拉刷新与纽。\n[嵌套UIScrollview的滑動沖突解決方案](http://www.reibang.com/p/040772693872)\n[iOS 嵌套UIScrollview的滑動沖突另一種解決方案](http://www.reibang.com/p/df01610b4e73)";
    
    [parseTitle segmentString:&text];
    
    WPMarkDownParseLinkModel * titleModel =  parseTitle.segmentArray.firstObject;
    XCTAssertTrue([titleModel.text isEqualToString:@"1.Textview展示超鏈接"]);
}

- (void)testParseTwoTitle{
    NSString * text = @"#1.Textview展示超鏈接\n#2.scrollView添加tableView侣签,scrollView支持橫向,tableView豎向滾動渣锦,在數(shù)據(jù)少時硝岗,不能下拉刷新。\n[嵌套UIScrollview的滑動沖突解決方案](http://www.reibang.com/p/040772693872)\n[iOS 嵌套UIScrollview的滑動沖突另一種解決方案](http://www.reibang.com/p/df01610b4e73)";
    
    [parseTitle segmentString:&text];
    
    WPMarkDownParseLinkModel * titleModel =  parseTitle.segmentArray.firstObject;
    WPMarkDownParseLinkModel * titleModel2 =  parseTitle.segmentArray[1];
    XCTAssertTrue([titleModel.text isEqualToString:@"1.Textview展示超鏈接"]);
    XCTAssertTrue([titleModel2.text isEqualToString:@"2.scrollView添加tableView袋毙,scrollView支持橫向,tableView豎向滾動冗尤,在數(shù)據(jù)少時听盖,不能下拉刷新胀溺。"]);
}

#pragma mark - 解析截取字符

- (void)testSubStringLast3Number{
    WPMarkDownParseOrder * order = [WPMarkDownParseOrder new];
    NSString * text = @"abcd123";
    NSString * subString = [order subStringLastNum:text];
    XCTAssertTrue([subString isEqualToString:@"123"]);
}

- (void)testSubStringLast1Number{
    WPMarkDownParseOrder * order = [WPMarkDownParseOrder new];
    NSString * text = @"abcd1";
    NSString * subString = [order subStringLastNum:text];
    XCTAssertTrue([subString isEqualToString:@"1"]);
}

- (void)testSubString1Number{
    WPMarkDownParseOrder * order = [WPMarkDownParseOrder new];
    NSString * text = @"1";
    NSString * subString = [order subStringLastNum:text];
    XCTAssertTrue([subString isEqualToString:@"1"]);
}

- (void)testSubStringNoNumber{
    WPMarkDownParseOrder * order = [WPMarkDownParseOrder new];
    NSString * text = @"abc";
    NSString * subString = [order subStringLastNum:text];
    XCTAssertTrue([subString isEqualToString:@""]);
}

@end

5. 總結(jié)

MarkDown組件庫地址

  1. Markdown的解析功能基本完成,但還有很多細(xì)節(jié)需處理皆看。
  2. 由于按文字匹配仓坞,會出現(xiàn)匹配文字。如標(biāo)題與鏈接相同時腰吟,標(biāo)題可能會被加上下劃線无埃;有序嵌套時效果不是很好,現(xiàn)在是碰到兩個\n停止毛雇,而實(shí)際遠(yuǎn)不止這些條件嫉称。
  3. 文中的富文本鏈?zhǔn)绞褂茫呀?jīng)封裝成了WPChained
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末灵疮,一起剝皮案震驚了整個濱河市织阅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌震捣,老刑警劉巖荔棉,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蒿赢,居然都是意外死亡润樱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門羡棵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祥国,“玉大人,你說我怎么就攤上這事晾腔∩嘞。” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵灼擂,是天一觀的道長壁查。 經(jīng)常有香客問我,道長剔应,這世上最難降的妖魔是什么睡腿? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮峻贮,結(jié)果婚禮上席怪,老公的妹妹穿的比我還像新娘。我一直安慰自己纤控,他們只是感情好挂捻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著船万,像睡著了一般刻撒。 火紅的嫁衣襯著肌膚如雪骨田。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天声怔,我揣著相機(jī)與錄音态贤,去河邊找鬼。 笑死醋火,一個胖子當(dāng)著我的面吹牛悠汽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芥驳,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼柿冲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晚树?” 一聲冷哼從身側(cè)響起姻采,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎爵憎,沒想到半個月后慨亲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宝鼓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年刑棵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愚铡。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛉签,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沥寥,到底是詐尸還是另有隱情碍舍,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布邑雅,位于F島的核電站片橡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淮野。R本人自食惡果不足惜捧书,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望骤星。 院中可真熱鬧经瓷,春花似錦、人聲如沸洞难。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至歪泳,卻和暖如春萝勤,著一層夾襖步出監(jiān)牢的瞬間露筒,已是汗流浹背呐伞。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慎式,地道東北人伶氢。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像瘪吏,于是被迫代替她去往敵國和親癣防。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,381評論 0 5
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,196評論 0 3
  • 你是否聽過一首音樂感動到熱淚盈眶掌眠,卻又不知為何要流淚蕾盯,瞬間引起人生的各種共鳴 音樂是溝通人類文化的藝術(shù)之一,前幾日...
    一顆小雞蛋閱讀 290評論 0 1
  • 當(dāng)我寫這一篇文章時蓝丙,我已經(jīng)是浙江金融職業(yè)學(xué)院的一名學(xué)生了级遭,在即將入學(xué)之際,我站在大學(xué)的開頭渺尘,展望一下大學(xué)四年的學(xué)習(xí)...
    心中藏了匹自由的野馬閱讀 193評論 0 0
  • 洞察底層規(guī)律挫鸽,實(shí)現(xiàn)跨越式成長,升級認(rèn)知鸥跟,迭代操作系統(tǒng)丢郊。 這個時代:信息變多、思考變淺,機(jī)會變多医咨、競...
    趙秀榮_3e2b閱讀 315評論 0 2