Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
48c7a04f
Commit
48c7a04f
authored
Feb 25, 2016
by
Viktor Lidholt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds initial version of Markdown renderer
parent
b193854b
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
940 additions
and
0 deletions
+940
-0
README.md
packages/flutter_markdown/README.md
+22
-0
demo.dart
packages/flutter_markdown/example/demo.dart
+36
-0
flutter_markdown.dart
packages/flutter_markdown/lib/flutter_markdown.dart
+8
-0
flutter_markdown_raw.dart
packages/flutter_markdown/lib/flutter_markdown_raw.dart
+8
-0
markdown.dart
packages/flutter_markdown/lib/src/markdown.dart
+84
-0
markdown_raw.dart
packages/flutter_markdown/lib/src/markdown_raw.dart
+433
-0
markdown_style.dart
packages/flutter_markdown/lib/src/markdown_style.dart
+77
-0
markdown_style_raw.dart
packages/flutter_markdown/lib/src/markdown_style_raw.dart
+120
-0
pubspec.yaml
packages/flutter_markdown/pubspec.yaml
+18
-0
flutter_markdown_test.dart
packages/flutter_markdown/test/flutter_markdown_test.dart
+134
-0
No files found.
packages/flutter_markdown/README.md
0 → 100644
View file @
48c7a04f
# Flutter Markdown
A markdown renderer for Flutter. It supports the
[
original format
](
https://daringfireball.net/projects/markdown/
)
, but no inline
html.
## Getting Started
Using the Markdown widget is simple, just pass in the source markdown as a
string:
new Markdown(data: markdownSource);
If you do not want the padding or scrolling behavior, use the MarkdownBody
instead:
new MarkdownBody(data: markdownSource);
By default, Markdown uses the formatting from the current material design theme,
but it's possible to create your own custom styling. Use the MarkdownStyle class
to pass in your own style. If you don't want to use Markdown outside of material
design, use the MarkdownRaw class.
packages/flutter_markdown/example/demo.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'package:flutter_markdown/flutter_markdown.dart'
;
const
String
_kMarkdownData
=
"""# Markdown Example
Markdown allows you to easily include formatted text, images, and even formatted Dart code in your app.
## Styling
Style text as _italic_, __bold__, or `inline code`.
- Use bulleted lists
- To better clarify
- Your points
## Code blocks
Formatted Dart code looks really pretty too. This is an example of how to create your own Markdown widget:
new Markdown(data: "
Hello
_world_
!
");
Enjoy!
"""
;
void
main
(
)
{
runApp
(
new
MaterialApp
(
title:
"Markdown Demo"
,
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
RouteArguments
args
)
=>
new
Scaffold
(
toolBar:
new
ToolBar
(
center:
new
Text
(
"Markdown Demo"
)),
body:
new
Markdown
(
data:
_kMarkdownData
)
)
}
));
}
packages/flutter_markdown/lib/flutter_markdown.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
flutter_markdown
;
export
'src/markdown.dart'
;
export
'src/markdown_style.dart'
;
packages/flutter_markdown/lib/flutter_markdown_raw.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
flutter_markdown
;
export
'src/markdown_raw.dart'
;
export
'src/markdown_style_raw.dart'
;
packages/flutter_markdown/lib/src/markdown.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'markdown_raw.dart'
;
import
'markdown_style.dart'
;
/// A [Widget] that renders markdown formatted text. It supports all standard
/// markdowns from the original markdown specification found here:
/// https://daringfireball.net/projects/markdown/ The rendered markdown is
/// placed in a padded scrolling view port. If you do not want the scrolling
/// behaviour, use the [MarkdownBody] class instead.
class
Markdown
extends
MarkdownRaw
{
/// Creates a new Markdown [Widget] that renders the markdown formatted string
/// passed in as [data]. By default the markdown will be rendered using the
/// styles from the current theme, but you can optionally pass in a custom
/// [markdownStyle] that specifies colors and fonts to use. Code blocks are
/// by default not using syntax highlighting, but it's possible to pass in
/// a custom [syntaxHighlighter].
///
/// new Markdown(data: "Hello _world_!");
Markdown
({
String
data
,
SyntaxHighlighter
syntaxHighlighter
,
MarkdownStyle
markdownStyle
})
:
super
(
data:
data
,
syntaxHighlighter:
syntaxHighlighter
,
markdownStyle:
markdownStyle
);
MarkdownBody
createMarkdownBody
({
String
data
,
MarkdownStyle
markdownStyle
,
SyntaxHighlighter
syntaxHighlighter
})
{
return
new
MarkdownBody
(
data:
data
,
markdownStyle:
markdownStyle
,
syntaxHighlighter:
syntaxHighlighter
);
}
}
/// A [Widget] that renders markdown formatted text. It supports all standard
/// markdowns from the original markdown specification found here:
/// https://daringfireball.net/projects/markdown/ This class doesn't implement
/// any scrolling behavior, if you want scrolling either wrap the widget in
/// a [ScrollableViewport] or use the [Markdown] widget.
class
MarkdownBody
extends
MarkdownBodyRaw
{
/// Creates a new Markdown [Widget] that renders the markdown formatted string
/// passed in as [data]. By default the markdown will be rendered using the
/// styles from the current theme, but you can optionally pass in a custom
/// [markdownStyle] that specifies colors and fonts to use. Code blocks are
/// by default not using syntax highlighting, but it's possible to pass in
/// a custom [syntaxHighlighter].
///
/// Typically, you may want to wrap the [MarkdownBody] widget in a [Padding] and
/// a [ScrollableViewport], or use the [Markdown] class
///
/// new ScrollableViewport(
/// child: new Padding(
/// padding: new EdgeDims.all(16.0),
/// child: new Markdown(data: markdownSource)
/// )
/// )
MarkdownBody
({
String
data
,
SyntaxHighlighter
syntaxHighlighter
,
MarkdownStyle
markdownStyle
})
:
super
(
data:
data
,
syntaxHighlighter:
syntaxHighlighter
,
markdownStyle:
markdownStyle
);
MarkdownStyle
createDefaultStyle
(
BuildContext
context
)
{
return
new
MarkdownStyle
.
defaultFromTheme
(
Theme
.
of
(
context
));
}
}
packages/flutter_markdown/lib/src/markdown_raw.dart
0 → 100644
View file @
48c7a04f
This diff is collapsed.
Click to expand it.
packages/flutter_markdown/lib/src/markdown_style.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/material.dart'
;
import
'markdown_style_raw.dart'
;
/// Style used for rendering markdown formatted text using the [MarkdownBody]
/// widget.
class
MarkdownStyle
extends
MarkdownStyleRaw
{
/// Creates a [MarkdownStyle] from the [TextStyle]s in the provided [theme].
MarkdownStyle
.
defaultFromTheme
(
ThemeData
theme
)
:
super
(
a:
new
TextStyle
(
color:
Colors
.
blue
[
500
]),
p:
theme
.
text
.
body1
,
code:
new
TextStyle
(
color:
Colors
.
grey
[
700
],
fontFamily:
"monospace"
,
fontSize:
theme
.
text
.
body1
.
fontSize
*
0.85
),
h1:
theme
.
text
.
headline
,
h2:
theme
.
text
.
title
,
h3:
theme
.
text
.
subhead
,
h4:
theme
.
text
.
body2
,
h5:
theme
.
text
.
body2
,
h6:
theme
.
text
.
body2
,
em:
new
TextStyle
(
fontStyle:
FontStyle
.
italic
),
strong:
new
TextStyle
(
fontWeight:
FontWeight
.
bold
),
blockquote:
theme
.
text
.
body1
,
blockSpacing:
8.0
,
listIndent:
32.0
,
blockquotePadding:
8.0
,
blockquoteDecoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
blue
[
100
],
borderRadius:
2.0
),
codeblockPadding:
8.0
,
codeblockDecoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
grey
[
100
],
borderRadius:
2.0
)
);
/// Creates a [MarkdownStyle] from the [TextStyle]s in the provided [theme].
/// This style uses larger fonts for the headings than in
/// [MarkdownStyle.defaultFromTheme].
MarkdownStyle
.
largeFromTheme
(
ThemeData
theme
)
:
super
(
a:
new
TextStyle
(
color:
Colors
.
blue
[
500
]),
p:
theme
.
text
.
body1
,
code:
new
TextStyle
(
color:
Colors
.
grey
[
700
],
fontFamily:
"monospace"
,
fontSize:
theme
.
text
.
body1
.
fontSize
*
0.85
),
h1:
theme
.
text
.
display3
,
h2:
theme
.
text
.
display2
,
h3:
theme
.
text
.
display1
,
h4:
theme
.
text
.
headline
,
h5:
theme
.
text
.
title
,
h6:
theme
.
text
.
subhead
,
em:
new
TextStyle
(
fontStyle:
FontStyle
.
italic
),
strong:
new
TextStyle
(
fontWeight:
FontWeight
.
bold
),
blockquote:
theme
.
text
.
body1
,
blockSpacing:
8.0
,
listIndent:
32.0
,
blockquotePadding:
8.0
,
blockquoteDecoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
blue
[
100
],
borderRadius:
2.0
),
codeblockPadding:
8.0
,
codeblockDecoration:
new
BoxDecoration
(
backgroundColor:
Colors
.
grey
[
100
],
borderRadius:
2.0
)
);
}
packages/flutter_markdown/lib/src/markdown_style_raw.dart
0 → 100644
View file @
48c7a04f
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter/widgets.dart'
;
/// Style used for rendering markdown formatted text using the [MarkdownBody]
/// widget.
class
MarkdownStyleRaw
{
/// Creates a new [MarkdownStyleRaw]
MarkdownStyleRaw
({
this
.
a
,
this
.
p
,
this
.
code
,
this
.
h1
,
this
.
h2
,
this
.
h3
,
this
.
h4
,
this
.
h5
,
this
.
h6
,
this
.
em
,
this
.
strong
,
this
.
blockquote
,
this
.
blockSpacing
,
this
.
listIndent
,
this
.
blockquotePadding
,
this
.
blockquoteDecoration
,
this
.
codeblockPadding
,
this
.
codeblockDecoration
})
{
_init
();
}
/// Creates a new [MarkdownStyleRaw] based on the current style, with the
/// provided paramaters overridden.
MarkdownStyleRaw
copyWith
({
TextStyle
a
,
TextStyle
p
,
TextStyle
code
,
TextStyle
h1
,
TextStyle
h2
,
TextStyle
h3
,
TextStyle
h4
,
TextStyle
h5
,
TextStyle
h6
,
TextStyle
em
,
TextStyle
strong
,
TextStyle
blockquote
,
double
blockSpacing
,
double
listIndent
,
double
blockquotePadding
,
BoxDecoration
blockquoteDecoration
,
double
codeblockPadding
,
BoxDecoration
codeblockDecoration
})
{
return
new
MarkdownStyleRaw
(
a:
a
!=
null
?
a
:
this
.
a
,
p:
p
!=
null
?
p
:
this
.
p
,
code:
code
!=
null
?
code
:
this
.
code
,
h1:
h1
!=
null
?
h1
:
this
.
h1
,
h2:
h2
!=
null
?
h2
:
this
.
h2
,
h3:
h3
!=
null
?
h3
:
this
.
h3
,
h4:
h4
!=
null
?
h4
:
this
.
h4
,
h5:
h5
!=
null
?
h5
:
this
.
h5
,
h6:
h6
!=
null
?
h6
:
this
.
h6
,
em:
em
!=
null
?
em
:
this
.
em
,
strong:
strong
!=
null
?
strong
:
this
.
strong
,
blockquote:
blockquote
!=
null
?
blockquote
:
this
.
blockquote
,
blockSpacing:
blockSpacing
!=
null
?
blockSpacing
:
this
.
blockSpacing
,
listIndent:
listIndent
!=
null
?
listIndent
:
this
.
listIndent
,
blockquotePadding:
blockquotePadding
!=
null
?
blockquotePadding
:
this
.
blockquotePadding
,
blockquoteDecoration:
blockquoteDecoration
!=
null
?
blockquoteDecoration
:
this
.
blockquoteDecoration
,
codeblockPadding:
codeblockPadding
!=
null
?
codeblockPadding
:
this
.
codeblockPadding
,
codeblockDecoration:
codeblockDecoration
!=
null
?
codeblockDecoration
:
this
.
codeblockDecoration
);
}
final
TextStyle
a
;
final
TextStyle
p
;
final
TextStyle
code
;
final
TextStyle
h1
;
final
TextStyle
h2
;
final
TextStyle
h3
;
final
TextStyle
h4
;
final
TextStyle
h5
;
final
TextStyle
h6
;
final
TextStyle
em
;
final
TextStyle
strong
;
final
TextStyle
blockquote
;
final
double
blockSpacing
;
final
double
listIndent
;
final
double
blockquotePadding
;
final
BoxDecoration
blockquoteDecoration
;
final
double
codeblockPadding
;
final
BoxDecoration
codeblockDecoration
;
Map
<
String
,
TextStyle
>
_styles
;
Map
<
String
,
TextStyle
>
get
styles
=>
_styles
;
void
_init
()
{
_styles
=
{
'a'
:
a
,
'p'
:
p
,
'li'
:
p
,
'code'
:
code
,
'pre'
:
p
,
'h1'
:
h1
,
'h2'
:
h2
,
'h3'
:
h3
,
'h4'
:
h4
,
'h5'
:
h5
,
'h6'
:
h6
,
'em'
:
em
,
'strong'
:
strong
,
'blockquote'
:
blockquote
};
}
}
packages/flutter_markdown/pubspec.yaml
0 → 100644
View file @
48c7a04f
name
:
flutter_markdown
description
:
A markdown renderer for Flutter.
version
:
0.1.0
author
:
Flutter Authors <flutter-dev@googlegroups.com>
homepage
:
http://flutter.io
dependencies
:
flutter
:
path
:
../flutter
markdown
:
"
0.9.0"
string_scanner
:
"
0.1.4+1"
dev_dependencies
:
flutter_tools
:
path
:
../flutter_tools
test
:
any
# constrained by the dependency in flutter_tools
flutter_test
:
path
:
../flutter_test
packages/flutter_markdown/test/flutter_markdown_test.dart
0 → 100644
View file @
48c7a04f
import
'package:flutter_markdown/flutter_markdown.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:test/test.dart'
;
import
'package:flutter/material.dart'
;
void
main
(
)
{
test
(
"Simple string"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
MarkdownBody
(
data:
"Hello"
));
Element
textElement
=
tester
.
findElement
((
Element
element
)
=>
element
.
widget
is
RichText
);
RichText
textWidget
=
textElement
.
widget
;
TextSpan
textSpan
=
textWidget
.
text
;
List
<
Element
>
elements
=
_listElements
(
tester
);
_expectWidgetTypes
(
elements
,
<
Type
>[
MarkdownBody
,
Column
,
Container
,
Padding
,
RichText
]);
expect
(
textSpan
.
children
[
0
].
text
,
equals
(
"Hello"
));
});
});
test
(
"Header"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
MarkdownBody
(
data:
"# Header"
));
Element
textElement
=
tester
.
findElement
((
Element
element
)
=>
element
.
widget
is
RichText
);
RichText
textWidget
=
textElement
.
widget
;
TextSpan
textSpan
=
textWidget
.
text
;
List
<
Element
>
elements
=
_listElements
(
tester
);
_expectWidgetTypes
(
elements
,
<
Type
>[
MarkdownBody
,
Column
,
Container
,
Padding
,
RichText
]);
expect
(
textSpan
.
children
[
0
].
text
,
equals
(
"Header"
));
});
});
test
(
"Empty string"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
MarkdownBody
(
data:
""
));
List
<
Element
>
elements
=
_listElements
(
tester
);
_expectWidgetTypes
(
elements
,
<
Type
>[
MarkdownBody
,
Column
]);
});
});
test
(
"Ordered list"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
MarkdownBody
(
data:
"1. Item 1
\n
1. Item 2
\n
2. Item 3"
));
List
<
Element
>
elements
=
_listElements
(
tester
);
_expectTextStrings
(
elements
,
<
String
>[
"1."
,
"Item 1"
,
"2."
,
"Item 2"
,
"3."
,
"Item 3"
]
);
});
});
test
(
"Unordered list"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
MarkdownBody
(
data:
"- Item 1
\n
- Item 2
\n
- Item 3"
));
List
<
Element
>
elements
=
_listElements
(
tester
);
_expectTextStrings
(
elements
,
<
String
>[
"•"
,
"Item 1"
,
"•"
,
"Item 2"
,
"•"
,
"Item 3"
]
);
});
});
test
(
"Scrollable wrapping"
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Markdown
(
data:
""
));
List
<
Element
>
elements
=
_listElements
(
tester
);
for
(
Element
element
in
elements
)
print
(
"e:
$element
"
);
_expectWidgetTypes
(
elements
,
<
Type
>[
Markdown
,
ScrollableViewport
,
null
,
null
,
null
,
null
,
null
,
// ScrollableViewport internals
Padding
,
MarkdownBody
,
Column
]);
});
});
}
List
<
Element
>
_listElements
(
WidgetTester
tester
)
{
List
<
Element
>
elements
=
<
Element
>[];
tester
.
walkElements
((
Element
element
)
{
elements
.
add
(
element
);
});
return
elements
;
}
void
_expectWidgetTypes
(
List
<
Element
>
elements
,
List
<
Type
>
types
)
{
expect
(
elements
.
length
,
equals
(
types
.
length
));
for
(
int
i
=
0
;
i
<
elements
.
length
;
i
+=
1
)
{
Element
element
=
elements
[
i
];
Type
type
=
types
[
i
];
if
(
type
==
null
)
continue
;
expect
(
element
.
widget
.
runtimeType
,
equals
(
type
));
}
}
void
_expectTextStrings
(
List
<
Element
>
elements
,
List
<
String
>
strings
)
{
int
currentString
=
0
;
for
(
Element
element
in
elements
)
{
Widget
widget
=
element
.
widget
;
if
(
widget
is
RichText
)
{
TextSpan
span
=
widget
.
text
;
String
text
=
_extractTextFromTextSpan
(
span
);
expect
(
text
,
equals
(
strings
[
currentString
]));
currentString
+=
1
;
}
}
}
String
_extractTextFromTextSpan
(
TextSpan
span
)
{
String
text
=
span
.
text
??
""
;
if
(
span
.
children
!=
null
)
{
for
(
TextSpan
child
in
span
.
children
)
{
text
+=
_extractTextFromTextSpan
(
child
);
}
}
return
text
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment