-
Notifications
You must be signed in to change notification settings - Fork 44
/
InvalidElement.scala
128 lines (107 loc) · 4.73 KB
/
InvalidElement.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package laika.ast
import laika.parse.SourceFragment
import scala.math.Ordered
/** Groups a span that could not be successfully parsed with a runtime message.
* Renderers may then choose to just render the fallback, the message or both.
*/
case class InvalidSpan(
message: RuntimeMessage,
source: SourceFragment,
fallback: Span,
options: Options = Options.empty
) extends Span with Invalid {
type Self = InvalidSpan
type FallbackElement = Span
def withOptions(options: Options): InvalidSpan = copy(options = options)
}
object InvalidSpan {
def apply(message: String, source: SourceFragment): InvalidSpan =
apply(RuntimeMessage(MessageLevel.Error, message), source)
def apply(message: RuntimeMessage, source: SourceFragment): InvalidSpan =
apply(message, source, Literal(source.input))
}
/** Groups a block that could not be successfully parsed with a runtime message.
* Renderers may then choose to just render the fallback, the message or both.
*/
case class InvalidBlock(
message: RuntimeMessage,
source: SourceFragment,
fallback: Block,
options: Options = Options.empty
) extends Block with Invalid {
type Self = InvalidBlock
type FallbackElement = Block
def withOptions(options: Options): InvalidBlock = copy(options = options)
}
object InvalidBlock {
def apply(message: String, source: SourceFragment): InvalidBlock =
apply(RuntimeMessage(MessageLevel.Error, message), source)
def apply(message: RuntimeMessage, source: SourceFragment): InvalidBlock =
apply(message, source, LiteralBlock(source.input))
}
/** Message generated by the parser, a directive or a rewrite rule.
*
* They usually get inserted immediately after the block or span that caused the problem.
* It mixes in both the Span and Block trait so that it can appear in sequences of both types.
* By default messages are ignored by most renderers (apart from AST), but
* they can be explicitly activated for a particular level.
*
* A message of level `MessageLevel.Error` will cause a transformation to fail, unless
* the user has configured with the `renderErrors` method to debug in a visual mode
* in which case the errors will get rendered in-place in the output.
*/
case class RuntimeMessage(level: MessageLevel, content: String, options: Options = Options.empty)
extends Span
with Block
with TextContainer {
type Self = RuntimeMessage
def withOptions(options: Options): RuntimeMessage = copy(options = options)
}
/** Signals the severity of a runtime message.
*/
sealed abstract class MessageLevel(private val level: Int) extends Ordered[MessageLevel]
with Product {
def compare(that: MessageLevel): Int = level compare that.level
override val toString: String = productPrefix.toLowerCase
}
/** Enumeration of available message levels.
*
* The library's internal parsers and AST transformation only use the `Error` level for recoverable issues
* encountered during transformations. All other levels are available for user code.
*/
object MessageLevel {
/** Debug level that is not used by the library itself, but may be used by application code for debugging purposes.
*/
case object Debug extends MessageLevel(0)
/** Info level that is not used by the library itself, but may be used by application code for debugging purposes.
*/
case object Info extends MessageLevel(1)
/** An issue that hints at a potential problem, but in the library's default settings it won't
* cause the transformation to fail.
*/
case object Warning extends MessageLevel(2)
/** An error that is confined to a single AST node or range of nodes, but most likely with surrounding
* areas unaffected. An example is an internal link that remained unresolved.
*/
case object Error extends MessageLevel(3)
/** A critical issue that might affect the integrity of the entire output beyond just the node where it occurred.
* An example is a configuration header with parsing errors in a markup document that might affect other markup
* content that would then unexpectedly fall back to defaults.
*/
case object Fatal extends MessageLevel(4)
}