[flutter_markdown] Import from flutter/flutter_markdown

Imports the flutter/flutter_markdown repository as a package, to
consolidate repositories.

Part of https://github.com/flutter/flutter/issues/74757
This commit is contained in:
Stuart Morgan
2021-04-30 10:12:24 -04:00
183 changed files with 19227 additions and 0 deletions

View File

@ -0,0 +1,24 @@
---
name: Bug report
about: Create an issue to report a bug
title: 'Bug: '
labels: ''
assignees: ''
---
**Describe the bug**
Please provide a clear and concise description of the bug.
**How to reproduce**
Steps to reproduce the behavior:
1.
**Expected behavior**
A description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain the problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,3 @@
# Use one of the three issue templates provided. The "Other issue"
# template should be used instead of a blank issue.
blank_issues_enabled: false

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an feature enhancement or new functionality
title: 'Feature: '
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of the problem.
**Describe a possible solution.**
Do you have a possible solution or approach you think should be considered?
**Describe possible alternatives.**
Are there possible alternative solutions or features.
**Additional context.**
List any additional context or screenshots about the feature request here.

View File

@ -0,0 +1,11 @@
---
name: Other issue
about: Issues that are not bugs or feature requests.
title: ''
labels: ''
assignees: ''
---
**Describe the issue**
Please provide a clear and concise description of the issue.

View File

@ -0,0 +1,23 @@
**IMPORTANT: Please do not create a Pull Request without creating an issue first.**
*Any change needs to be discussed before proceeding. Failure to do so may result in the rejection of the pull request.*
Please provide enough information so that others can review your pull request:
<!--
Explain the **details** for making this change. What existing problem does the pull request solve? Example: When "Adding a function to do X", explain why it is necessary to have a way to do X.
-->
**Test plan (required)**
<!--
Demonstrate the code is solid. Make sure all automated tests pass. New features or enhancements need an appropriate unit test. If no unit test is required, please explain why. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI.
-->
**Closing issues**
<!-- If this PR fixes open issues, put `closes #XXXX` in your comment to auto-close the issue. -->
**Additional considerations**
<!-- List any additional information that can help reviewers understand. -->

View File

@ -0,0 +1,35 @@
name: flutter_markdown
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
schedule:
- cron: '0 0 * * *' # Every day at midnight
defaults:
run:
shell: bash
jobs:
flutter-tests:
name: Test Flutter ${{ matrix.flutter_version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
flutter_version: [dev, beta] # Disable stable until Null Safety goes stable
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: '12.x'
- uses: subosito/flutter-action@v1
with:
channel: ${{ matrix.flutter_version }}
- run: flutter analyze
- run: flutter format --dry-run --set-exit-if-changed .
- run: flutter test

36
packages/flutter_markdown/.gitignore vendored Normal file
View File

@ -0,0 +1,36 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

View File

@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "flutter_markdown",
"request": "launch",
"type": "dart"
},
{
"name": "example",
"cwd": "example",
"request": "launch",
"type": "dart"
}
]
}

View File

@ -0,0 +1,154 @@
## 0.6.1
* Added builder option bulletBuilder
## 0.6.0
* Null safety release
* Added stylesheet option listBulletPadding
* Fixed blockquote inline styling
* Added onTapText handler for selectable text
## 0.6.0-nullsafety.2
* Dependencies updated for null safety
## 0.6.0-nullsafety.1
* Fix null safety on web
* Image test mocks fixed for null safety
## 0.6.0-nullsafety.0
* Initial null safety migration.
## 0.5.2
* Added `MarkdownListItemCrossAxisAlignment` to allow for intrinsic height
measurements of lists.
## 0.5.1
* Fix user defined builders
## 0.5.0
* BREAKING CHANGE: `MarkdownTapLinkCallback` now has three parameters, not one, exposing more
information about a tapped link.
* Note for upgraders, the old single parameter `href` is now the second parameter to match the specification.
* Android example upgraded
* Test coverage updated to match GitHub Flavoured Markdown and CommonMark
* Handle links with empty descriptions
* Handle empty rows in tables
## 0.4.4
* Fix handling of newline character in blockquote
* Add new example demo
* Use the start attribute in ordered list to set the first number
* Revert changes made in PR #235 (which broke newline handling)
## 0.4.3
* Fix merging of `MarkdownStyleSheets`
* Fix `MarkdownStyleSheet` textScaleFactor to use default value of 1.0, if not provided, instead using the textScaleFactor of the nearest MediaQuery
## 0.4.2
* Fix parsing of image caption & alt attributes
* Fix baseline alignment in lists
* Support `LineBreakSyntax`
## 0.4.1
* Downgrade Flutter minimum from 1.17.1 to 1.17.0 for Pub
## 0.4.0
* Updated for Flutter 1.17
* Ignore newlines in paragraphs
* Improve handling of horizontal rules
## 0.3.5
* Fix hardcoded colors and improve Darktheme
* Fix text alignment when formatting is involved
## 0.3.4
* Add support for text paragraphs and blockquotes.
## 0.3.3
* Add the ability to control the scroll position of the `MarkdownWidget`.
## 0.3.2
* Uplift `package:markdown` dependency version to enable deleting HTML unescape URI workaround
* Explictly state that Flutter 1.10.7 is the minimum supported Flutter version in the library `pubspec.yaml`.
## 0.3.1
* Expose `tableColumnWidth`
* Add `MarkdownStyleSheet.fromCupertinoTheme`
* Fix `MarkdownStyleSheet.blockquote`
* Flutter for web support
* Add physic and shrinkWrap to Markdown widget
* Add MarkdownBody.fitContent
* Support select text to copy
* Fix list bullet alignment
* HTML unescape URIs (temporary workaround for [dart-lang/markdown #272](https://github.com/dart-lang/markdown/issues/272))
* Rebuilt `example/android` and `example/ios` directories
**Note:** this version has an implicit minimum supported version of Flutter 1.10.7.
See [flutter/flutter_markdown issue #156](https://github.com/flutter/flutter_markdown/issues/156) for more detail.
## 0.3.0
* Support GitHub flavoured Markdown
* Support strikethrough
* Convert TextSpan to use new InlineSpan API
## 0.2.0
* Updated environment sdk constraints to make the package
Dart 2 compatible. As a result, usage of this version and higher
requires a Dart 2 SDK.
## 0.1.6
* Updated `markdown` dependency.
## 0.1.5
* Add `mockito` as a dev dependency. Eliminate use of `package:http`, which
is no longer part of Flutter.
## 0.1.4
* Add `li` style to bullets
## 0.1.3
* Add `path` and `http` as declared dependencies in `pubspec.yaml`
## 0.1.2
* Add support for horizontal rules.
* Fix the `onTap` callback on images nested in hyperlinks
## 0.1.1
* Add support for local file paths in image links. Make sure to set the
`imageDirectory` property to specify the base directory containing the image
files.
## 0.1.0
* Roll the dependency on `markdown` to 1.0.0
* Add a test and example for image links
* Fix the `onTap` callback on hyperlinks
## 0.0.9
* First published version

View File

@ -0,0 +1,27 @@
// Copyright 2017 Google, Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,148 @@
# Flutter Markdown
[![pub package](https://img.shields.io/pub/v/flutter_markdown.svg)](https://pub.dartlang.org/packages/flutter_markdown)
[![Build Status](https://github.com/flutter/flutter_markdown/workflows/flutter_markdown/badge.svg)](https://github.com/flutter/flutter_markdown/actions?workflow=flutter_markdown)
A markdown renderer for Flutter. It supports the
[original format](https://daringfireball.net/projects/markdown/), but no inline
HTML.
## Overview
The [`flutter_markdown`](https://pub.dev/packages/flutter_markdown) package
renders Markdown, a lightweight markup language, into a Flutter widget
containing a rich text representation.
`flutter_markdown` is built on top of the Dart
[`markdown`](https://pub.dev/packages/markdown) package, which parses
the Markdown into an abstract syntax tree (AST). The nodes of the AST are an
HTML representation of the Markdown data.
## Flutter Isn't a HTML Renderer
While this approach to creating a rich text representation of Markdown source
text in Flutter works well, Flutter isn't a HTML renderer like a web browser.
Markdown was developed by John Gruber in 2004 to allow users to turn readable,
plain text content into rich text HTML. This close association with HTML allows
for the injection of HTML into the Markdown source data. Markdown parsers
generally ignore hand-tuned HTML and pass it through to be included in the
generated HTML. This *trick* has allowed users to perform some customization
or tweaking of the HTML output. A common HTML tweak is to insert HTML line-break
elements **\<br />** in Markdown source to force additional line breaks not
supported by the Markdown syntax. This HTML *trick* doesn't apply to Flutter. The
`flutter_markdown` package doesn't support inline HTML.
## Markdown Specifications and `flutter_markdown` Compliance
There are three seminal documents regarding Markdown syntax; the
[original Markdown syntax documentation](https://daringfireball.net/projects/markdown/syntax)
specified by John Gruber, the
[CommonMark specification](https://spec.commonmark.org/0.29/), and the
[GitHub Flavored Markdown specification](https://github.github.com/gfm/).
The CommonMark specification brings order to and clarifies the Markdown syntax
cases left ambiguous or unclear in the Gruber document. GitHub Flavored
Markdown (GFM) is a strict superset of CommonMark used by GitHub.
The `markdown` package, and in extension, the `flutter_markdown` package, supports
four levels of Markdown syntax; basic, CommonMark, GitHub Flavored, and GitHub
Web. Basic, CommonMark, and GitHub Flavored adhere to the three Markdown
documents, respectively. GitHub Web adds header ID and emoji support. The
`flutter_markdown` package defaults to GitHub Flavored Markdown.
## Getting Started
Using the Markdown widget is simple, just pass in the source markdown as a
string:
Markdown(data: markdownSource);
If you do not want the padding or scrolling behavior, use the MarkdownBody
instead:
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.
## Emoji Support
Emoji glyphs can be included in the formatted text displayed by the Markdown
widget by either inserting the emoji glyph directly or using the inline emoji
tag syntax in the source Markdown document.
Markdown documents using UTF-8 encoding can insert emojis, symbols, and other
Unicode characters directly in the source document. Emoji glyphs inserted
directly in the Markdown source data are treated as text and preserved in the
formatted output of the Markdown widget. For example, in the following Markdown
widget constructor, a text string with a smiley face emoji is passed in as the
source Markdown data.
```
Markdown(
controller: controller,
selectable: true,
data: 'Insert emoji here😀 ',
)
```
The resulting Markdown widget will contain a single line of text with the
emoji preserved in the formatted text output.
The second method for including emoji glyphs is to provide the Markdown
widget with a syntax extension for inline emoji tags. The Markdown
package includes a syntax extension for emojis, EmojiSyntax. The default
extension set used by the Markdown widget is the GitHub flavored extension
set. This pre-defined extension set approximates the GitHub supported
Markdown tags, providing syntax handlers for fenced code blocks, tables,
auto-links, and strike-through. To include the inline emoji tag syntax
while maintaining the default GitHub flavored Markdown behavior, define
an extension set that combines EmojiSyntax with ExtensionSet.gitHubFlavored.
```
import 'package:markdown/markdown.dart' as md;
Markdown(
controller: controller,
selectable: true,
data: 'Insert emoji :smiley: here',
extensionSet: md.ExtensionSet(
md.ExtensionSet.gitHubFlavored.blockSyntaxes,
[md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes],
),
)
```
## Image Support
The `Img` tag only supports the following image locations:
* From the network: Use a URL prefixed by either `http://` or `https://`.
* From local files on the device: Use an absolute path to the file, for example by
concatenating the file name with the path returned by a known storage location,
such as those provided by the [`path_provider`](https://pub.dartlang.org/packages/path_provider)
plugin.
* From image locations referring to bundled assets: Use an asset name prefixed by `resource:`.
like `resource:assets/image.png`.
## Verifying Markdown Behavior
Verifying Markdown behavior in other applications can often be useful to track
down or identify unexpected output from the `flutter_markdown` package. Two
valuable resources are the
[Dart Markdown Live Editor](https://dart-lang.github.io/markdown/) and the
[Markdown Live Preview](https://markdownlivepreview.com/). These two resources
are dynamic, online Markdown viewers.
## Markdown Resources
Here are some additional Markdown syntax resources:
- [Markdown Guide](https://www.markdownguide.org/)
- [CommonMark Markdown Reference](https://commonmark.org/help/)
- [GitHub Guides - Mastering Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown)
- [Download PDF cheatsheet version](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf)

View File

@ -0,0 +1,36 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

View File

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 532a8fed41a4f6595965f02f3edf9666ba5ebf44
channel: master
project_type: app

View File

@ -0,0 +1,16 @@
# flutter_markdown_example
Demonstrates how to use the flutter_markdown package.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@ -0,0 +1,11 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties

View File

@ -0,0 +1,59 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.flutter.packages.flutter_markdown_example"
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.packages.flutter_markdown_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,41 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.packages.flutter_markdown_example">
<application
android:label="flutter_markdown_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

View File

@ -0,0 +1,6 @@
package io.flutter.packages.flutter_markdown_example
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.flutter.packages.flutter_markdown_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View File

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

View File

@ -0,0 +1,11 @@
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,199 @@
# Markdown Test Page
# Basic Syntax
## Headings
---
# Heading One
Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat commodo id sunt. Nostrud enim ad commodo incididunt cupidatat in ullamco ullamco Lorem cupidatat velit enim et Lorem.
## Heading Two
Aute officia nulla deserunt do deserunt cillum velit magna. Officia veniam culpa anim minim dolore labore pariatur voluptate id ad est duis quis velit dolor pariatur enim. Incididunt enim excepteur do veniam consequat culpa do voluptate dolor fugiat ad adipisicing sit.
### Heading Three
Voluptate cupidatat cillum elit quis ipsum eu voluptate fugiat consectetur enim. Quis ut voluptate culpa ex anim aute consectetur dolore proident voluptate exercitation eiusmod. Esse in do anim magna minim culpa sint.
#### Heading Four
Commodo fugiat aliqua minim quis pariatur mollit id tempor. Non occaecat minim esse enim aliqua adipisicing nostrud duis consequat eu adipisicing qui. Minim aliquip sit excepteur ipsum consequat laborum pariatur excepteur.
##### Heading Five
Veniam enim esse amet veniam deserunt laboris amet enim consequat. Minim nostrud deserunt cillum consectetur commodo eu enim nostrud ullamco occaecat excepteur. Aliquip et ut est commodo enim dolor amet sint excepteur.
###### Heading Six
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
## Paragraphs
---
Incididunt ex adipisicing ea ullamco consectetur in voluptate proident fugiat tempor deserunt reprehenderit ullamco id dolore laborum. Do laboris laboris minim incididunt qui consectetur exercitation adipisicing dolore et magna consequat magna anim sunt. Officia fugiat Lorem sunt pariatur incididunt Lorem reprehenderit proident irure.
Officia dolore laborum aute incididunt commodo nisi velit est est elit et dolore elit exercitation. Enim aliquip magna id ipsum aliquip consectetur ad nulla quis. Incididunt pariatur dolor consectetur cillum enim velit cupidatat laborum quis ex.
Officia irure in non voluptate adipisicing sit amet tempor duis dolore deserunt enim ut. Reprehenderit incididunt in ad anim et deserunt deserunt Lorem laborum quis. Enim aute anim labore proident laboris voluptate elit excepteur in.
## Inline Emphasis - Bold and Italic
---
Sint ea do **exercitation** incididunt et minim ad labore sunt. Minim deserunt labore laboris velit nulla incididunt ipsum nulla. **Consequat commodo** reprehenderit duis esse esse ex**ercita**tion minim enim Lorem dolore duis irure. Et ad ipsum labore enim ipsum **cupidatat consequat**. Commodo non ea __cupidatat magna__ deserunt dolore ipsum velit nulla elit veniam nulla eiusmod proident officia.
*"Proident sit veniam in est proident officia adipisicing"* ea tempor cillum non cillum velit deserunt. Sit tempor ad*ipisic*ing ea laboris anim aute reprehenderit id eu ea. Aute Lorem minim _adipisicing nostrud mollit_ ad ut voluptate do nulla esse occaecat aliqua sint anim.
## Blockquotes
---
Ad nisi laborum aute cupidatat magna deserunt eu id laboris id. Aliquip nulla cupidatat sint ex Lorem mollit laborum dolor amet est ut esse aute. Nostrud ex consequat id incididunt proident ipsum minim duis aliqua ut ex et ad quis.
> Ipsum et cupidatat mollit exercitation enim duis sunt irure aliqua reprehenderit mollit. Pariatur Lorem pariatur laboris do culpa do elit irure.
Labore ea magna Lorem consequat aliquip consectetur cillum duis dolore. Et veniam dolor qui incididunt minim amet laboris sit.
> Qui est sit et reprehenderit aute est esse enim aliqua id aliquip ea anim. Pariatur sint reprehenderit mollit velit voluptate enim consectetur sint enim. Quis exercitation proident elit non id qui culpa dolore esse aliquip consequat.
## Lists
---
### Ordered List
1. Longan
2. Lychee
3. Excepteur ad cupidatat do elit laborum amet cillum reprehenderit consequat quis.
Deserunt officia esse aliquip consectetur duis ut labore laborum commodo aliquip aliquip velit pariatur dolore.
4. Marionberry
4. Melon
- Cantaloupe
- Honeydew
- Watermelon
6. Miracle fruit
7. Mulberry
9. Strawberry
12. Plum
### Unordered List
- Olive
- Orange
- Blood orange
- Clementine
- Papaya
- Ut aute ipsum occaecat nisi culpa Lorem id occaecat cupidatat id id magna laboris ad duis. Fugiat cillum dolore veniam nostrud proident sint consectetur eiusmod irure adipisicing.
- Passionfruit
## Inline Code
---
Duis duis est `code in text` velit velit aute culpa ex quis pariatur pariatur laborum aute pariatur duis tempor sunt ad. Irure magna voluptate dolore consectetur consectetur irure esse. Anim magna `md.ExtensionSet.GitHub` dolor.
## Horizontal Rule
---
In dolore velit aliquip labore mollit minim tempor veniam eu veniam ad in sint aliquip mollit mollit. Ex occaecat non deserunt elit laborum sunt tempor sint consequat culpa culpa qui sit.
***
or
---
or
____________
In laboris eiusmod reprehenderit aliquip sit proident occaecat. Non sit labore anim elit veniam Lorem minim commodo eiusmod irure do minim nisi.
## Link
---
[Google]: https://www.google.com
Excepteur ad cupidatat do elit laborum amet cillum reprehenderit consequat quis.
Deserunt officia esse [Flutter](https://www.flutter.dev) aliquip consectetur duis ut labore laborum commodo aliquip aliquip velit pariatur dolore.
[Flutter](https://www.flutter.dev)
Excepteur ad cupidatat do *[Flutter](https://www.flutter.dev)* elit laborum amet cillum reprehenderit **[Dart](https://www.dart.dev)** aliquip sit proident occaecat. Non sit labore anim elit veniam Lorem minim commodo eiusmod irure do minim nisi.
In laboris eiusmod reprehenderit aliquip sit proident occaecat. Non sit labore anim elit veniam Lorem minim commodo eiusmod irure do minim nisi [Google's Home Page][Google].
## Image
---
Minim id consequat adipisicing cupidatat laborum culpa veniam non consectetur et duis pariatur reprehenderit eu ex consectetur. Sunt nisi qui eiusmod ut cillum laborum Lorem officia aliquip laboris ullamco nostrud laboris non irure laboris.
![Super wide](https://picsum.photos/id/15/1280/800)
In laboris eiusmod reprehenderit aliquip sit proident occaecat. Non sit labore anim elit veniam Lorem minim commodo eiusmod irure do minim nisi.
![Flutter logo](/dart-lang/site-shared/master/src/_assets/image/flutter/icon/64.png)
Officia irure in non voluptate adipisicing sit amet tempor duis dolore deserunt enim ut. Reprehenderit incididunt in ad anim et deserunt deserunt Lorem laborum quis. Enim aute anim labore proident laboris voluptate elit excepteur in.
![Not so big](https://picsum.photos/id/180/480/400)
In laboris eiusmod reprehenderit aliquip sit proident occaecat. Non sit labore anim elit veniam Lorem minim commodo eiusmod irure do minim nisi.
![alt](resource:assets/logo.png)
# Extended Syntax
# Table
---
Duis sunt ut pariatur reprehenderit mollit mollit magna dolore in pariatur nulla commodo sit dolor ad fugiat.
| Table Heading 1 | Table Heading 2 | Table Heading 3 |
| --------------- | --------------- | --------------- |
| Item 1 | Item 2 | Item 3 |
| Item 1 | Item 2 | Item 3 |
| Item 1 | Item 2 | Item 3 |
Ex amet id ex aliquip id do laborum excepteur exercitation elit sint commodo occaecat nostrud est. Nostrud pariatur esse veniam laborum non sint magna sit laboris minim in id.
## Fenced Code Block
---
Et fugiat ad nisi amet magna labore do cillum fugiat occaecat cillum Lorem proident. In sint dolor ullamco ad do adipisicing amet.
```
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
const String _markdownData = """
# Markdown Example
Markdown allows you to easily include formatted text, images,
and even formatted Dart code in your app.
""";
void main() {
runApp(
MaterialApp(
title: "Markdown Demo",
home: Scaffold(
appBar: AppBar(
title: const Text('Markdown Demo'),
),
body: SafeArea(
child: Markdown(
data: _markdownData,
),
),
),
),
);
}
```
## Strikethrough
---
~~Voluptate cupidatat cillum elit quis ipsum eu voluptate fugiat consectetur enim. Quis ut voluptate culpa ex anim aute consectetur dolore proident voluptate exercitation eiusmod. Esse in do anim magna minim culpa sint.~~
Commodo ***~~fugiat aliqua minim quis pariatur mollit~~*** id tempor. Non occaecat **~~minim~~** anim aute ~~**consectetur esse**~~ enim aliqua *~~adipisicing~~* nostrud duis consequat eu ~~*adipisicing*~~ qui. Minim aliquip ~~***sit excepteur ipsum consequat***~~ laborum pariatur excepteur.
## Task List
---
Officia irure in non voluptate adipisicing sit amet tempor duis dolore deserunt enim ut. Reprehenderit incididunt in ad anim et deserunt deserunt Lorem laborum quis. Enim aute anim labore proident laboris voluptate elit excepteur in.
- [ ] laboris voluptate
- [x] consectetur
- [ ] eiusmod irure do
Labore ea magna Lorem consequat aliquip consectetur cillum duis dolore. Et veniam dolor qui incididunt minim amet laboris sit.

View File

@ -0,0 +1,112 @@
# Markdown Example
Markdown allows you to easily include formatted text, images, and even formatted Dart code in your app.
## Titles
Setext-style
```
This is an H1
=============
This is an H2
-------------
```
Atx-style
```
# This is an H1
## This is an H2
###### This is an H6
```
Select the valid headers:
- [x] `# hello`
- [ ] `#hello`
## Links
[Google's Homepage][Google]
```
[inline-style](https://www.google.com)
[reference-style][Google]
```
## Images
![Flutter logo](/dart-lang/site-shared/master/src/_assets/image/flutter/icon/64.png)
## Tables
|Syntax |Result |
|---------------------------------------|-------------------------------------|
|`*italic 1*` |*italic 1* |
|`_italic 2_` | _italic 2_ |
|`**bold 1**` |**bold 1** |
|`__bold 2__` |__bold 2__ |
|`This is a ~~strikethrough~~` |This is a ~~strikethrough~~ |
|`***italic bold 1***` |***italic bold 1*** |
|`___italic bold 2___` |___italic bold 2___ |
|`***~~italic bold strikethrough 1~~***`|***~~italic bold strikethrough 1~~***|
|`~~***italic bold strikethrough 2***~~`|~~***italic bold strikethrough 2***~~|
## Styling
Style text as _italic_, __bold__, ~~strikethrough~~, or `inline code`.
- Use bulleted lists
- To better clarify
- Your points
## Code blocks
Formatted Dart code looks really pretty too:
```
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Markdown(data: markdownData),
),
));
}
```
## Center Title
###### ※ ※ ※
_* How to implement it see main.dart#L129 in example._
## Custom Syntax
NaOH + Al_2O_3 = NaAlO_2 + H_2O
C_4H_10 = C_2H_6 + C_2H_4
## Markdown widget
This is an example of how to create your own Markdown widget:
Markdown(data: 'Hello _world_!');
Enjoy!
[Google]: https://www.google.com/
## Line Breaks
This is an example of how to create line breaks (tab or two whitespaces):
line 1
line 2
line 3

View File

@ -0,0 +1,32 @@
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>

View File

@ -0,0 +1 @@
#include "Generated.xcconfig"

View File

@ -0,0 +1 @@
#include "Generated.xcconfig"

View File

@ -0,0 +1,471 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.packages.flutterMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.packages.flutterMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.flutter.packages.flutterMarkdownExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_markdown_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -0,0 +1,164 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import '../shared/dropdown_menu.dart';
import '../shared/markdown_demo_widget.dart';
import '../shared/markdown_extensions.dart';
const String _notes = """
# Basic Markdown Demo
---
The Basic Markdown Demo shows the effect of the four Markdown extension sets
on formatting basic and extended Markdown tags.
## Overview
The Dart [markdown](https://pub.dev/packages/markdown) package parses Markdown
into HTML. The flutter_markdown package builds on this package using the
abstract syntax tree generated by the parser to make a tree of widgets instead
of HTML elements.
The markdown package supports the basic block and inline Markdown syntax
specified in the original Markdown implementation as well as a few Markdown
extensions. The markdown package uses extension sets to make extension
management easy. There are four pre-defined extension sets; none, Common Mark,
GitHub Flavored, and GitHub Web. The default extension set used by the
flutter_markdown package is GitHub Flavored.
The Basic Markdown Demo shows the effect each of the pre-defined extension sets
has on a test Markdown document with basic and extended Markdown tags. Use the
Extension Set dropdown menu to select an extension set and view the Markdown
widget's output.
## Comments
Since GitHub Flavored is the default extension set, it is the initial setting
for the formatted Markdown view in the demo.
""";
class BasicMarkdownDemo extends StatefulWidget implements MarkdownDemoWidget {
static const _title = 'Basic Markdown Demo';
@override
String get title => BasicMarkdownDemo._title;
@override
String get description => 'Shows the effect the four Markdown extension sets '
'have on basic and extended Markdown tagged elements.';
@override
Future<String> get data async =>
await rootBundle.loadString('assets/markdown_test_page.md');
@override
Future<String> get notes => Future<String>.value(_notes);
@override
_BasicMarkdownDemoState createState() => _BasicMarkdownDemoState();
}
class _BasicMarkdownDemoState extends State<BasicMarkdownDemo> {
var _extensionSet = MarkdownExtensionSet.githubFlavored;
final _menuItems = Map<String, MarkdownExtensionSet>.fromIterables(
MarkdownExtensionSet.values.map((e) => e.displayTitle),
MarkdownExtensionSet.values,
);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: widget.data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Column(
children: [
DropdownMenu<MarkdownExtensionSet>(
items: _menuItems,
label: 'Extension Set:',
initialValue: _extensionSet,
onChanged: (value) {
if (value != _extensionSet) {
setState(() {
_extensionSet = value!;
});
}
},
),
Expanded(
child: Markdown(
key: Key(_extensionSet.name),
data: snapshot.data!,
imageDirectory: 'https://raw.githubusercontent.com',
extensionSet: _extensionSet.value,
onTapLink: (text, href, title) =>
linkOnTapHandler(context, text, href, title),
),
),
],
);
} else {
return CircularProgressIndicator();
}
},
);
}
// Handle the link. The [href] in the callback contains information
// from the link. The url_launcher package or other similar package
// can be used to execute the link.
void linkOnTapHandler(
BuildContext context,
String text,
String? href,
String title,
) async {
showDialog(
context: context,
builder: (context) => _createDialog(context, text, href, title),
);
}
Widget _createDialog(
BuildContext context, String text, String? href, String title) =>
AlertDialog(
title: Text('Reference Link'),
content: SingleChildScrollView(
child: ListBody(
children: [
Text(
'See the following link for more information:',
style: Theme.of(context).textTheme.bodyText1,
),
SizedBox(height: 8),
Text(
'Link text: $text',
style: Theme.of(context).textTheme.bodyText2,
),
SizedBox(height: 8),
Text(
'Link destination: $href',
style: Theme.of(context).textTheme.bodyText2,
),
SizedBox(height: 8),
Text(
'Link title: $title',
style: Theme.of(context).textTheme.bodyText2,
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK'),
)
],
);
}

View File

@ -0,0 +1,73 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
import 'package:markdown/markdown.dart' as md;
import '../shared/markdown_demo_widget.dart';
const String _data = """
## Centered Title
###### ※ ※ ※
""";
const String _notes = """
# Centered Title Demo
---
## Overview
This example demonstrates how to implement a centered headline using a custom builder.
""";
class CenteredHeaderDemo extends StatelessWidget implements MarkdownDemoWidget {
static const _title = 'Centered Header Demo';
@override
String get title => CenteredHeaderDemo._title;
@override
String get description =>
'An example of using a user defined builder to implement a centered headline';
@override
Future<String> get data => Future<String>.value(_data);
@override
Future<String> get notes => Future<String>.value(_notes);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Markdown(
data: snapshot.data!,
builders: {
'h2': CenteredHeaderBuilder(),
'h6': CenteredHeaderBuilder(),
},
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
class CenteredHeaderBuilder extends MarkdownElementBuilder {
@override
Widget visitText(md.Text text, TextStyle? preferredStyle) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(text.text, style: preferredStyle),
],
);
}
}

View File

@ -0,0 +1,117 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
import 'package:markdown/markdown.dart' as md;
import '../shared/markdown_demo_widget.dart';
import '../shared/markdown_extensions.dart';
const String _notes = """
# Extended Emoji Demo
---
## Overview
This simple example demonstrates how to subclass an existing inline syntax
parser to extend, enhance, or modify its behavior. This example shows how to
subclass the EmojiSyntax inline syntax parser to support alternative names for
the thumbs up and thumbs down emoji characters. The emoji character map used by
EmojiSyntax has the keys "+1" and "-1" associated with the thumbs up and thumbs
down emoji characters, respectively. The ExtendedEmojiSyntax subclass extends
the EmojiSyntax class by overriding the onMatch method to intercept the call
from the parser. ExtendedEmojiSyntax either handles the matched tag or passes
the match along to its parent for processing.
```
class ExtendedEmojiSyntax extends md.EmojiSyntax {
static const alternateTags = <String, String>{
'thumbsup': '👍',
'thumbsdown': '👎',
};
@override
bool onMatch(md.InlineParser parser, Match match) {
var emoji = alternateTags[match[1]];
if (emoji != null) {
parser.addNode(md.Text(emoji));
return true;
}
return super.onMatch(parser, match);
}
}
```
""";
class ExtendedEmojiDemo extends StatelessWidget implements MarkdownDemoWidget {
static const _title = 'Extended Emoji Demo';
@override
String get title => ExtendedEmojiDemo._title;
@override
String get description => 'Demonstrates how to extend an existing inline'
' syntax parser by intercepting the parser onMatch routine.';
@override
Future<String> get data =>
Future<String>.value('Simple test :smiley: :thumbsup:!');
@override
Future<String> get notes => Future<String>.value(_notes);
final _notExtended = '# Using Emoji Syntax\n';
final _extended = '# Using Extened Emoji Syntax\n';
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Container(
margin: EdgeInsets.all(12),
constraints: BoxConstraints.expand(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MarkdownBody(
data: _notExtended + snapshot.data!,
extensionSet: MarkdownExtensionSet.githubWeb.value,
),
SizedBox(
height: 24,
),
MarkdownBody(
data: _extended + snapshot.data!,
extensionSet: md.ExtensionSet([], [ExtendedEmojiSyntax()]),
),
],
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
class ExtendedEmojiSyntax extends md.EmojiSyntax {
static const alternateTags = <String, String>{
'thumbsup': '👍',
'thumbsdown': '👎',
};
@override
bool onMatch(md.InlineParser parser, Match match) {
var emoji = alternateTags[match[1]!];
if (emoji != null) {
parser.addNode(md.Text(emoji));
return true;
}
return super.onMatch(parser, match);
}
}

View File

@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import '../shared/markdown_demo_widget.dart';
const String _data = """
# Minimal Markdown Test
---
This is a simple Markdown test. Provide a text string with Markdown tags
to the Markdown widget and it will display the formatted output in a scrollable
widget.
## Section 1
Maecenas eget **arcu egestas**, mollis ex vitae, posuere magna. Nunc eget
aliquam tortor. Vestibulum porta sodales efficitur. Mauris interdum turpis
eget est condimentum, vitae porttitor diam ornare.
### Subsection A
Sed et massa finibus, blandit massa vel, vulputate velit. Vestibulum vitae
venenatis libero. ***Curabitur sem lectus, feugiat eu justo in, eleifend
accumsan ante.*** Sed a fermentum elit. Curabitur sodales metus id mi ornare,
in ullamcorper magna congue.
""";
const String _notes = """
# Minimal Markdown Demo
---
## Overview
The simplest use case that illustrates how to make use of the
flutter_markdown package is to include a Markdown widget in a widget tree
and supply it with a character string of text containing Markdown formatting
syntax. Here is a simple Flutter app that creates a Markdown widget that
formats and displays the text in the string _markdownData. The resulting
Flutter app demonstrates the use of headers, rules, and emphasis text from
plain text Markdown syntax.
## Usage
The code sample below demonstrates a simple Flutter app with a Markdown widget.
```
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
const String _markdownData = \"""
# Minimal Markdown Test
---
This is a simple Markdown test. Provide a text string with Markdown tags
to the Markdown widget and it will display the formatted output in a
scrollable widget.
## Section 1
Maecenas eget **arcu egestas**, mollis ex vitae, posuere magna. Nunc eget
aliquam tortor. Vestibulum porta sodales efficitur. Mauris interdum turpis
eget est condimentum, vitae porttitor diam ornare.
### Subsection A
Sed et massa finibus, blandit massa vel, vulputate velit. Vestibulum vitae
venenatis libero. **__Curabitur sem lectus, feugiat eu justo in, eleifend
accumsan ante.__** Sed a fermentum elit. Curabitur sodales metus id mi
ornare, in ullamcorper magna congue.
\""";
void main() {
runApp(
MaterialApp(
title: "Markdown Demo",
home: Scaffold(
appBar: AppBar(
title: const Text('Simple Markdown Demo'),
),
body: SafeArea(
child: Markdown(
data: _markdownData,
),
),
),
),
);
}
```
""";
class MinimalMarkdownDemo extends StatelessWidget
implements MarkdownDemoWidget {
static const _title = 'Minimal Markdown Demo';
@override
String get title => MinimalMarkdownDemo._title;
@override
String get description => 'A minimal example of how to use the Markdown '
'widget in a Flutter app.';
@override
Future<String> get data => Future<String>.value(_data);
@override
Future<String> get notes => Future<String>.value(_notes);
@override
Widget build(BuildContext context) {
return Markdown(
data: _data,
);
}
}

View File

@ -0,0 +1,179 @@
// 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';
import '../shared/markdown_demo_widget.dart';
const String _markdownData = """
# Markdown Example
Markdown allows you to easily include formatted text, images, and even formatted
Dart code in your app.
## Titles
Setext-style
```
This is an H1
=============
This is an H2
-------------
```
Atx-style
```
# This is an H1
## This is an H2
###### This is an H6
```
Select the valid headers:
- [x] `# hello`
- [ ] `#hello`
## Links
[Google's Homepage][Google]
```
[inline-style](https://www.google.com)
[reference-style][Google]
```
## Images
![Flutter logo](/dart-lang/site-shared/master/src/_assets/image/flutter/icon/64.png)
## Tables
|Syntax |Result |
|---------------------------------------|-------------------------------------|
|`*italic 1*` |*italic 1* |
|`_italic 2_` | _italic 2_ |
|`**bold 1**` |**bold 1** |
|`__bold 2__` |__bold 2__ |
|`This is a ~~strikethrough~~` |This is a ~~strikethrough~~ |
|`***italic bold 1***` |***italic bold 1*** |
|`___italic bold 2___` |___italic bold 2___ |
|`***~~italic bold strikethrough 1~~***`|***~~italic bold strikethrough 1~~***|
|`~~***italic bold strikethrough 2***~~`|~~***italic bold strikethrough 2***~~|
## Styling
Style text as _italic_, __bold__, ~~strikethrough~~, or `inline code`.
- Use bulleted lists
- To better clarify
- Your points
## Code blocks
Formatted Dart code looks really pretty too:
```
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Markdown(data: markdownData),
),
));
}
```
## Center Title
###### ※ ※ ※
_* How to implement it see main.dart#L129 in example._
## Custom Syntax
NaOH + Al_2O_3 = NaAlO_2 + H_2O
C_4H_10 = C_2H_6 + C_2H_4
## Markdown widget
This is an example of how to create your own Markdown widget:
Markdown(data: 'Hello _world_!');
Enjoy!
[Google]: https://www.google.com/
## Line Breaks
This is an example of how to create line breaks (tab or two whitespaces):
line 1
line 2
line 3
""";
const String _notes = """
# Original Markdown Demo
---
## Overview
This is the original Flutter Markdown demo example that was created to
show how to use the flutter_markdown package. There were limitations in
the implementation of this demo example that didn't show the full potential
or extensibility of using the flutter_markdown package. This demo example
is being preserved for reference purposes.
## Comments
This demo example is being preserved for reference purposes.
""";
class OriginalMarkdownDemo extends StatelessWidget
implements MarkdownDemoWidget {
static const _title = 'Original Markdown Demo';
@override
String get title => OriginalMarkdownDemo._title;
@override
String get description => 'The original demo example. This demo was '
'include with versions of the package prior to version 0.4.4.';
@override
Future<String> get data => Future<String>.value(_markdownData);
@override
Future<String> get notes => Future<String>.value(_notes);
final controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Markdown(
controller: controller,
selectable: true,
data: _markdownData,
imageDirectory: 'https://raw.githubusercontent.com',
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.arrow_upward),
onPressed: () => controller.animateTo(0,
duration: Duration(seconds: 1), curve: Curves.easeOut),
),
);
}
}

View File

@ -0,0 +1,164 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
import 'package:markdown/markdown.dart' as md;
import '../shared/markdown_demo_widget.dart';
// Markdown source data showing the use of subscript tags.
const String _data = """
## Subscript Syntax
NaOH + Al_2O_3 = NaAlO_2 + H_2O
C_4H_10 = C_2H_6 + C_2H_4
""";
const String _notes = """
# Subscript Syntax Demo
---
## Overview
This is an example of how to create an inline syntax parser with an
associated element builder. This example defines an inline syntax parser that
matches instances of an underscore character "**_**" followed by a integer
numerical value. When the parser finds a match for this syntax sequence,
a '**sub**' element is inserted into the abstract syntac tree. The supplied
builder for the '**sub**' element, SubscriptBuilder, is then called to create
an appropriate RichText widget for the formatted output.
## Usage
To support a new custom inline Markdown tag, an inline syntax object needs to be
defined for the Markdown parser and an element builder which is deligated the
task of building the appropriate Flutter widgets for the resulting Markdown
output. Instances of these objects need to be provided to the Markdown widget.
```
Markdown(
data: _data,
builders: {
'sub': SubscriptBuilder(),
},
extensionSet: md.ExtensionSet([], [SubscriptSyntax()]),
);
```
### Inline Syntax Class
```
class SubscriptSyntax extends md.InlineSyntax {
static final _pattern = r'_([0-9]+)';
SubscriptSyntax() : super(_pattern);
@override
bool onMatch(md.InlineParser parser, Match match) {
parser.addNode(md.Element.text('sub', match[1]));
return true;
}
```
### Markdown Element Builder
```
class SubscriptBuilder extends MarkdownElementBuilder {
static const List<String> _subscripts = [
'₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉'
];
@override
Widget visitElementAfter(md.Element element, TextStyle preferredStyle) {
String textContent = element.textContent;
String text = '';
for (int i = 0; i < textContent.length; i++) {
text += _subscripts[int.parse(textContent[i])];
}
return SelectableText.rich(TextSpan(text: text));
}
}
```
""";
/// The subscript syntax demo provides an example of creating an inline syntax
/// object which defines the syntax for the Markdown inline parser and an
/// accompanying Markdown element builder object to handle subscript tags.
class SubscriptSyntaxDemo extends StatelessWidget
implements MarkdownDemoWidget {
static const _title = 'Subscript Syntax Demo';
@override
String get title => SubscriptSyntaxDemo._title;
@override
String get description => 'An example of how to create a custom inline '
'syntax parser and element builder for numerical subscripts.';
@override
Future<String> get data => Future<String>.value(_data);
@override
Future<String> get notes => Future<String>.value(_notes);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Markdown(
data: snapshot.data!,
builders: {
'sub': SubscriptBuilder(),
},
extensionSet: md.ExtensionSet([], [SubscriptSyntax()]),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
class SubscriptBuilder extends MarkdownElementBuilder {
static const List<String> _subscripts = [
'',
'',
'',
'',
'',
'',
'',
'',
'',
''
];
@override
Widget visitElementAfter(md.Element element, TextStyle? preferredStyle) {
// We don't currently have a way to control the vertical alignment of text spans.
// See https://github.com/flutter/flutter/issues/10906#issuecomment-385723664
String textContent = element.textContent;
String text = '';
for (int i = 0; i < textContent.length; i++) {
text += _subscripts[int.parse(textContent[i])];
}
return SelectableText.rich(TextSpan(text: text));
}
}
class SubscriptSyntax extends md.InlineSyntax {
static final _pattern = r'_([0-9]+)';
SubscriptSyntax() : super(_pattern);
@override
bool onMatch(md.InlineParser parser, Match match) {
parser.addNode(md.Element.text('sub', match[1]!));
return true;
}
}

View File

@ -0,0 +1,127 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import '../shared/dropdown_menu.dart';
import '../shared/markdown_demo_widget.dart';
import '../shared/markdown_extensions.dart';
const String _notes = """
# Wrap Alignment Demo
---
The Wrap Alignment Demo shows the effect of defining a wrap alignment for
various Markdown elements. Wrap alignments for the block elements text
paragraphs, headers, ordered and unordered lists, blockquotes, and code blocks
are set in the **MarkdownStyleSheet**. This demo shows the effect of setting
this parameter universally on these block elements for illustration purposes,
but they are independent settings.
This demo also shows the effect of setting the **MarkdownStyleSheet** block
spacing parameter. The Markdown widget lays out block elements in a column using
**SizedBox** widgets to separate widgets with formatted output. The block
spacing parameter sets the height of the **SizedBox**.
""";
class WrapAlignmentDemo extends StatefulWidget implements MarkdownDemoWidget {
static const _title = 'Wrap Alignment Demo';
@override
String get title => WrapAlignmentDemo._title;
@override
String get description => 'Shows the effect the wrap alignment and block '
'spacing parameters have on various Markdown tagged elements.';
@override
Future<String> get data async =>
await rootBundle.loadString('assets/markdown_test_page.md');
@override
Future<String> get notes => Future<String>.value(_notes);
@override
_WrapAlignmentDemoState createState() => _WrapAlignmentDemoState();
}
class _WrapAlignmentDemoState extends State<WrapAlignmentDemo> {
var _blockSpacing = 8.0;
var _wrapAlignment = WrapAlignment.start;
final _wrapAlignmentMenuItems = Map<String, WrapAlignment>.fromIterables(
WrapAlignment.values.map((e) => e.displayTitle),
WrapAlignment.values,
);
static const _spacing = [4.0, 8.0, 16.0, 24.0, 32.0];
final _blockSpacingMenuItems = Map<String, double>.fromIterables(
_spacing.map((e) => '${e.toString()}'),
_spacing,
);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: widget.data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Column(
children: [
DropdownMenu<WrapAlignment>(
items: _wrapAlignmentMenuItems,
label: 'Wrap Alignment:',
initialValue: _wrapAlignment,
onChanged: (value) {
if (value != _wrapAlignment) {
setState(() {
_wrapAlignment = value!;
});
}
},
),
DropdownMenu<double>(
items: _blockSpacingMenuItems,
label: 'Block Spacing:',
initialValue: _blockSpacing,
onChanged: (value) {
if (value != _blockSpacing) {
setState(() {
_blockSpacing = value!;
});
}
},
),
Expanded(
child: Markdown(
key: Key(_wrapAlignment.toString()),
data: snapshot.data!,
imageDirectory: 'https://raw.githubusercontent.com',
styleSheet:
MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
blockSpacing: _blockSpacing,
textAlign: _wrapAlignment,
h1Align: _wrapAlignment,
h2Align: _wrapAlignment,
h3Align: _wrapAlignment,
h4Align: _wrapAlignment,
h5Align: _wrapAlignment,
h6Align: _wrapAlignment,
unorderedListAlign: _wrapAlignment,
orderedListAlign: _wrapAlignment,
blockquoteAlign: _wrapAlignment,
codeblockAlign: _wrapAlignment,
),
),
),
],
);
} else {
return CircularProgressIndicator();
}
},
);
}
}

View File

@ -0,0 +1,78 @@
// 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.
///
/// The simplest use case that illustrates how to make use of the
/// flutter_markdown package is to include a Markdown widget in a widget tree
/// and supply it with a character string of text containing Markdown formatting
/// syntax. Here is a simple Flutter app that creates a Markdown widget that
/// formats and displays the text in the string _markdownData. The resulting
/// Flutter app demonstrates the use of headers, rules, and emphasis text from
/// plain text Markdown syntax.
///
/// import 'package:flutter/material.dart';
/// import 'package:flutter_markdown/flutter_markdown.dart';
///
/// const String _markdownData = """
/// # Minimal Markdown Test
/// ---
/// This is a simple Markdown test. Provide a text string with Markdown tags
/// to the Markdown widget and it will display the formatted output in a
/// scrollable widget.
///
/// ## Section 1
/// Maecenas eget **arcu egestas**, mollis ex vitae, posuere magna. Nunc eget
/// aliquam tortor. Vestibulum porta sodales efficitur. Mauris interdum turpis
/// eget est condimentum, vitae porttitor diam ornare.
///
/// ### Subsection A
/// Sed et massa finibus, blandit massa vel, vulputate velit. Vestibulum vitae
/// venenatis libero. **__Curabitur sem lectus, feugiat eu justo in, eleifend
/// accumsan ante.__** Sed a fermentum elit. Curabitur sodales metus id mi
/// ornare, in ullamcorper magna congue.
/// """;
///
/// void main() {
/// runApp(
/// MaterialApp(
/// title: "Markdown Demo",
/// home: Scaffold(
/// appBar: AppBar(
/// title: const Text('Simple Markdown Demo'),
/// ),
/// body: SafeArea(
/// child: Markdown(
/// data: _markdownData,
/// ),
/// ),
/// ),
/// ),
/// );
/// }
///
/// The flutter_markdown package has options for customizing and extending the
/// parsing of Markdown syntax and building of the formatted output. The demos
/// in this example app illustrate some of the potentials of the
/// flutter_markdown package.
import 'package:flutter/material.dart';
import 'screens/demo_screen.dart';
import 'screens/home_screen.dart';
import 'shared/markdown_demo_widget.dart';
void main() {
runApp(
MaterialApp(
title: "Markdown Demos",
initialRoute: '/',
home: HomeScreen(),
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: (_) => DemoScreen(
child: settings.arguments as MarkdownDemoWidget?,
),
);
},
),
);
}

View File

@ -0,0 +1,53 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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 '../screens/demo_screen.dart';
import '../shared/markdown_demo_widget.dart';
class DemoCard extends StatelessWidget {
final MarkdownDemoWidget widget;
const DemoCard({Key? key, required this.widget}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => Navigator.pushNamed(
context,
DemoScreen.routeName,
arguments: widget,
),
child: Container(
alignment: Alignment.center,
child: ConstrainedBox(
constraints:
BoxConstraints(minHeight: 50, minWidth: 425, maxWidth: 425),
child: Card(
color: Colors.blue,
margin: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.title,
style: Theme.of(context).primaryTextTheme.headline5,
),
SizedBox(
height: 6,
),
Text(
widget.description,
style: Theme.of(context).primaryTextTheme.bodyText1,
),
],
),
)),
),
),
);
}
}

View File

@ -0,0 +1,175 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
import '../shared/markdown_demo_widget.dart';
import '../shared/markdown_extensions.dart';
class DemoScreen extends StatelessWidget {
static const routeName = '/demoScreen';
final MarkdownDemoWidget? child;
const DemoScreen({Key? key, required this.child}) : super(key: key);
final _tabLabels = const <String>['Formatted', 'Raw', 'Notes'];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text(child!.title),
bottom: TabBar(
indicatorPadding: EdgeInsets.only(bottom: 8),
indicatorSize: TabBarIndicatorSize.label,
tabs: [
for (var label in _tabLabels) Tab(text: label),
],
),
),
body: TabBarView(
children: [
DemoFormattedView(child: child),
DemoRawDataView(data: child!.data),
DemoNotesView(notes: child!.notes), //child.notes as String),
],
),
),
);
}
}
class DemoFormattedView extends StatelessWidget {
final Widget? child;
const DemoFormattedView({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 1250),
child: child,
),
);
}
}
class DemoRawDataView extends StatelessWidget {
final Future<String> data;
const DemoRawDataView({Key? key, required this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: data,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Text(
snapshot.data!,
softWrap: true,
style: Theme.of(context)
.primaryTextTheme
.bodyText1!
.copyWith(fontFamily: 'Roboto Mono', color: Colors.black),
),
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}
class DemoNotesView extends StatelessWidget {
final Future<String> notes;
const DemoNotesView({Key? key, required this.notes}) : super(key: key);
// Handle the link. The [href] in the callback contains information
// from the link. The url_launcher package or other similar package
// can be used to execute the link.
void linkOnTapHandler(
BuildContext context,
String text,
String? href,
String title,
) async {
showDialog(
context: context,
builder: (context) => _createDialog(context, text, href, title),
);
}
Widget _createDialog(
BuildContext context,
String text,
String? href,
String title,
) =>
AlertDialog(
title: Text('Reference Link'),
content: SingleChildScrollView(
child: ListBody(
children: [
Text(
'See the following link for more information:',
style: Theme.of(context).textTheme.bodyText1,
),
SizedBox(height: 8),
Text(
'Link text: $text',
style: Theme.of(context).textTheme.bodyText2,
),
SizedBox(height: 8),
Text(
'Link destination: $href',
style: Theme.of(context).textTheme.bodyText2,
),
SizedBox(height: 8),
Text(
'Link title: $title',
style: Theme.of(context).textTheme.bodyText2,
),
],
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK'),
)
],
);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: notes,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Markdown(
data: snapshot.data!,
extensionSet: MarkdownExtensionSet.githubFlavored.value,
onTapLink: (text, href, title) =>
linkOnTapHandler(context, text, href, title),
);
} else {
return CircularProgressIndicator();
}
},
);
}
}

View File

@ -0,0 +1,48 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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 '../demos/centered_header_demo.dart';
import '../demos/basic_markdown_demo.dart';
import '../demos/extended_emoji_demo.dart';
import '../demos/minimal_markdown_demo.dart';
import '../demos/original_demo.dart';
import '../demos/subscript_syntax_demo.dart';
import '../demos/wrap_alignment_demo.dart';
import '../screens/demo_card.dart';
import '../shared/markdown_demo_widget.dart';
class HomeScreen extends StatelessWidget {
static const routeName = '/homeScreen';
final _demos = <MarkdownDemoWidget>[
MinimalMarkdownDemo(),
BasicMarkdownDemo(),
WrapAlignmentDemo(),
SubscriptSyntaxDemo(),
ExtendedEmojiDemo(),
OriginalMarkdownDemo(),
CenteredHeaderDemo(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: const Text('Markdown Demos'),
),
body: SafeArea(
child: Container(
color: Colors.black12,
child: ListView(
children: [
for (var demo in _demos) DemoCard(widget: demo),
],
),
),
),
);
}
}

View File

@ -0,0 +1,80 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
class DropdownMenu<T> extends StatelessWidget {
final Map<String, T> items;
final T initialValue;
final String label;
final TextStyle? labelStyle;
final ValueChanged<T?>? onChanged;
final Color background;
final EdgeInsetsGeometry padding;
final Color menuItemBackground;
final EdgeInsetsGeometry menuItemMargin;
DropdownMenu({
Key? key,
required this.items,
required this.initialValue,
required this.label,
this.labelStyle,
Color? background,
EdgeInsetsGeometry? padding,
Color? menuItemBackground,
EdgeInsetsGeometry? menuItemMargin,
this.onChanged,
}) : assert(
items.length > 0, 'The items map must contain at least one entry'),
this.background = background ?? Colors.black12,
this.padding =
padding ?? EdgeInsets.symmetric(horizontal: 12, vertical: 8),
this.menuItemBackground = menuItemBackground ?? Colors.white,
this.menuItemMargin = menuItemMargin ?? EdgeInsets.only(left: 4),
super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: background,
padding: padding,
child: Row(
children: [
Text(
label,
style: labelStyle ?? Theme.of(context).textTheme.subtitle1,
),
Container(
color: menuItemBackground,
margin: menuItemMargin,
child: DropdownButton<T>(
isDense: true,
value: initialValue,
items: [
for (var item in items.keys)
DropdownMenuItem<T>(
child: Container(
padding: EdgeInsets.only(left: 4),
child: Text(item),
),
value: items[item],
),
],
onChanged: (value) => onChanged!(value),
),
),
],
),
);
}
}

View File

@ -0,0 +1,31 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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';
abstract class MarkdownDemoWidget extends Widget {
// The title property should be a short name to uniquely identify the example
// demo. The title will be displayed at the top of the card in the home screen
// to identify the demo and as the banner title on the demo screen.
String get title;
// The description property should be a short explanation to provide
// additional information to clarify the actions performed by the demo. This
// should be a terse explanation of no more than three sentences.
String get description;
// The data property is the sample Markdown source text data to be displayed
// in the Formatted and Raw tabs of the demo screen. This data will be used by
// the demo widget that implements MarkdownDemoWidget to format the Markdown
// data to be displayed in the Formatted tab. The raw source text of data is
// used by the Raw tab of the demo screen. The data can be as short or as long
// as needed for demonstration purposes.
Future<String> get data;
// The notes property is a detailed explanation of the syntax, concepts,
// comments, notes, or other additional information useful in explaining the
// demo. The notes are displayed in the Notes tab of the demo screen. Notes
// supports Markdown data to allow for rich text formatting.
Future<String> get notes;
}

View File

@ -0,0 +1,60 @@
// Copyright 2020 Quiverware LLC. Open source contribution. 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/foundation.dart';
import 'package:flutter/material.dart';
import 'package:markdown/markdown.dart' as md;
enum MarkdownExtensionSet { none, commonMark, githubFlavored, githubWeb }
extension MarkdownExtensionSetExtension on MarkdownExtensionSet {
String get name => describeEnum(this);
String get displayTitle => () {
switch (this) {
case MarkdownExtensionSet.none:
return 'None';
case MarkdownExtensionSet.commonMark:
return 'Common Mark';
case MarkdownExtensionSet.githubFlavored:
return 'GitHub Flavored';
case MarkdownExtensionSet.githubWeb:
return 'GitHub Web';
}
}();
md.ExtensionSet get value => () {
switch (this) {
case MarkdownExtensionSet.none:
return md.ExtensionSet.none;
case MarkdownExtensionSet.commonMark:
return md.ExtensionSet.commonMark;
case MarkdownExtensionSet.githubFlavored:
return md.ExtensionSet.gitHubFlavored;
case MarkdownExtensionSet.githubWeb:
return md.ExtensionSet.gitHubWeb;
}
}();
}
extension WrapAlignmentExtension on WrapAlignment {
String get name => describeEnum(this);
String get displayTitle => () {
switch (this) {
case WrapAlignment.center:
return 'Center';
case WrapAlignment.end:
return 'End';
case WrapAlignment.spaceAround:
return 'Space Around';
case WrapAlignment.spaceBetween:
return 'Space Between';
case WrapAlignment.spaceEvenly:
return 'Space Evenly';
case WrapAlignment.start:
return 'Start';
}
}();
}

View File

@ -0,0 +1 @@
flutter/ephemeral

View File

@ -0,0 +1,106 @@
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
set(BINARY_NAME "flutter_markdown_example")
set(APPLICATION_ID "io.flutter.packages.flutter_markdown_example")
cmake_policy(SET CMP0063 NEW)
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Configure build options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
# Flutter library and tool build rules.
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Application build
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
apply_standard_settings(${BINARY_NAME})
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
if(PLUGIN_BUNDLED_LIBRARIES)
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()

View File

@ -0,0 +1,91 @@
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid)
pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
PkgConfig::BLKID
PkgConfig::LZMA
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
linux-x64 ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)

View File

@ -0,0 +1,9 @@
//
// Generated file. Do not edit.
//
#include "generated_plugin_registrant.h"
void fl_register_plugins(FlPluginRegistry* registry) {
}

View File

@ -0,0 +1,13 @@
//
// Generated file. Do not edit.
//
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_

View File

@ -0,0 +1,15 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

View File

@ -0,0 +1,6 @@
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}

View File

@ -0,0 +1,104 @@
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen *screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "flutter_markdown_example");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
}
else {
gtk_window_set_title(window, "flutter_markdown_example");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject *object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
nullptr));
}

View File

@ -0,0 +1,18 @@
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_

View File

@ -0,0 +1,6 @@
# Flutter-related
**/Flutter/ephemeral/
**/Pods/
# Xcode-related
**/xcuserdata/

View File

@ -0,0 +1 @@
#include "ephemeral/Flutter-Generated.xcconfig"

View File

@ -0,0 +1 @@
#include "ephemeral/Flutter-Generated.xcconfig"

Some files were not shown because too many files have changed in this diff Show More