Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
dart_pdf
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David PHAM-VAN
2020-02-08 10:03:16 -0500
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
1cab091b736520930e5556524109d46428d47f55
1cab091b
1 parent
e6147663
Add Social Preview image
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
434 additions
and
4 deletions
test/github_social_preview.dart
test/pubspec.yaml
test/github_social_preview.dart
0 → 100644
View file @
1cab091
import
'dart:io'
;
import
'package:pdf/pdf.dart'
;
import
'package:pdf/widgets.dart'
;
import
'package:string_scanner/string_scanner.dart'
;
const
dpi
=
72.0
;
const
px
=
dpi
/
PdfPageFormat
.
inch
*
PdfPageFormat
.
point
;
void
main
(
)
{
// Open self
final
source
=
File
(
'../test/github_social_preview.dart'
).
readAsStringSync
();
final
code
=
DartSyntaxHighlighter
(
SyntaxHighlighterStyle
.
dark
(),
).
format
(
source
.
substring
(
source
.
lastIndexOf
(
'// START'
)
+
9
,
source
.
lastIndexOf
(
'// END'
)
-
3
,
),
);
// START
// Enable debug painting
Document
.
debug
=
true
;
// Create a pdf document
final
pdf
=
Document
(
title:
'Github Social Preview'
,
author:
'David PHAM-VAN'
,
);
// New page
pdf
.
addPage
(
Page
(
pageFormat:
PdfPageFormat
(
1280
*
px
,
640
*
px
,
marginAll:
78
*
px
,
),
build:
(
context
)
=>
Row
(
mainAxisSize:
MainAxisSize
.
max
,
children:
[
// Display the source code on the first half of the page
Flexible
(
fit:
FlexFit
.
tight
,
child:
Container
(
color:
PdfColors
.
grey800
,
padding:
EdgeInsets
.
all
(
10
*
px
),
child:
ClipRect
(
child:
RichText
(
text:
code
)),
),
),
// Add a vertical separator
Container
(
width:
5
*
px
,
color:
PdfColors
.
lightBlue
),
// Show "Hello World!" centered and rotated on the second half of the page
Flexible
(
fit:
FlexFit
.
tight
,
child:
Center
(
child:
Transform
.
rotateBox
(
angle:
.
2
,
child:
Text
(
'Hello World!'
,
style:
TextStyle
(
font:
Font
.
helveticaBold
(),
fontSize:
50
*
px
,
),
),
),
),
),
],
),
),
);
// END
// Save the file
File
(
'social_preview.pdf'
).
writeAsBytesSync
(
pdf
.
save
());
// Convert to png
Process
.
runSync
(
'pdftocairo'
,
[
'social_preview.pdf'
,
'-png'
,
'-r'
,
'72'
,
'social_preview.png'
]);
}
class
SyntaxHighlighterStyle
{
const
SyntaxHighlighterStyle
(
{
this
.
baseStyle
,
this
.
numberStyle
,
this
.
commentStyle
,
this
.
keywordStyle
,
this
.
stringStyle
,
this
.
punctuationStyle
,
this
.
classStyle
,
this
.
constantStyle
});
final
TextStyle
baseStyle
;
final
TextStyle
numberStyle
;
final
TextStyle
commentStyle
;
final
TextStyle
keywordStyle
;
final
TextStyle
stringStyle
;
final
TextStyle
punctuationStyle
;
final
TextStyle
classStyle
;
final
TextStyle
constantStyle
;
factory
SyntaxHighlighterStyle
.
dark
()
=>
SyntaxHighlighterStyle
(
baseStyle:
TextStyle
(
font:
Font
.
courierBold
(),
color:
PdfColors
.
white
,
fontSize:
10
*
px
,
),
numberStyle:
TextStyle
(
color:
PdfColors
.
purple300
),
commentStyle:
TextStyle
(
color:
PdfColors
.
green600
),
keywordStyle:
TextStyle
(
color:
PdfColors
.
blue600
),
stringStyle:
TextStyle
(
color:
PdfColors
.
orange400
),
punctuationStyle:
TextStyle
(
color:
PdfColors
.
pink
),
classStyle:
TextStyle
(
color:
PdfColors
.
cyan
),
constantStyle:
TextStyle
(
color:
PdfColors
.
pink
),
);
}
class
DartSyntaxHighlighter
{
DartSyntaxHighlighter
(
this
.
_style
)
{
_spans
=
<
_HighlightSpan
>[];
}
final
SyntaxHighlighterStyle
_style
;
static
const
List
<
String
>
_keywords
=
<
String
>[
'abstract'
,
'as'
,
'assert'
,
'async'
,
'await'
,
'break'
,
'case'
,
'catch'
,
'class'
,
'const'
,
'continue'
,
'default'
,
'deferred'
,
'do'
,
'dynamic'
,
'else'
,
'enum'
,
'export'
,
'external'
,
'extends'
,
'factory'
,
'false'
,
'final'
,
'finally'
,
'for'
,
'get'
,
'if'
,
'implements'
,
'import'
,
'in'
,
'is'
,
'library'
,
'new'
,
'null'
,
'operator'
,
'part'
,
'rethrow'
,
'return'
,
'set'
,
'static'
,
'super'
,
'switch'
,
'sync'
,
'this'
,
'throw'
,
'true'
,
'try'
,
'typedef'
,
'var'
,
'void'
,
'while'
,
'with'
,
'yield'
];
static
const
List
<
String
>
_builtInTypes
=
<
String
>[
'int'
,
'double'
,
'num'
,
'bool'
];
String
_src
;
StringScanner
_scanner
;
List
<
_HighlightSpan
>
_spans
;
TextSpan
format
(
String
source
)
{
_src
=
source
;
_scanner
=
StringScanner
(
_src
);
if
(
_generateSpans
())
{
// Successfully parsed the code
final
List
<
TextSpan
>
formattedText
=
<
TextSpan
>[];
int
currentPosition
=
0
;
for
(
_HighlightSpan
span
in
_spans
)
{
if
(
currentPosition
!=
span
.
start
)
formattedText
.
add
(
TextSpan
(
text:
_src
.
substring
(
currentPosition
,
span
.
start
)));
formattedText
.
add
(
TextSpan
(
style:
span
.
textStyle
(
_style
),
text:
span
.
textForSpan
(
_src
)));
currentPosition
=
span
.
end
;
}
if
(
currentPosition
!=
_src
.
length
)
formattedText
.
add
(
TextSpan
(
text:
_src
.
substring
(
currentPosition
,
_src
.
length
)));
_spans
.
clear
();
return
TextSpan
(
style:
_style
.
baseStyle
,
children:
formattedText
);
}
else
{
// Parsing failed, return with only basic formatting
return
TextSpan
(
style:
_style
.
baseStyle
,
text:
source
);
}
}
bool
_generateSpans
()
{
int
lastLoopPosition
=
_scanner
.
position
;
while
(!
_scanner
.
isDone
)
{
// Skip White space
_scanner
.
scan
(
RegExp
(
r'\s+'
));
// Block comments
if
(
_scanner
.
scan
(
RegExp
(
r'/\*(.|\n)*\*/'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
comment
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Line comments
if
(
_scanner
.
scan
(
'//'
))
{
final
int
startComment
=
_scanner
.
lastMatch
.
start
;
bool
eof
=
false
;
int
endComment
;
if
(
_scanner
.
scan
(
RegExp
(
r'.*\n'
)))
{
endComment
=
_scanner
.
lastMatch
.
end
-
1
;
}
else
{
eof
=
true
;
endComment
=
_src
.
length
;
}
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
comment
,
startComment
,
endComment
));
if
(
eof
)
{
break
;
}
continue
;
}
// Raw r"String"
if
(
_scanner
.
scan
(
RegExp
(
r'r".*"'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Raw r'String'
if
(
_scanner
.
scan
(
RegExp
(
r"r'.*'"
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Multiline """String"""
if
(
_scanner
.
scan
(
RegExp
(
r'"""(?:[^"\\]|\\(.|\n))*"""'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Multiline '''String'''
if
(
_scanner
.
scan
(
RegExp
(
r"'''(?:[^'\\]|\\(.|\n))*'''"
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// "String"
if
(
_scanner
.
scan
(
RegExp
(
r'"(?:[^"\\]|\\.)*"'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// 'String'
if
(
_scanner
.
scan
(
RegExp
(
r"'(?:[^'\\]|\\.)*'"
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
string
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Double
if
(
_scanner
.
scan
(
RegExp
(
r'\d+\.\d+'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
number
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Integer
if
(
_scanner
.
scan
(
RegExp
(
r'\d+'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
number
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Punctuation
if
(
_scanner
.
scan
(
RegExp
(
r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
punctuation
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Meta data
if
(
_scanner
.
scan
(
RegExp
(
r'@\w+'
)))
{
_spans
.
add
(
_HighlightSpan
(
_HighlightType
.
keyword
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
continue
;
}
// Words
if
(
_scanner
.
scan
(
RegExp
(
r'\w+'
)))
{
_HighlightType
type
;
String
word
=
_scanner
.
lastMatch
[
0
];
if
(
word
.
startsWith
(
'_'
))
{
word
=
word
.
substring
(
1
);
}
if
(
_keywords
.
contains
(
word
))
type
=
_HighlightType
.
keyword
;
else
if
(
_builtInTypes
.
contains
(
word
))
type
=
_HighlightType
.
keyword
;
else
if
(
_firstLetterIsUpperCase
(
word
))
type
=
_HighlightType
.
klass
;
else
if
(
word
.
length
>=
2
&&
word
.
startsWith
(
'k'
)
&&
_firstLetterIsUpperCase
(
word
.
substring
(
1
)))
type
=
_HighlightType
.
constant
;
if
(
type
!=
null
)
{
_spans
.
add
(
_HighlightSpan
(
type
,
_scanner
.
lastMatch
.
start
,
_scanner
.
lastMatch
.
end
));
}
}
// Check if this loop did anything
if
(
lastLoopPosition
==
_scanner
.
position
)
{
// Failed to parse this file, abort gracefully
return
false
;
}
lastLoopPosition
=
_scanner
.
position
;
}
_simplify
();
return
true
;
}
void
_simplify
()
{
for
(
int
i
=
_spans
.
length
-
2
;
i
>=
0
;
i
-=
1
)
{
if
(
_spans
[
i
].
type
==
_spans
[
i
+
1
].
type
&&
_spans
[
i
].
end
==
_spans
[
i
+
1
].
start
)
{
_spans
[
i
]
=
_HighlightSpan
(
_spans
[
i
].
type
,
_spans
[
i
].
start
,
_spans
[
i
+
1
].
end
);
_spans
.
removeAt
(
i
+
1
);
}
}
}
bool
_firstLetterIsUpperCase
(
String
str
)
{
if
(
str
.
isNotEmpty
)
{
final
String
first
=
str
.
substring
(
0
,
1
);
return
first
==
first
.
toUpperCase
();
}
return
false
;
}
}
enum
_HighlightType
{
number
,
comment
,
keyword
,
string
,
punctuation
,
klass
,
constant
}
class
_HighlightSpan
{
_HighlightSpan
(
this
.
type
,
this
.
start
,
this
.
end
);
final
_HighlightType
type
;
final
int
start
;
final
int
end
;
String
textForSpan
(
String
src
)
{
return
src
.
substring
(
start
,
end
);
}
TextStyle
textStyle
(
SyntaxHighlighterStyle
style
)
{
if
(
type
==
_HighlightType
.
number
)
return
style
.
numberStyle
;
else
if
(
type
==
_HighlightType
.
comment
)
return
style
.
commentStyle
;
else
if
(
type
==
_HighlightType
.
keyword
)
return
style
.
keywordStyle
;
else
if
(
type
==
_HighlightType
.
string
)
return
style
.
stringStyle
;
else
if
(
type
==
_HighlightType
.
punctuation
)
return
style
.
punctuationStyle
;
else
if
(
type
==
_HighlightType
.
klass
)
return
style
.
classStyle
;
else
if
(
type
==
_HighlightType
.
constant
)
return
style
.
constantStyle
;
else
return
style
.
baseStyle
;
}
}
...
...
test/pubspec.yaml
View file @
1cab091
...
...
@@ -10,15 +10,15 @@ environment:
sdk
:
"
>=2.1.0
<3.0.0"
flutter
:
"
^1.2.0"
dependencies
:
dependencies
:
flutter
:
sdk
:
flutter
markdown
:
meta
:
string_scanner
:
meta
:
string_scanner
:
pdf
:
printing
:
path
:
path
:
image
:
path_provider
:
...
...
Please
register
or
login
to post a comment