GONMarkupParser 0.8.2

GONMarkupParser 0.8.2

测试已测试
语言编程语言 Obj-CObjective C
许可证 MIT
发布上一次发布2020年7月

Nicolas Goutaland 维护。



  • 作者:
  • nicolasgoutaland

GONMarkupParser

轻松地从 XML/HTML 字符串构建 NSAttributedString。

示例

ScreenShot

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];

ScreenShot

需要更复杂的示例?

    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];

ScreenShot

描述

在 iOS 中创建富文本可能很繁琐,需要很多代码。
GONMarkupParser 的主要目标是提供一个易于使用的语法,类似于 XML/HTML,但更灵活。
其他一些项目允许您从 HTML 构建 NSAttributedString,但我的主要目标是专注于文本语义。实际上,解析器将检测已注册的标记,并应用到文本上。
这样做的目的是能从相同的输入字符串生成不同的输出,而不修改其内容,而是修改标记样式。

GONMarkupParser 不是 解析 HTML 文件的开箱即用解决方案。

安装

CocoaPods: pod 'GONMarkupParser'
手动: 将项目中的 Classes 目录复制。您还需要 手动 安装 NSString+Color。诚恳地建议使用 cocoapods 吧 ;)

在项目中导入所需头文件。.pch 是一个好地方 ;)
GONMarkupParser_All.h 会引用所有库头文件,而 GONMarkupDefaultMarkups.h 只引用默认标记类。

用法

  • 实例化一个新的 GONMarkupParser 或使用 + GONMarkupParserManager sharedParser
  • 设置您的解析器,添加支持的标签,默认标签,自定义标签等...
  • 使用 - attributedStringFromString:error: 方法从 GONMarkupParser 解析输入字符串并获取结果 NSMutableAttributedString
  • 您还可以使用 setMarkedUpText: 方法设置 UILabel / UITextField / UITextView / UIButton 上的文本

工作原理

ScreenShot

要完全理解样式将如何应用于字符串,你必须想象一个由 后进先出 stack 组成的样式描述。
每次发现新的标记,都将在当前样式配置上保存,然后按堆栈堆放。新配置将是上一个配置,由当前标记配置更新。
每次发现闭合标记,当前样式配置将被弹出,并且恢复上一个配置。

语法

语法很简单,就像 XML,但是非标准的一个,易于书写,更快。

  • 每个标记应该包含在 <> 字符之间
  • <strong>
  • 就像 XML 一样,闭合标记应从 / 字符开始。您可以在闭合标签中省略标记名称。如果闭合标签与当前打开的标签不匹配,将会生成错误,不会崩溃,生成的文本可能不符合预期。
  • </strong></>
  • 您还可以使用 <//> 来关闭所有打开的标记。

示例

 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<//>.

解析器

构造函数

GONMarkupParser 类提供两个类构造函数。

  • + defaultMarkupParser 是一个注册了所有默认标签的解析器(更多信息请见默认标签摘要
  • + emptyMarkgiupParser 是一个没有注册任何标签的解析器

属性

解析器可以有一个预处理和后处理块,将在解析前后被调用。这允许您在解析前执行一些字符串替换操作,例如。

解析器有两个有趣的属性

  • replaceNewLineCharactersFromInputString,用于从输入字符串中删除所有换行符字符。使用 br 标记来添加新行。默认为 NO
  • replaceHTMLCharactersFromOutputString,在解析后替换字符串中的所有 HTML 实体。默认为 YES

defaultConfiguration 将包含生成字符串的默认样式配置。内容应该是有效的属性参数,您可以将其传递给 - addAttributes:range:NSMutableAttributedString 对象。例如,要设置默认文字颜色,可以设置 NSForegroundColorAttributeName

为了调试目的,您可以配置 debugLevel 属性。

assertOnError 属性也用于在遇到错误时生成断言。

配置

解析器必须注册一些标记才能正确处理字符串。
使用 - addMarkup:- addMarkups:- removeMarkups:- removeAllMarkups 方法来实现此目的。
每次只能对一个解析器添加一个标记。

已注册字体

为了简化字体使用,可以使用 - registerFont:forKey: 方法注册字体,然后通过给定的键引用它们。
<font> 标记一起非常实用,允许您直接使用代码而不是完整的字体名称。您还可以使用 mainFonttitleFont 等代码来轻松地在所有字符串中更新它们。

GONMarkupParserManager

共享解析器

共享解析器可以供使用,因此您无需创建一个并在整个应用程序中引用它。
共享解析器默认配置了所有标记。

解析器注册

可以将一些解析器注册到此类,这样您就可以在应用程序的各个位置使用它们。

可用的UIKit类别

UILabel/UITextField/UITextView
为 UILabel、UITextField 和 UITextView 添加了 2 个方法,允许您使用标记的字符串轻松更新其属性字符串。

  • - setMarkedUpText:(NSString *)text parser:(GONMarkupParser *)parser 将使用给定的解析器来处理字符串并生成属性字符串。
  • - setMarkedUpText:(NSString *)text 将使用共享的解析器,即 [GONMarkupParserManager sharedParser]

如果没有为 NSForegroundColorAttributeNameNSFontAttributeName 和 NSParagraphStyleAttributeName 设置解析器默认配置,则将使用默认的组件属性 textColortextAlignmentfont

如果您想将组件样式用作默认解析器配置,强烈建议您使用这些方法。

锚支持

通过使用 <a href="..."> 标记实现锚支持。
如果 NSAttributedString 在 UITextView 中显示,您可以处理对其的用户的点击。
确保您的 UITextView 是 不可编辑的可选择的 并设置了其 代理
然后,在您的代理中实现
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
方法。

链接不会应用颜色样式。您必须使用 UITextViewlinkTextAttributes 属性来设置它。

默认标签

摘要

标签 参数 效果
left GONMarkupAlignment none 强制文本左对齐
right GONMarkupAlignment none 强制文本右对齐
center GONMarkupAlignment none 强制文本居中对齐
justified GONMarkupAlignment none 强制文本两端对齐
natural GONMarkupAlignment none 强制文本自然对齐
color GONMarkupColor value 设置文本颜色。有关支持的 value 语法的详细信息,请查看 NSString+Color 中的 representedColor 方法。
N/A GONMarkupNamedColor none 设置文本颜色。如果指定的颜色为nil,则可以将其重置为解析器默认颜色。
font GONMarkupFont sizenamecolor 设置文本字体、文本大小或两者。也可以用来设置文本颜色。
N/A GONMarkupNamedFont none 设置文本字体和大小。如果指定的字体为nil,则可以将其重置为解析器默认字体。
br GONMarkupLineBreak none 添加新行
ul GONMarkupList none 创建无序列表
ol GONMarkupList none 创建有序列表
li GONMarkupListItem none 将列表项添加到当前列表
p GONMarkupParagraph none 指定一个段落。段落将自动在其后插入一个空白行
inc GONMarkupInc value 增加文本字体大小。如果缺失,字体将会增加一个点
GONMarkupDec value 减少文本字体大小。如果缺失,字体将会减少一个点
重置 GONMarkupReset all 所有括号内的文本将使用默认的解析配置
N/A GONMarkupSimple none 应用于括号内文本的配置
b GONMarkupBold none 将文本设置为粗体。允许用户通过提供另一个字体来定义替换块overrideBlock。例如,提供一种中等字体而不是粗体字体很有用。
strong GONMarkupStrong none 将文本设置为粗体(粗体)。允许用户通过提供另一个字体来定义替换块overrideBlock。例如,提供一种中等字体而不是粗体字体很有用。
i GONMarkupItalic none 将文本设置为斜体。允许用户通过提供另一个字体来定义替换块overrideBlock。例如,提供一种中等斜体字体而不是粗体斜体字体很有用。
sup GONMarkupTextStyle none 将文本设置为上标
sub GONMarkupTextStyle none 将文本设置为下标
u GONMarkupLineStyle words只对单词应用样式(true, false),patternsolid,点,破折号,点破折号,点破折号点),stylesingle,粗体,双线)和color(检查NSString+Color representedColor方法) 下划线文本
strike GONMarkupLineStyle words只对单词应用样式(true, false),patternsolid,点,破折号,点破折号,点破折号点),stylesingle,粗体,双线)和color(检查NSString+Color representedColor方法) 删除线文本
a GONMarkupAnchor href链接值 支持锚点链接。有关更多信息,请参阅锚点支持
N/A GONMarkupBlock none 遇到时执行关联的块

重置

重置是一个特殊标签,允许您保护字符串的一部分。您还可以通过设置< strong>all属性强制标记忽略默认解析配置。

ScreenShot

如何添加新的标记

您可以在应用程序中添加新的标记,以添加新样式,或仅为了给文本添加语义,允许您在不更改输入字符串的情况下更新渲染。
共有3种方法可以实现。

添加新的简单标记

在应用程序中添加新的标记的最简单方法之一是使用以下3个类之一

  • GONMarkupNamedColor,允许您添加能够更新文本颜色的标记
  • GONMarkupNamedFont,允许您添加能够更新文本字体的标记
  • GONMarkupSimple 允许您添加标记,以更新所有文本属性。字典旨在与您可能传给使用 -setAttributes:range: 方法配置 NSMutableAttributedString 的字典相同。

示例

    // 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]];

添加基于块的新的标记

对于更复杂的标记,您可以添加 GONMarkupBlock 实例。

它有5个参数

  • openingMarkupBlock,在找到标记打开时调用。用于将自定义配置推入堆栈
  • closingMarkupBlock,标记关闭后调用一次。
  • updatedContentStringBlock,在 closingMarkupBlock 之后立即调用,允许您覆盖返回的字符串
  • prefixStringForContextBlock,在 openingMarkupBlock 之后立即调用,允许您返回前缀
  • suffixStringForContextBlock,在 openingMarkupBlock 之后立即调用,允许您返回后缀

示例

    // 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];

创建一个新的 GONMarkup 子类

您可以通过继承 GONMarkup 类添加自定义标记。

通过继承添加新标记对于您想要在多个项目中重用标记或实现更复杂的行为非常有用。在进行继承时,您可以访问共享对象,允许您保留数据并在各个标记处理程序之间共享数据。

例如,查看当前定义的标记。 ;). 请参见 GONMarkupListGONMarkupListItem,它们使用共享上下文进行实现。

故障排除

某些文本丢失

检查您的标记是否正确注册,您的标签是否正确匹配。

在使用 < / > 时,某些文本丢失

在文本中使用 &lt; 和 &gt;。

我的标签关闭后文本颜色仍然生效。

这是由 NSAttributedString 的内部行为引起的。一旦设置了颜色,它就会应用,直到设置新的颜色。
为了避免这个问题,请确保在您的解析器中设置了默认文本颜色(defaultConfiguration / NSForegroundColorAttributeName 键)。您可以在 UILabel / UITextField 上使用 setMarkedUpText: 来使用默认组件配置。

文本样式未应用于我的链接

有关更多信息,请参阅 锚点支持

当使用自定义字体时,遇到一些崩溃

请确保使用正确的字体名称,或者您正在使用的字体代码已正确注册到您的解析器。
想倾出您的设备上所有可用的字体并检查它们的真实名称吗?
请看这里的 DUMP_FONT_LIST()

使用 <br> 不会插入新行

<br> 单独在 GONMarkupParser 中是无效的。请确保使用 <br/>

颜色未应用

检查您颜色的语法是否正确。
有关支持的语法,请参阅 NSString+UIColor 的更多信息,这用于从您的字符串值计算颜色。

金·卡戴珊打破互联网了吗?

没有,绝对没有。我昨天还能推送到GitHub。

演变

  • 允许自定义列表的缩进前缀。
  • 在解析器和标记器中实现 NSCoder
  • 允许在解析器/标记器上使用 copy
  • 改进关闭标签。

贡献者

请参阅 GitHub 上的 贡献者页面

变更日志

更改日志可以在这里找到