markymark 11.0.1

markymark 11.0.1

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2023年1月
SPM支持 SPM

Jim van ZummerenJim van ZummerenBas KerkhovenJim van Zummeren 维护。



markymark 11.0.1

  • M2Mobi

Marky Mark

build status codecov Marky Mark 是一个用 Swift 编写的解析器,可以将 markdown 转换为原生视图。其外观高度可自定义,支持的 markdown 语法易于扩展。

Screenshot Screenshot Screenshot

示例

要运行示例项目,首先克隆仓库,然后从 Example 目录运行 pod install

要求

  • iOS 8.0+
  • Xcode 8.0+

安装

构建MarkyMark需要CocoaPods 1.0.0+。

要使用CocoaPods将MarkyMark集成到您的Xcode项目中,请在您的Podfile中指定它。

pod "markymark"

或者,使用Swift Package Manager添加MarkyMark到您的项目中:

https://github.com/M2Mobi/Marky-Mark

简单用法

默认样式视图

let markDownView = MarkDownTextView()
markDownView.text = "# Header\nParagraph"

自定义样式视图

Markymark有很多样式选项,请查看本README文件的样式部分中的示例。一个简单的例子

let markDownView = MarkDownTextView()
markDownView.styling.headingStyling.textColorsForLevels = [
	.orange, //H1 (i.e. # Title)
	.black,  //H2, ... (i.e. ## Subtitle, ### Sub subtitle)
]

markDownView.styling.linkStyling.textColor = .blue
markDownView.styling.paragraphStyling.baseFont = .systemFont(ofSize: 14)
markDownView.text = "# Header\nParagraph"

默认风味中支持的标签

注意:不同的标签可以通过扩展ContentfulFlavor(默认)或者实现一个符合Flavor类并实现所需的Rule来支持。

Headings
# H1
## H2
### H3
#### H4
##### H5
###### H6

Lists
- item
	- item
* item
	* item
+ item
	+ item
a. item
b. item
1. item
2. item

Emphasis
*Em*
_Em_
**Strong**
__Strong__
~~Strike through~~

Images
![Alternative text](image.png)

Links
[Link text](https://www.example.net)

Code 
`code`
```code```

自定义默认样式

默认样式实例

var styling = DefaultStyling()

段落(普通文本)

Markdown 示例:一些文本

styling.paragraphStyling.baseFont = .systemFont(ofSize: 14)
styling.paragraphStyling.textColor = .black
styling.paragraphStyling.contentInsets = UIEdgeInsets(top:0, left: 0, bottom: 5, right: 0)  
styling.paragraphStyling.lineHeight = 4
styling.paragraphStyling.isBold = false
styling.paragraphStyling.isItalic = false
styling.paragraphStyling.textAlignment = .left

标题

Markdown 示例:# 标题##副标题 等。

styling.headingStyling.fontsForLevels = [
	UIFont.boldSystemFontOfSize(24), //H1
	UIFont.systemFontOfSize(18),     //H2
	UIFont.systemFontOfSize(16)      //H3, ... (last item will be next levels as well)
]

styling.headingStyling.colorsForLevels = [
	.red, //H1
	.black, //H2, ... (last item will be next levels as well)
]

// Margins
styling.headingStyling.contentInsetsForLevels = [
	UIEdgeInsets(top: 5, left: 0, bottom: 15, right: 10), // H1
	UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 10) //H2, ... (last item will be next levels as well)
]

styling.headingStyling.isBold = false
styling.headingStyling.isItalic = false
styling.headingStyling.isUnderlined = false
styling.headingStyling.textAlignment = .left

链接样式

Markdown 示例 [Google](http://www.google.com)

styling.linkStyling.textColor = .black
styling.linkStyling.baseFont = nil // Default: nil. Setting baseFont to nil will inherit font from paragraphStyling

styling.linkStyling.isBold = false
styling.linkStyling.isItalic = false
styling.linkStyling.isUnderlined = true

列表样式

Markdown 示例

- List item 1
- List item 2
- Nested List item
// By default a font will be used with the bullet character `•`. Use the follow properties to configure it's size and color:
styling.listStyling.bulletFont = .systemFont(ofSize: 14)
styling.listStyling.bulletColor = .black

// Bullets can also be images for more complex styling. When setting images, bullet font and color won't be used anymore
// Array of images used as bullet for each level of nested list items
styling.listStyling.bulletImages = [
	UIImage(named: "circle"),
	UIImage(named: "emptyCircle"),
	UIImage(named: "line"),
	UIImage(named: "square")
]

// Size of the images
styling.listStyling.bulletViewSize = CGSize(width: 16, height: 16)

styling.listStyling.baseFont = .systemFont(ofSize: 14)
styling.listStyling.contentInsets = UIEdgeInsets(top: 0, left:  0, bottom: 10, right: 10)

//Amount of space underneath each list item
styling.listStyling.bottomListItemSpacing = 5

// Number of pixels to indent for each nested list level
styling.listStyling.listIdentSpace = 15

styling.listStyling.textColor = .black

样式同样适用于

styling.paragraphStyling
styling.italicStyling
styling.boldStyling
styling.strikeThroughStyling
styling.imageStyling
styling.linkStyling
styling.horizontalLineStyling
styling.codeBlockStyling
styling.inlineCodeBlockStyling
styling.quoteStyling

请查阅 DefaultStyling 类以获取更多信息

无障碍:动态类型(字体缩放)

启用 MarkDownTextView 上的动态类型

    markDownView.hasScalableFonts = true

在某些情况下,您可能希望为每个字体配置最大尺寸(默认为 nil)。以下是如何限制段落字体大小的示例

    markDownView.styling.paragraphStyling.maximumPointSize = 26

要设置标题的最大字体点大小,您可以在 headingStyling 上设置 'maximumPointSizeForLevels'。以下示例设置了 heading1、heading2、heading3 的最大尺寸

    markDownView.styling.headingStyling.maximumPointSizeForLevels = [36, 20, 18]

高级用法

高级用法仅适用于非常特定的情况。创建样式子集、制作不同的样式组合、支持不同的Markdown规则(语法)或修改之后生成的某些视图。

自定义样式对象

struct CustomMarkyMarkStyling: Styling {
	var headerStyling = CustomHeaderStyling()
	var paragraphStyling = ParagraphStyling()
	var linkStyling = ListStyling()

	var itemStylingRules: [ItemStyling] {
		return [headerStyling, paragraphStyling, linkStyling]  
	}
}

您可以通过查看其他 Styling 对象的实现方式,如 HeaderStyling,来实现 CustomHeaderStyling。确保您的 CustomHeaderStyling 符合所有您希望自定义样式支持的样式规则。例如,符合 TextColorStylingRule 以支持您的自定义样式的 textStyle。

每个样式规则都可以通过符合 ItemStyling 并实现所需的方法来应用到 MarkdownItem 上。

public func isApplicableOn(_ markDownItem: MarkDownItem) -> Bool {
	return markDownItem is HeaderMarkDownItem
}

这将让机制知道应该将您的样式应用到 HeaderMarkdownItem 上。

您可以通过将其传递给 MarkdownTextView 构造函数来注入您的新样式对象。

MarkDownTextView(styling: CustomMarkyMarkStyling())

添加您自己的规则

添加新规则需要基于以下协议创建三个新类

  • Rule 能够识别所需 Markdown 语法
  • MarkdownItem 用于您的新元素,该元素由您的新规则创建
  • LayoutBlockBuilder 能够将您的 MarkdownItem 转换为布局

将规则添加到 MarkyMark

markyMark.addRule(MyCustomRule())

或在使用 MarkdownTextView 时

markdownTextView.add(rule: MyCustomRule())

将块构建器添加到您的布局转换器中

converter.addLayoutBlockBuilder(MyCustomLayoutBlockBuilder())

或在使用 MarkdownTextView 时使用以下任一选项(取决于配置视图或 attributedString)

markdownTextView.addViewLayoutBlockBuilder(MyCustomLayoutBlockBuilder())
markdownTextView.addAttributedStringLayoutBlockBuilder(MyCustomLayoutBlockBuilder())

如果需要,您还可以将自定义样式类添加到默认样式

styling.addStyling(MyCustomStyling())

转换器钩子

转换器有一个回调方法,每次将 MarkdownItem 转换为布局时都会被调用。

converter.didConvertElement = {
	markDownItem, view in
	// Do something with markDownItem and / or view here
}

当使用 MarkdownTextView 时

markDownTextView.onDidConvertMarkDownItemToView = {
    markDownItem, view in

}

链接行为

默认情况下,Markymark 使用 UIApplication.shared.delegate.open(_:open:options) 打开 URL。只有在实现了此方法时才会打开链接。Markymark 允许通过传递自定义 URLOpener,一个符合 URLOpener 协议的对象来更改此行为。

let markDownView = MarkDownTextView()
markDownTextView?.urlOpener = MyCustomerURLOpener()

在 Extensions 中使用 Markymark

Markymark 同样支持 Today 扩展的用法。默认情况下,点击 URL 不起作用,因为扩展没有权限访问 UIApplication.shared,为了支持链接,你可以向 MarkyDownTextView 传递不同的 URL 打开器。请参考 Example 项目查看一个工作示例

markDownTextView?.urlOpener = ExtensionContextURLOpener(extensionContext: self.extensionContext)

作者

M2mobi, [email protected]

许可证

MarkyMark 基于 MIT 许可证。请参阅 LICENSE 文件获取更多信息。