[翻译] GONMarkupParser

GONMarkupParser

https://github.com/nicolasgoutaland/GONMarkupParser

    NSString *inputText = @"Simple input text, using a preconfigured parser.\n<red>This text will be displayed in red</>.\n<small>This one will be displayed in small</>.\n<pwet>This one is a custom one, to demonstrate <red>how</> easy it is to declare a new markup.</>";

    // 设置默认的配置
    [[GONMarkupParserManager sharedParser].defaultConfiguration setObject:[UIFont systemFontOfSize:25.0]
                                                                   forKey:NSFontAttributeName];

    // 添加一个自定义标签
    NSMutableParagraphStyle *defaultParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    defaultParagraphStyle.alignment                = NSTextAlignmentCenter;
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupSimple simpleMarkup:@"pwet"
                                                                             style:@{
                                                                                     NSParagraphStyleAttributeName : defaultParagraphStyle,
                                                                                     NSForegroundColorAttributeName : [@"pink" representedColor] // NSString+Color
                                                                                     }
                                                                   mergingStrategy:GONMarkupSimpleMergingStrategyMergeAll]];

    // 设置文本字体样式
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupNamedFont namedFontMarkup:[UIFont systemFontOfSize:12.0] forTag:@"small"]];

    // 设置文本颜色样式
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupNamedColor namedColorMarkup:[UIColor redColor]
                                                                                    forTag:@"red"]];

    // 初始化要显示的控件
    self.label               = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 320, 500)];
    self.label.numberOfLines = 0;
    [self.view addSubview:self.label];

    // 生成富文本
    self.label.attributedText = [[GONMarkupParserManager sharedParser] attributedStringFromString:inputText
                                                                                       error:nil];
    [self.label sizeToFit];

Easily build NSAttributedString from XML/HTML like strings.

方便你构造类似于XML/HTML格式的富文本.

Demo

TL;DR;

    NSString *inputText = @"Simple input text, using a preconfigured parser.\n<color value=\"red\">This text will be displayed in red</>.\n<font size="8">This one will be displayed in small</>.\nNow a list:\n<ul><li>First item</><li>Second item</><li><color value="blue">Third blue item</></><li><b><color value="green">Fourth bold green item<//>";

    // No custom configuration, use default tags only

    // Affect text to label
    label.attributedText = [[GONMarkupParserManager sharedParser] attributedStringFromString:inputText
                                                                                       error:nil];
    // You can also use [label setMarkedUpText:inputText];

 

Need a more complex example ?

需要一个更复杂的例子?

    NSString *inputText = @"Simple input text, using a preconfigured parser.\n<red>This text will be displayed in red</>.\n<small>This one will be displayed in small</>.\n<pwet>This one is a custom one, to demonstrate how easy it is to declare a new markup.</>";

    // Set your custom configuration here
#ifdef DEBUG
    [GONMarkupParserManager sharedParser].logLevel = GONMarkupParserLogLevelAll; // Fuck yeah, error debugging
#endif

    // Set default string configuration
    [[GONMarkupParserManager sharedParser].defaultConfiguration setObject:[UIFont systemFontOfSize:25.0] forKey:NSFontAttributeName];

    // Add a custom markup, that will center text when used, and display it in pink.
    NSMutableParagraphStyle *defaultParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    defaultParagraphStyle.alignment = NSTextAlignmentCenter;
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupSimple simpleMarkup:@"pwet"
                                                                             style:@{
                                                                                     NSParagraphStyleAttributeName : defaultParagraphStyle,
                                                                                     NSForegroundColorAttributeName : [@"pink" representedColor] // NSString+Color
                                                                                     }
                                                                   mergingStrategy:GONMarkupSimpleMergingStrategyMergeAll]];

    // Add add font markup, to display small text when encountered
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupNamedFont namedFontMarkup:[UIFont systemFontOfSize:12.0] forTag:@"small"]];

    // Add a convenient tag for red color
    [[GONMarkupParserManager sharedParser] addMarkup:[GONMarkupNamedColor namedColorMarkup:[UIColor redColor]
                                                                                    forTag:@"red"]];

    // Affect text to label
    label.attributedText = [[GONMarkupParserManager sharedParser] attributedStringFromString:inputText
                                                                                       error:nil];

Description

Creating rich text under iOS can be cumbersome, needing a lot of code.

在iOS上面创建出富文本会非常的繁琐,需要写好多好多好多的代码.

The main goal of GONMarkupParser is to provide an easy to use syntax, near XML/HTML, but more flexible.

设计GONMarkupParser的宗旨就是为了提供一种简单的,格式化的,接近于XML/HTML方式的富文本,使用更加灵活.

Some others projects exists, allowing you to build NSAttributedString from HTML, but my main goal here was to focus on text semantic. In fact, the parser will detect registered markups and apply style on text.
The purpose of this was to be able to generate different outputs from the same input string, without editing its content, but editing the markups style.

有很多其他的工程,允许你从HTML上创建出富文本,但是,我设计的主要目的是为了让你仅仅聚焦在文本上面,而不是复杂的冗余代码上,他不会修改原始的字符串文件,而只会编辑做上标记的字符.

GONMarkupParser is not an out of the box solution to parse HTML files.

注意,GONMarkupParser并不是用于解析HTML的解决方案.

Installation

Cocoapodspod ‘GONMarkupParser‘ 直接用Cocoapds安装
Manual: Copy the Classes folder in your project. You will also need to manually installNSString+Color. Seriously, consider using cocoapods instead ;)  将文件夹复制到你的项目当中,然后你需要手动安装NSString+Color文件.

Import wanted headers in your project. .pch is a good place ;) GONMarkupParser_All.h will reference all library headers, whereas GONMarkupDefaultMarkups.h only references default markup classes.

引入你想要的文件到你的项目当中, .pch文件是一个好的选择;),GONMarkupParser_All.h 会帮你引入所有你所需要的文件,而GONMarkupDefaultMarkups.h 只包含了默认配置的类.

Usage

    • instantiate a new GONMarkupParser or use the + GONMarkupParserManager sharedParser one. 实例化一个GONMarkupParser ,或者是用+ GONMarkupParserManager sharedParser 实例化出一个单例.
    • configure your parser adding supported tags, default ones, custom ones, etc... 配置你的标签tag,默认值,自定义等等诸如此类.
    • parse input string and retrieve result NSMutableAttributedString using - attributedStringFromString:error: method from GONMarkupParser 然后从GONMarkupParser中使用- attributedStringFromString:error:来解析生成富文本.
    • you can also set text on UILabel / UITextField by using setMarkedUpText: methods ##How does it work ?  你也可以直接在UILabel / UITextField上用setMarkedUpText:方法进行设置, 他是如何工作的呢?

To fully understand how style will be applied to string, you have to imagine a LIFO stack composed of style description.

为了理解这些样式是如何作用在string上面去的,你需要想象出栈的概念.
Each time a new markup is found, current style configuration will be saved then stacked. New configuration will be the previous one, updated by current markup configuration.

每次发现了新的标签的时候,当前的配置就会被压入栈中.新配置匹配完成结束后,就会轮到旧设置,这样子来更新配置文件.

Each time a closing markup is found, current style configuration is popped out, and previous one restored.

当发现了结束标签的时候,先前的那个配置就会从栈中弹出,其实就是栈的实现.

Syntax

Syntax is pretty easy. It‘s like XML, but non valid one, to be easier and faster to write.

语法非常简单,就像XML,但是不够健全,但使用上还是非常便利的.

  • Each markup should be contained between < and > characters

    • <strong>
  • Like XML, closing markup should start with / character. You can omit markup name in closing tag. If closing tag isn‘t matching currently opened one, an error will be generated, no crash will occur and generated text may not be be as expected You can also close all opened markup by using <//>
    • </strong></>

Examples

 This is a <strong>valid</strong> string with some <color value="red">red <b>bold text</b></color>.
 This is a <strong>valid</>string with some <color value="red">red <b>bold text</></>.
 This is a <strong>valid</Hakuna> string with some <color value="red">red <b>bold text</mata></ta>. // Will work but generates an error
 This is a <strong>valid</> string with some <color value="red">red <b>bold text<//>.

Parser

Constructor

GONMarkupParser class provide two class constructors. GONMarkupParser 提供了两个构造器.

  • + defaultMarkupParser is a parser with all default tags registered (See Default tags summary for more information)  + defaultMarkupParser 提供了所有的默认注册的标签.
  • + emptyMarkupParser is a parser without any registered tags + emptyMarkupParser 是一个解析器,但是没有任何的注册标签.

Properties

A parser can have a pre / post processing block, that will be called prior and after parsing. This allows you to perform some string replace before parsing for example.

Parsers have two interesting properties :

  • replaceNewLineCharactersFromInputString, is intended to strip all newlines characters from input string. Use br markup to add new lines. Default is NO.
  • replaceHTMLCharactersFromOutputString, is intended to replace all HTML entities contained in string, after parsing. Default is YES.

defaultConfiguration will contains default style configuration for generated attributed string. Content should be valid attributes parameters, as you may pass to - addAttributes:range: ofNSMutableAttributedString objects. For default text color, you can setNSForegroundColorAttributeName for example.

For debugging purpose, you can configure debugLevel property.

assertOnError property is also available to generate an assert when an error is encountered.

Configuration

A parser must have some registered markups to correctly handling strings.
Use - addMarkup:- addMarkups:- removeMarkups: and - removeAllMarkups methods for that purpose.
A markup can be added to only one parser at a time.

Registered fonts

To simplify fonts uses, you can register then using - registerFont:forKey: method, then referencing them using given key.

为了简化字体的使用,你可以使用- registerFont:forKey: 方法来注册字体.

Very useful with <font> markup, allowing you to directly use code instead of full font name. You can also use codes such as mainFonttitleFont to easily update them later throught all your strings.

GONMarkupParserManager

sharedParser

A shared parser is available, so you don‘t have to create one and reference it throught all your application.

一个共享的解析器是全局使用的,所以,你没有必要创建出自己的单例来全局使用.

Shared parser is configured with all default markups.

该单例解析器已经包含了所有的默认标签.

parsers registration

You can register some parser to this class, allowing you to use them from different places in your application.

你可以用这个类来注册你自己的标签,允许你在程序的不同地方统一使用.

Available UIKit Categories

UILabel/UITextField
2 methods were added to UILabel and UITextField, allowing you to easily update its attribtued string using a markedup one.

提供了以下的两种方法来让你便利的处理UILabel与UITextField,允许你非常便利的使用富文本.

  • - setMarkedUpText:(NSString *)text parser:(GONMarkupParser *)parser will use given parser to handle string and generate attributedOne.
  • - setMarkedUpText:(NSString *)text will use shared one, aka [GONMarkupParserManager sharedParser]

If no parser default configuration is set for NSForegroundColorAttributeName,NSFontAttributeName and NSParagraphStyleAttributeName, components textColor,textAlignment and font properties will be used as default.

You are stronlgy encouraged to use these methods if you want to use your component style as default parser configuration.

强烈建议你直接使用category的方法.

Default tags

Summary

Tag Class Parameters Effect
left GONMarkupAlignment none Force text alignment to left
right GONMarkupAlignment none Force text alignment to right
center GONMarkupAlignment none Force text alignment to center
justified GONMarkupAlignment none Force text alignment to justified
natural GONMarkupAlignment none Force text alignment to natural
color GONMarkupColor value Set text color. For supported valuesyntaxes, check NSString+ColorrepresentedColor method.
N/A GONMarkupNamedColor none Set text color. Can be used to reset text color to parser default one if specified color is nil
font GONMarkupFont sizename Set text font, text size or both.
N/A GONMarkupNamedFont none Set text font and size. Can be used to reset font to parser default one if specified font is nil
br GONMarkupLineBreak none Add a new line
ul GONMarkupList none Create an unordered list
ol GONMarkupList none Create an ordered list
li GONMarkupListItem none Add a list item to current list
p GONMarkupParagrap none Specify a paragraph. A paragraph will automatically insert a new blanck line after it
inc GONMarkupInc value Increment text font size. If value is missing, font will be increased by one point
dec GONMarkupDec value Decrement text font size. If value is missing, font will be decreased by one point
reset GONMarkupReset all All enclosed text will use default parser configuration
N/A GONMarkupSimple none Apply a configuration to enclosed text
b GONMarkupBold none Set text to bold. Allows user to define an override block overrideBlock to provide another font. Useful to provide a medium font instead of bold one for example.
i GONMarkupItalic none Set text to italic. Allows user to define an override block overrideBlock to provide another font. Useful to provide a medium italic font instead of bold italic one for example.
sup GONMarkupTextStyle none Set text to superscript
sub GONMarkupTextStyle none Set text to subscript
N/A GONMarkupBlock none When encountered executes associated block

Reset

Reset is a special tag, allowing you to protect some parts of a string. You can also force markup to ignore default parser configuration by setting all attribute.

Reset是一种特殊的标签,让你来保护部分过分设置的字符串(详细见下图)

How to add new markup

You can add new markup in your application, to add new style, or to just add some semantic to your text, allowing you to update rendering, without changing input string.
There is 3 ways to do it.

你有3种方法来添加标签.

Adding a new simple marker

The simpler way to add a new markup in your application is to use one of theses 3 following classes :

  • GONMarkupNamedColor, allows you to add a markup that updates text color 这个类是用来更新颜色的.
  • GONMarkupNamedFont, allows you to add a markup that updates text font 这个类是用来更新字体的.
  • GONMarkupSimple, allows you to add a markup that updates all text attributes. Dictionary is intended to be the same as you may pass to configure an NSMutableAttributedString using -setAttributes:range: method. 这个类可以添加所有的属性标签.

Example

    // Retrieve shared parser
    GONMarkupParser *parser = [GONMarkupParserManager sharedParser];

    // Add a named color markup
    [parser addMarkup:[GONMarkupNamedColor namedColorMarkup:[UIColor redColor]
               forTag:@"red"]];

    // Add a named font markup
    [parser addMarkup:[GONMarkupNamedFont namedFontMarkup:[UIFont systemFontOfSize:12.0]
               forTag:@"small"]];

    // Add a custom markup, that will center text when used, and display it in pink.
    NSMutableParagraphStyle *defaultParagraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    defaultParagraphStyle.alignment = NSTextAlignmentCenter;
    [parser addMarkup:[GONMarkupSimple simpleMarkup:@"pwet"
                                              style:@{
                                                        NSParagraphStyleAttributeName : defaultParagraphStyle,
                                                        NSForegroundColorAttributeName : [@"pink" representedColor] // NSString+Color
                                                     }
                                    mergingStrategy:GONMarkupSimpleMergingStrategyMergeAll]];

Adding a new block based marker

For more complexe markup, you can add GONMarkupBlock instances.

如果需要更复杂的标签,你可以添加GONMarkupBlock实例变量.

It have blocks 5 parameters :

  • openingMarkupBlock, called when markup opening is found. Used to pushed your custom configuration to stack
  • closingMarkupBlock, called once markup is closed.
  • updatedContentStringBlock, called right after closingMarkupBlock, allowing you to override returned string
  • prefixStringForContextBlock, called right after openingMarkupBlock, allowing you to return a prefix
  • suffixStringForContextBlock, called right after openingMarkupBlock, allowing you to return a suffix

Example

    // Retrieve shared parser
    GONMarkupParser *parser = [GONMarkupParserManager sharedParser];

    // Custom markup, based on block
    GONMarkupBlock *markupBlock = [GONMarkupBlock blockMarkup:@"custom"];
    markupBlock.openingMarkupBlock = ^(NSMutableDictionary *configurationDictionary, NSString *tag, NSMutableDictionary *context, NSDictionary *attributes) {
        // Update font size
        [configurationDictionary setObject:[UIFont boldSystemFontOfSize:69.0]
                                    forKey:NSFontAttributeName];

        // Update text color
        [configurationDictionary setObject:[@"brown" representedColor]
                                    forKey:NSForegroundColorAttributeName];
    };

    [parser addMarkup:markupBlock];

Creating a new GONMarkup subclass

You can add a custom markup by subclassing GONMarkup class.

Adding a new markup by subclassing is useful if you want to reuse your markups between several projets, or to implement more complex behavior. When subclassing, you have access to a shared object, allowing you to persists data and share it between each markup handling.

For examples, have a look a currently defined markups ;) See GONMarkupList andGONMarkupListItem for an implementation using shared context.

Troubleshooting

Some text is missing

Check that your markup is correctly registered and that your tags are right balanced.

When using < / >, some text is missing

Use &lt; and &gt; in text.

Text color is still applied after my tag is closed.

This is caused by NSAttributedString internal behavior. Once a color is set, it is applied until a new one is set. To prevent this problem, be sure to have set a default text color in your parser (defaultConfiguration / NSForegroundColorAttributeName key). You can use setMarkedUpText:on UILabel / UITextField to use default component configuration.

I am encountering some crashes when using custom font

Be sure to use correct font name, or that font code you are using is correctly registered to your parser. Want to dump all available fonts on your device and check real names ? Have a look at DUMP_FONT_LIST() here

No new lines are inserted using <br>

<br> alone is not valid in GONMArkupParser. Be sure to use <br/>.

Color isn‘t applied

Check that you color value synthax is correct. For more information on supported synthax, have a look at NSString+UIColor here, that is used to compute colors from your string values.

Did Kim Kardashian broke the Internet ?

No, definitely not. I was still able to push to GitHub yesterday.

Evolutions

  • Allow indentation prefix in lists customisation
  • Implement NSCoder in parser and Markers
  • Allow copy on parsers / markers

Versions

0.5 : Initial release

时间: 2024-09-29 17:55:49

[翻译] GONMarkupParser的相关文章

在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】

前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优秀的guide文章,于是按照guide成功完成了一个RESTful的demo.官方文档非常简洁,给我带来了很大的帮助,于是翻译之,希望对其他不愿意看原文的人有所帮助.由于水平有限,读者发现错误请指正,谢谢. 原文地址: https://www.jetbrains.com/help/idea/2016

Java 7 Concurrency Cookbook 翻译 序言

在日常的Java代码开发过程中,很难免地有对多线程的需求,掌握java多线程和并发的机制也是Java程序员写出更健壮和高效代码的基础.笔者找寻国内已出版的关于Java多线程和并发的的中文书籍和翻译书籍,大家一致推荐的是<Java Concurrency in Practice>,笔者暂时还没有看英文原版,笔者看的是它的翻译版<Java并发编程实战>,笔者读起来感觉并不通畅,不知道是翻译的问题还是原版本来就写得不够流畅,同时感觉知识的深度也超过了入门的需求. 笔者在机缘巧合之下,发现

[翻译] ORMLite document -- How to Use Part (二)

前言 此文档翻译于第一次学习 ORMLite 框架,如果发现当中有什么不对的地方,请指正.若翻译与原文档出现任何的不相符,请以原文档为准.原则上建议学习原英文文档. ---------------------------------------------------------------------------------------------- 二.如何使用 2.7 表的创建 ORMLite 提供了一些工具类为您存储在数据库中的类创建 table 和 schema. 2.7.1 Tabl

Reveal常用技巧(翻译来自Reveal官网blog)

翻译来自官网:http://revealapp.com/blog/reveal-common-tips-cn.html 以下基于Reveal 1.6. 用于快速上手的内置应用 刚刚下载Reveal,啥都还没配置呢,想先随便玩玩看,怎么办? 我们花了不少时间开发这个复杂程度类似与实际场景的Sample应用──Soundstagram(音频分享版的Instagram, ¯\_(ツ)_/¯),就是为了让大家能最快速地上手Reveal,尝试它的各种强大功能. 在 Help 菜单项中,点击 Inspect

qt 国际化(翻译时会触发changeEvent)

1. 修改工程文件 .pro ,加入翻译源文件 hello_world.ts: TRANSLATIONS += \        Resource/translations/hello_world.ts 写代码时需要注意下面两点:  2. 源码用 utf-8 字符集3. 源码中需要翻译的字符串必须用英文(不能有中文或其它语言),则需要用 tr()  函数.  例如: QMessageBox::information(this,tr("Information"),tr("Hel

还在吐槽翻译的外版书质量差吗?谈谈我个人的理解

很难想象哪个学习计算机技术的人是没看过这方面书籍的,如果只是在网上看看技术贴,那样得来的知识绝对是离散的,不系统的.而要真正学好一门学问(比如一门计算机语言或者一门技术),一本好书的作用是不言而喻的.很多人抱怨国人在技术图书方面抄来抄去,不求甚解,虽然出版图书者甚众,但最终成为精品者却凤毛麟角.于是,更多读者热衷于外版书.但显然,并非所有国人的外语水平都足以在阅读原版书籍时毫无障碍.那么退而求其次,寻求翻译版就成为一种看似不得已的选择. 不幸的是,网上对于翻译版书籍的吐槽可以说从未消停.我也看过

VLD 1.0 ReadMe翻译尝试

近期想学习下VLD的实现,打算从最简单的V1.0版本看起.以下是V1.0版本自己尝试翻译下,最新的2.x版本似乎强大了很多. 简介 Visual C++提供了内置的内存检测机制,但其充其量只满足了最小定位需求.VLD工具定位为内置内存泄漏的替代,提供了如下特性: 泄漏内存块的全调用栈回溯,包括文件及其行号: 泄漏内存完整转储(hex和ascii格式): 可定制的泄漏报告等级(报告的详细程度可配置) 相对于Purify和BoundsChecher工具其是免费的,而其他免费工具,往往需要入侵式代码.

如何调用有道翻译API(Java,HTTP)

申请Key 首先如图进入有道翻译,在下方点击"有道翻译API". 紧接着来调用数据接口,按提示完成下列输入框. 如下图所示,已经申请成功了. 下图是官方给的示例,可以有xml和json.jsonp等三种数据格式. 代码(Java) public class TestPost { public static void main(String[] args) { new ReadByPost().start(); } } class ReadByPost extends Thread{ @

Android studio project文件结构翻译

Android studio project文件结构翻译 个人翻译,用作备忘. 链接地址:https://developer.android.com/tools/projects/index.html#ApplicationModules Android Project Files Studio的项目文件和设置,设置的作用范围包含所有的module. 以以下的demo为例. .git:git版本控制的文件存放目录. .gradle:gradle执行一些编译所生成的目录 Idea: 由Intell