├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── HtmlSpanner
├── LICENSE-2.0.txt
├── README.md
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── pom.xml
├── publishBintray.gradle
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ └── java
│ │ └── com
│ │ └── sysdata
│ │ └── htmlspanner
│ │ ├── FontFamily.java
│ │ ├── FontResolver.java
│ │ ├── HtmlSpanner.java
│ │ ├── SpanCallback.java
│ │ ├── SpanStack.java
│ │ ├── SystemFontResolver.java
│ │ ├── TagNodeHandler.java
│ │ ├── TextUtil.java
│ │ ├── css
│ │ ├── CSSCompiler.java
│ │ └── CompiledRule.java
│ │ ├── exception
│ │ └── ParsingCancelledException.java
│ │ ├── handlers
│ │ ├── FontHandler.java
│ │ ├── HeaderHandler.java
│ │ ├── ImageHandler.java
│ │ ├── LinkHandler.java
│ │ ├── ListItemHandler.java
│ │ ├── MonoSpaceHandler.java
│ │ ├── NewLineHandler.java
│ │ ├── PreHandler.java
│ │ ├── StyleNodeHandler.java
│ │ ├── StyledTextHandler.java
│ │ ├── SubScriptHandler.java
│ │ ├── SuperScriptHandler.java
│ │ ├── TableHandler.java
│ │ ├── UnderlineHandler.java
│ │ ├── WrappingHandler.java
│ │ └── attributes
│ │ │ ├── AlignmentAttributeHandler.java
│ │ │ ├── BorderAttributeHandler.java
│ │ │ ├── HorizontalLineHandler.java
│ │ │ ├── StyleAttributeHandler.java
│ │ │ └── WrappingStyleHandler.java
│ │ ├── spans
│ │ ├── AlignNormalSpan.java
│ │ ├── AlignOppositeSpan.java
│ │ ├── BorderSpan.java
│ │ ├── CenterSpan.java
│ │ ├── FontFamilySpan.java
│ │ ├── HorizontalLineSpan.java
│ │ ├── LineHeightSpanImpl.java
│ │ ├── ListItemSpan.java
│ │ └── VerticalMarginSpan.java
│ │ └── style
│ │ ├── Style.java
│ │ ├── StyleCallback.java
│ │ └── StyleValue.java
│ └── test
│ └── java
│ └── com
│ └── sysdata
│ └── htmlspanner
│ └── RuleMatchingTest.java
├── LICENSE
├── README.md
├── app
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── sysdata
│ │ └── kt
│ │ └── sdhtmltextview
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── sysdata
│ │ │ └── kt
│ │ │ └── sdhtmltextview
│ │ │ └── MainActivity.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── sysdata
│ └── kt
│ └── sdhtmltextview
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── htmltextview
├── build.gradle
├── pom.xml
├── proguard-rules.pro
├── publishBintray.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── sysdata
│ │ └── kt
│ │ └── htmltextview
│ │ └── SDHtmlTextView.kt
│ └── res
│ └── values
│ ├── strings.xml
│ └── styles.xml
├── release
├── htmlspanner-release-1.0.3.aar
└── htmltextview-release-1.0.3.aar
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated files
2 | bin/
3 | gen/
4 | out/
5 |
6 | # Gradle files
7 | .gradle/
8 | build/
9 |
10 | # Local configuration file (sdk path, etc)
11 | local.properties
12 |
13 | # Proguard folder generated by Eclipse
14 | proguard/
15 |
16 | # Log Files
17 | *.log
18 |
19 | # Android Studio Navigation editor temp files
20 | .navigation/
21 |
22 | # Android Studio captures folder
23 | captures/
24 |
25 | # Intellij
26 | *.iml
27 | .idea/
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/HtmlSpanner/LICENSE-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/HtmlSpanner/README.md:
--------------------------------------------------------------------------------
1 | # Android HTML rendering library
2 |
3 | HtmlSpanner started as the HTML rendering library for PageTurner, but looking through some questions on StackOverflow I noticed how many people were struggling with the infamous ``Html.fromHtml()`` and getting its results to display properly in TextViews.
4 |
5 | HtmlSpanner allows you full control over how tags are rendered and gives you all the data about the location of a tag in the text. This allows proper handling of anchors, tables, numbered lists and unordered lists.
6 |
7 | The default link implementation just opens URLs, but it can be easily overridden to support anchors.
8 |
9 | HtmlSpanner uses HtmlCleaner to do most of the heavy lifting for parsing HTML files.
10 |
11 | # CSS support
12 |
13 | HtmlSpanner now also supports the most common subset of CSS: both style tags and style attributes are parsed by default, and the style of all built-in tags can be updated.
14 |
15 | # Usage
16 | In its simplest form, just call ``(new HtmlSpanner()).fromHtml()`` to get similar output as Android's ``Html.fromHtml()``.
17 |
18 | # HTMLCleaner Source
19 | see http://htmlcleaner.sourceforge.net/index.php
20 |
21 | The fork under https://github.com/amplafi/htmlcleaner can not be used on Android <= 2.1 as it uses java.lang.String.isEmpty
22 |
--------------------------------------------------------------------------------
/HtmlSpanner/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.jfrog.artifactory-upload'
3 | apply plugin: 'com.github.dcendents.android-maven'
4 |
5 | // This is the library version used when deploying the artifact
6 | version = "1.0.3"
7 |
8 | group = "it.sysdata.mobile"
9 |
10 | buildscript {
11 | dependencies {
12 | repositories {
13 | google()
14 | mavenCentral()
15 | // serve per org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1
16 | maven {
17 | url "https://plugins.gradle.org/m2/"
18 | }
19 | }
20 | // artifactory
21 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
22 | classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
23 | // bintray
24 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
25 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
26 | }
27 | }
28 |
29 | repositories {
30 | google()
31 | mavenCentral()
32 | maven {
33 | url "http://repo.pageturner-reader.org"
34 | }
35 | }
36 |
37 | dependencies {
38 | implementation fileTree(dir: 'libs', include: ['*.jar'])
39 | implementation 'net.sourceforge.htmlcleaner:htmlcleaner:2.16'
40 | implementation 'com.osbcp.cssparser:cssparser:1.5'
41 | implementation 'io.reactivex:rxjava:1.3.8'
42 | implementation 'io.reactivex:rxandroid:1.2.1'
43 | }
44 |
45 | android {
46 | compileSdkVersion 21
47 |
48 | defaultConfig {
49 | minSdkVersion 9
50 | targetSdkVersion 21
51 | }
52 | }
53 |
54 | android {
55 | lintOptions {
56 | abortOnError false
57 | }
58 | }
59 |
60 | // pubblicazione maven
61 | Properties properties = new Properties()
62 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
63 | ext {
64 | // GROUP_ID
65 | publishedGroupId = group
66 | // ARTIFACT_ID
67 | artifact = 'htmlspanner'
68 | // VERSION_ID
69 | libraryVersion = version
70 |
71 | developerId = 'sysdata-mobile'
72 | developerName = ''
73 | developerEmail = 'team.mobile@sysdata.it'
74 |
75 | bintrayRepo = 'maven'
76 | bintrayName = 'sdHtmlSpanner'
77 | libraryName = 'htmlspanner'
78 | bintrayOrganization = 'sysdata-mobile'
79 | }
80 |
81 | //apply from: 'publishArtifactory.gradle'
82 | apply from: 'publishBintray.gradle'
83 |
84 |
--------------------------------------------------------------------------------
/HtmlSpanner/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/HtmlSpanner/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/HtmlSpanner/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Feb 28 10:37:10 CET 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
7 |
--------------------------------------------------------------------------------
/HtmlSpanner/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/HtmlSpanner/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/HtmlSpanner/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | net.nightwhistler.htmlspanner
6 | htmlspanner
7 | 0.5-SNAPSHOT
8 | jar
9 |
10 | htmlspanner
11 | http://maven.apache.org
12 |
13 |
14 | PageTurner Repo
15 | http://repo.pageturner-reader.org
16 |
17 |
18 |
19 |
20 | UTF-8
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven.plugins
27 | maven-compiler-plugin
28 |
29 | 1.6
30 | 1.6
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | com.google.android
40 | android
41 | 2.1.2
42 | provided
43 |
44 |
45 |
46 |
47 | net.sourceforge.htmlcleaner
48 | htmlcleaner
49 | 2.2
50 |
51 |
52 |
53 | com.osbcp.cssparser
54 | cssparser
55 | 1.5
56 |
57 |
58 |
59 | junit
60 | junit
61 | 4.8.2
62 | test
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/HtmlSpanner/publishBintray.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:3.1.3'
8 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
9 | classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
10 | }
11 | }
12 |
13 | apply plugin: 'com.android.library'
14 |
15 | ext {
16 | libraryDescription = ''
17 | siteUrl = 'https://github.com/SysdataSpA/SDHtmlTextView'
18 | gitUrl = 'https://github.com/SysdataSpA/SDHtmlTextView.git'
19 |
20 | licenseName = 'The Apache Software License, Version 2.0'
21 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
22 | allLicenses = ["Apache-2.0"]
23 | }
24 |
25 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
26 | apply plugin: 'com.github.dcendents.android-maven'
27 |
28 | group = publishedGroupId // Maven Group ID for the artifact
29 |
30 | install {
31 | repositories.mavenInstaller {
32 | // This generates POM.xml with proper parameters
33 | pom {
34 | project {
35 | packaging 'aar'
36 | groupId publishedGroupId
37 | artifactId artifact
38 |
39 | // Add your description here
40 | name libraryName
41 | description libraryDescription
42 | url siteUrl
43 |
44 | // Set your license
45 | licenses {
46 | license {
47 | name licenseName
48 | url licenseUrl
49 | }
50 | }
51 | developers {
52 | developer {
53 | id developerId
54 | name developerName
55 | email developerEmail
56 | }
57 | }
58 | scm {
59 | connection gitUrl
60 | developerConnection gitUrl
61 | url siteUrl
62 |
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
69 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
70 | apply plugin: 'com.jfrog.bintray'
71 | apply plugin: 'maven'
72 |
73 | version = libraryVersion
74 |
75 | task sourcesJar(type: Jar) {
76 | dependsOn = ['test', 'connectedAndroidTest']
77 | from android.sourceSets.main.java.srcDirs
78 | classifier = 'sources'
79 | }
80 |
81 | task writeNewPom {
82 | pom {
83 | project {
84 | packaging 'aar'
85 | name 'HtmlSpanner'
86 | url siteUrl
87 | licenses {
88 | license {
89 | name 'The Apache Software License, Version 2.0'
90 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
91 | distribution 'repo'
92 | }
93 | }
94 | }
95 | }.writeTo("$buildDir/poms/pom-default.xml")
96 | }
97 |
98 | artifacts {
99 | archives sourcesJar
100 | }
101 |
102 | // Bintray
103 | Properties properties = new Properties()
104 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
105 |
106 | bintray {
107 | user = properties.getProperty("bintray.user")
108 | key = properties.getProperty("bintray.apikey")
109 |
110 | configurations = ['archives']
111 | pkg {
112 | repo = bintrayRepo
113 | name = bintrayName
114 | desc = libraryDescription
115 | userOrg = bintrayOrganization
116 | websiteUrl = siteUrl
117 | vcsUrl = gitUrl
118 | licenses = allLicenses
119 | publish = true
120 | publicDownloadNumbers = true
121 | version {
122 | desc = libraryDescription
123 | gpg {
124 | sign = true //Determines whether to GPG sign the files. The default is false
125 | passphrase = properties.getProperty("bintray.gpg.password")
126 | //Optional. The passphrase for GPG signing'
127 | }
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/FontFamily.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sysdata.htmlspanner;
18 |
19 | import android.graphics.Typeface;
20 |
21 | public class FontFamily {
22 |
23 | private Typeface defaultTypeface;
24 |
25 | private Typeface boldTypeface;
26 |
27 | private Typeface italicTypeface;
28 |
29 | private Typeface boldItalicTypeface;
30 |
31 | private String name;
32 |
33 | public FontFamily(String name, Typeface defaultTypeFace) {
34 | this.name = name;
35 | this.defaultTypeface = defaultTypeFace;
36 | }
37 |
38 | public String getName() {
39 | return name;
40 | }
41 |
42 | public void setBoldItalicTypeface(Typeface boldItalicTypeface) {
43 | this.boldItalicTypeface = boldItalicTypeface;
44 | }
45 |
46 | public void setBoldTypeface(Typeface boldTypeface) {
47 | this.boldTypeface = boldTypeface;
48 | }
49 |
50 | public void setDefaultTypeface(Typeface defaultTypeface) {
51 | this.defaultTypeface = defaultTypeface;
52 | }
53 |
54 | public void setItalicTypeface(Typeface italicTypeface) {
55 | this.italicTypeface = italicTypeface;
56 | }
57 |
58 | public Typeface getBoldItalicTypeface() {
59 | return boldItalicTypeface;
60 | }
61 |
62 | public Typeface getBoldTypeface() {
63 | return boldTypeface;
64 | }
65 |
66 | public Typeface getDefaultTypeface() {
67 | return defaultTypeface;
68 | }
69 |
70 | public Typeface getItalicTypeface() {
71 | return italicTypeface;
72 | }
73 |
74 | public boolean isFakeBold() {
75 | return boldTypeface == null;
76 | }
77 |
78 | public boolean isFakeItalic() {
79 | return italicTypeface == null;
80 | }
81 |
82 | public String toString() {
83 | return name;
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/FontResolver.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner;
2 |
3 | /**
4 | * Interface for font-resolving components.
5 | */
6 | public interface FontResolver {
7 |
8 | FontFamily getDefaultFont();
9 |
10 | FontFamily getSansSerifFont();
11 |
12 | FontFamily getSerifFont();
13 |
14 | FontFamily getMonoSpaceFont();
15 |
16 | FontFamily getFont( String name );
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/SpanCallback.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner;
2 |
3 | import android.text.SpannableStringBuilder;
4 |
5 | /**
6 | * Created with IntelliJ IDEA.
7 | * User: alex
8 | * Date: 5/6/13
9 | * Time: 3:13 PM
10 | * To change this template use File | Settings | File Templates.
11 | */
12 | public interface SpanCallback {
13 |
14 | void applySpan( HtmlSpanner spanner, SpannableStringBuilder builder );
15 |
16 | }
17 |
18 |
19 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/SpanStack.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner;
2 |
3 | import android.text.Spannable;
4 | import android.text.SpannableStringBuilder;
5 | import android.util.Log;
6 | import com.sysdata.htmlspanner.css.CompiledRule;
7 | import com.sysdata.htmlspanner.style.Style;
8 | import org.htmlcleaner.TagNode;
9 |
10 | import java.util.*;
11 |
12 | /**
13 | * Simple stack structure that Spans can be pushed on.
14 | *
15 | * Handles the lookup and application of CSS styles.
16 | *
17 | * @author Alex Kuiper
18 | */
19 | public class SpanStack {
20 |
21 | private Stack spanItemStack = new Stack();
22 |
23 | private Set rules = new HashSet();
24 |
25 | private Map> lookupCache = new HashMap>();
26 |
27 | public void registerCompiledRule(CompiledRule rule) {
28 | this.rules.add( rule );
29 | }
30 |
31 | public Style getStyle( TagNode node, Style baseStyle ) {
32 |
33 | if ( ! lookupCache.containsKey(node) ) {
34 |
35 | Log.v("SpanStack", "Looking for matching CSS rules for node: "
36 | + "<" + node.getName() + " id='" + option(node.getAttributeByName("id"))
37 | + "' class='" + option(node.getAttributeByName("class")) + "'>");
38 |
39 | List matchingRules = new ArrayList();
40 | for ( CompiledRule rule: rules ) {
41 | if ( rule.matches(node)) {
42 | matchingRules.add(rule);
43 | }
44 | }
45 |
46 | Log.v("SpanStack", "Found " + matchingRules.size() + " matching rules.");
47 | lookupCache.put(node, matchingRules);
48 | }
49 |
50 | Style result = baseStyle;
51 |
52 | for ( CompiledRule rule: lookupCache.get(node) ) {
53 |
54 | Log.v( "SpanStack", "Applying rule " + rule );
55 |
56 | Style original = result;
57 | result = rule.applyStyle(result);
58 |
59 | Log.v("SpanStack", "Original style: " + original );
60 | Log.v("SpanStack", "Resulting style: " + result);
61 | }
62 |
63 | return result;
64 | }
65 |
66 | private static String option( String s ) {
67 | if ( s == null ) {
68 | return "";
69 | } else {
70 | return s;
71 | }
72 | }
73 |
74 | public void pushSpan( final Object span, final int start, final int end ) {
75 |
76 | if ( end > start ) {
77 | SpanCallback callback = new SpanCallback() {
78 | @Override
79 | public void applySpan(HtmlSpanner spanner, SpannableStringBuilder builder) {
80 | builder.setSpan(span, start, end,
81 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
82 | }
83 | };
84 |
85 | spanItemStack.push(callback);
86 | } else {
87 | Log.d( "SpanStack", "refusing to put span of type " + span.getClass().getSimpleName()
88 | + " and length " + (end - start) );
89 | }
90 | }
91 |
92 | public void pushSpan( SpanCallback callback ) {
93 | spanItemStack.push(callback);
94 | }
95 |
96 | public void applySpans(HtmlSpanner spanner, SpannableStringBuilder builder ) {
97 | while ( ! spanItemStack.isEmpty() ) {
98 | spanItemStack.pop().applySpan(spanner, builder);
99 | }
100 | }
101 |
102 |
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/SystemFontResolver.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner;
2 |
3 | import android.graphics.Typeface;
4 | import android.util.Log;
5 |
6 | /**
7 | * Created with IntelliJ IDEA.
8 | * User: alex
9 | * Date: 6/23/13
10 | * Time: 9:13 AM
11 | * To change this template use File | Settings | File Templates.
12 | */
13 | public class SystemFontResolver implements FontResolver {
14 |
15 | private FontFamily defaultFont;
16 |
17 | private FontFamily serifFont;
18 | private FontFamily sansSerifFont;
19 | private FontFamily monoSpaceFont;
20 |
21 |
22 | public SystemFontResolver() {
23 | this.defaultFont = new FontFamily("default", Typeface.DEFAULT);
24 | this.serifFont = new FontFamily("serif", Typeface.SERIF);
25 | this.sansSerifFont = new FontFamily("sans-serif", Typeface.SANS_SERIF);
26 | this.monoSpaceFont = new FontFamily("monospace", Typeface.MONOSPACE );
27 | }
28 |
29 | public FontFamily getDefaultFont() {
30 | return defaultFont;
31 | }
32 |
33 | public void setDefaultFont(FontFamily defaultFont) {
34 | this.defaultFont = defaultFont;
35 | }
36 |
37 | public FontFamily getSansSerifFont() {
38 | return sansSerifFont;
39 | }
40 |
41 | public void setSansSerifFont(FontFamily sansSerifFont) {
42 | this.sansSerifFont = sansSerifFont;
43 | }
44 |
45 | public FontFamily getSerifFont() {
46 | return serifFont;
47 | }
48 |
49 | public void setSerifFont(FontFamily serifFont) {
50 | this.serifFont = serifFont;
51 | }
52 |
53 | public FontFamily getMonoSpaceFont() {
54 | return monoSpaceFont;
55 | }
56 |
57 | public FontFamily getFont( String name ) {
58 |
59 | if ( name != null && name.length() > 0 ) {
60 |
61 | String[] parts = name.split(",(\\s)*");
62 |
63 | for ( int i = 0; i < parts.length; i++ ) {
64 |
65 | String fontName = parts[i];
66 |
67 | if ( fontName.startsWith("\"") && fontName.endsWith("\"")) {
68 | fontName = fontName.substring(1, fontName.length() -1 );
69 | }
70 |
71 | if ( fontName.startsWith("\'") && fontName.endsWith("\'")) {
72 | fontName = fontName.substring(1, fontName.length() -1 );
73 | }
74 |
75 | FontFamily fam = resolveFont(fontName);
76 | if ( fam != null ) {
77 | return fam;
78 | }
79 | }
80 | }
81 |
82 | return getDefaultFont();
83 | }
84 |
85 | protected FontFamily resolveFont( String name ) {
86 |
87 | Log.d("SystemFontResolver", "Trying to resolve font " + name );
88 |
89 | if ( name.equalsIgnoreCase("serif") ) {
90 | return getSerifFont();
91 | } else if ( name.equalsIgnoreCase("sans-serif") ) {
92 | return getSansSerifFont();
93 | } else if ( name.equalsIgnoreCase("monospace") ) {
94 | return monoSpaceFont;
95 | }
96 |
97 | return null;
98 | }
99 |
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/TagNodeHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner;
17 |
18 | import org.htmlcleaner.TagNode;
19 |
20 | import android.text.SpannableStringBuilder;
21 |
22 | /**
23 | * A TagNodeHandler handles a specific type of tag (a, img, p, etc), and adds
24 | * the correct spans to a SpannableStringBuilder.
25 | *
26 | * For example: the TagNodeHandler for i (italic) tags would do
27 | *
28 | *
29 | * public void handleTagNode( TagNode node, SpannableStringBuilder builder,
30 | * int start, int end ) {
31 | * builder.setSpan(new StyleSpan(Typeface.ITALIC),
32 | * start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
33 | * }
34 | *
35 | *
36 | * @author Alex Kuiper
37 | *
38 | */
39 | public abstract class TagNodeHandler {
40 |
41 | private HtmlSpanner spanner;
42 |
43 | /**
44 | * Called by HtmlSpanner when this TagNodeHandler is registered.
45 | *
46 | * @param spanner
47 | */
48 | public void setSpanner(HtmlSpanner spanner) {
49 | this.spanner = spanner;
50 | }
51 |
52 | /**
53 | * Returns a reference to the HtmlSpanner.
54 | *
55 | * @return the HtmlSpanner;
56 | */
57 | protected HtmlSpanner getSpanner() {
58 | return spanner;
59 | }
60 |
61 | /**
62 | * Called before the children of this node are handled, allowing for text to
63 | * be inserted before the childrens' text.
64 | *
65 | * Default implementation is a no-op.
66 | *
67 | * @param node
68 | * @param builder
69 | */
70 | public void beforeChildren(TagNode node, SpannableStringBuilder builder, SpanStack spanStack) {
71 |
72 | }
73 |
74 | /**
75 | * If this TagNodeHandler takes care of rendering the content.
76 | *
77 | * If true, the parser will not add the content itself.
78 | *
79 | * @return
80 | */
81 | public boolean rendersContent() {
82 | return false;
83 | }
84 |
85 | /**
86 | * Handle the given node and add spans if needed.
87 | *
88 | * @param node
89 | * the node to handle
90 | * @param builder
91 | * the current stringbuilder
92 | * @param start
93 | * start position of inner text of this node
94 | * @param end
95 | * end position of inner text of this node.
96 | *
97 | * @param spanStack stack to push new spans on
98 | */
99 | public abstract void handleTagNode(TagNode node,
100 | SpannableStringBuilder builder, int start, int end, SpanStack spanStack);
101 |
102 |
103 | /**
104 | * Utility method to append newlines while making sure that there are never
105 | * more than 2 consecutive newlines in the text (if whitespace stripping was
106 | * enabled).
107 | *
108 | * @param builder
109 | * @return true if a newline was added
110 | */
111 | protected boolean appendNewLine(SpannableStringBuilder builder) {
112 |
113 | int len = builder.length();
114 |
115 | if (this.spanner.isStripExtraWhiteSpace()) {
116 | // Should never have more than 2 \n characters in a row.
117 | if (len > 2 && builder.charAt(len - 1) == '\n'
118 | && builder.charAt(len - 2) == '\n') {
119 | return false;
120 | }
121 | }
122 |
123 | builder.append("\n");
124 |
125 | return true;
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/TextUtil.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.regex.Matcher;
6 | import java.util.regex.Pattern;
7 |
8 | public class TextUtil {
9 |
10 | private static Pattern SPECIAL_CHAR_WHITESPACE = Pattern
11 | .compile("(&[a-z]*;|?([a-f]|[A-F]|[0-9])*;|[\\s\n]+)");
12 |
13 | private static Pattern SPECIAL_CHAR_NO_WHITESPACE = Pattern
14 | .compile("(&[a-z]*;|?([a-f]|[A-F]|[0-9])*;)");
15 |
16 | private static Map REPLACEMENTS = new HashMap();
17 |
18 | static {
19 |
20 | REPLACEMENTS.put(" ", "\u00A0");
21 | REPLACEMENTS.put("&", "&");
22 | REPLACEMENTS.put(""", "\"");
23 | REPLACEMENTS.put("¢", "¢");
24 | REPLACEMENTS.put("<", "<");
25 | REPLACEMENTS.put(">", ">");
26 | REPLACEMENTS.put("§", "§");
27 |
28 | REPLACEMENTS.put("“", "“");
29 | REPLACEMENTS.put("”", "”");
30 | REPLACEMENTS.put("‘", "‘");
31 | REPLACEMENTS.put("’", "’");
32 |
33 | REPLACEMENTS.put("–", "\u2013");
34 | REPLACEMENTS.put("—", "\u2014");
35 | REPLACEMENTS.put("―", "\u2015");
36 | }
37 |
38 | /**
39 | * Replaces all HTML entities ( <, & ), with their Unicode
40 | * characters.
41 | *
42 | * @param aText
43 | * text to replace entities in
44 | * @return the text with entities replaced.
45 | */
46 | public static String replaceHtmlEntities(String aText,
47 | boolean preserveFormatting) {
48 | StringBuffer result = new StringBuffer();
49 |
50 | Map replacements = new HashMap(
51 | REPLACEMENTS);
52 | Matcher matcher;
53 |
54 | if (preserveFormatting) {
55 | matcher = SPECIAL_CHAR_NO_WHITESPACE.matcher(aText);
56 | } else {
57 | matcher = SPECIAL_CHAR_WHITESPACE.matcher(aText);
58 | replacements.put("", " ");
59 | replacements.put("\n", " ");
60 | }
61 |
62 | while (matcher.find()) {
63 | try {
64 | matcher.appendReplacement(result,
65 | getReplacement(matcher, replacements));
66 | } catch ( ArrayIndexOutOfBoundsException i ) {
67 | //Ignore, seems to be a matcher bug
68 | }
69 | }
70 | matcher.appendTail(result);
71 | return result.toString();
72 | }
73 |
74 | private static String getReplacement(Matcher aMatcher,
75 | Map replacements) {
76 |
77 | String match = aMatcher.group(0).trim();
78 | String result = replacements.get(match);
79 |
80 | if (result != null) {
81 | return result;
82 | } else if ( match.startsWith("")) {
83 |
84 | Integer code;
85 |
86 | // Translate to unicode character.
87 | try {
88 |
89 | //Check if it's hex or normal
90 | if ( match.startsWith("") ) {
91 | code = Integer.decode( "0x" + match.substring(3, match.length() -1));
92 | } else {
93 | code = Integer.parseInt(match.substring(2,
94 | match.length() - 1));
95 | }
96 |
97 | return "" + (char) code.intValue();
98 | } catch (NumberFormatException nfe) {
99 | return "";
100 | }
101 | } else {
102 | return "";
103 | }
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/css/CompiledRule.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner.css;
2 |
3 | import com.sysdata.htmlspanner.HtmlSpanner;
4 | import com.sysdata.htmlspanner.style.Style;
5 | import org.htmlcleaner.TagNode;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | /**
11 | * A Compiled CSS Rule.
12 | *
13 | * A CompiledRule consists of a numbers of matchers which can match TagNodes,
14 | * and StyleUpdaters which can update a Style object if the rule matches.
15 | *
16 | *
17 | */
18 | public class CompiledRule {
19 |
20 | private List> matchers = new ArrayList>();
21 | private List styleUpdaters = new ArrayList();
22 |
23 | private HtmlSpanner spanner;
24 |
25 | private String asText;
26 |
27 | CompiledRule(HtmlSpanner spanner, List> matchers,
28 | List styleUpdaters, String asText ) {
29 |
30 | this.spanner = spanner;
31 | this.matchers = matchers;
32 | this.styleUpdaters = styleUpdaters;
33 | this.asText = asText;
34 | }
35 |
36 | public String toString() {
37 | return asText;
38 | }
39 |
40 | public Style applyStyle( final Style style ) {
41 |
42 | Style result = style;
43 |
44 | for ( CSSCompiler.StyleUpdater updater: styleUpdaters ) {
45 | result = updater.updateStyle(result, spanner);
46 | }
47 |
48 | return result;
49 | }
50 |
51 |
52 |
53 | public boolean matches( TagNode tagNode ) {
54 |
55 | for ( List matcherList: matchers ) {
56 | if ( matchesChain(matcherList, tagNode)) {
57 | return true;
58 | }
59 | }
60 |
61 | return false;
62 | }
63 |
64 | private static boolean matchesChain( List matchers, TagNode tagNode ) {
65 |
66 | TagNode nodeToMatch = tagNode;
67 |
68 | for ( CSSCompiler.TagNodeMatcher matcher: matchers ) {
69 | if ( ! matcher.matches(nodeToMatch) ) {
70 | return false;
71 | }
72 |
73 | nodeToMatch = nodeToMatch.getParent();
74 | }
75 |
76 | return true;
77 | }
78 |
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/exception/ParsingCancelledException.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner.exception;
2 |
3 | /**
4 | Simple RuntimeException which is throws when parsing is cancelled by the user.
5 |
6 | @author Alex Kuiper
7 | */
8 |
9 | public class ParsingCancelledException extends RuntimeException {
10 | }
11 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/FontHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sysdata.htmlspanner.handlers;
18 |
19 | import com.sysdata.htmlspanner.FontFamily;
20 | import com.sysdata.htmlspanner.SpanStack;
21 |
22 | import com.sysdata.htmlspanner.css.CSSCompiler;
23 | import com.sysdata.htmlspanner.style.Style;
24 | import org.htmlcleaner.TagNode;
25 |
26 | import android.text.SpannableStringBuilder;
27 |
28 | /**
29 | * Handler for font-tags
30 | */
31 | public class FontHandler extends StyledTextHandler {
32 |
33 | public FontHandler() {
34 | super(new Style());
35 | }
36 |
37 | @Override
38 | public void handleTagNode(TagNode node, SpannableStringBuilder builder,
39 | int start, int end, Style style, SpanStack spanStack) {
40 |
41 | if ( getSpanner().isAllowStyling() ) {
42 |
43 | String face = node.getAttributeByName("face");
44 | String size = node.getAttributeByName("size");
45 | String color = node.getAttributeByName("color");
46 |
47 | FontFamily family = getSpanner().getFont(face);
48 |
49 | style = style.setFontFamily(family);
50 |
51 | if ( size != null ) {
52 | CSSCompiler.StyleUpdater updater = CSSCompiler.getStyleUpdater("font-size", size);
53 |
54 | if ( updater != null ) {
55 | style = updater.updateStyle(style, getSpanner() );
56 | }
57 | }
58 |
59 | if ( color != null && getSpanner().isUseColoursFromStyle() ) {
60 |
61 | CSSCompiler.StyleUpdater updater = CSSCompiler.getStyleUpdater("color", color);
62 |
63 | if ( updater != null ) {
64 | style = updater.updateStyle(style, getSpanner() );
65 | }
66 | }
67 | }
68 |
69 | super.handleTagNode(node, builder, start, end, style, spanStack);
70 | }
71 |
72 |
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/HeaderHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 | import com.sysdata.htmlspanner.style.Style;
19 | import com.sysdata.htmlspanner.style.StyleValue;
20 |
21 | /**
22 | * Handles Headers, by assigning a relative text-size.
23 | *
24 | * Note that which header is handled (h1, h2, etc) is determined by the tag this
25 | * handler is registered for.
26 | *
27 | * Example:
28 | *
29 | * spanner.registerHandler("h1", new HeaderHandler(1.5f));
30 | * spanner.registerHandler("h2", new HeaderHandler(1.4f));
31 | *
32 | * @author Alex Kuiper
33 | *
34 | */
35 | public class HeaderHandler extends StyledTextHandler {
36 |
37 | private final StyleValue size;
38 | private final StyleValue margin;
39 |
40 | /**
41 | * Creates a HeaderHandler which gives
42 | *
43 | * @param size
44 | */
45 | public HeaderHandler(float size, float margin) {
46 | this.size = new StyleValue(size, StyleValue.Unit.EM);
47 | this.margin = new StyleValue(margin, StyleValue.Unit.EM);
48 | }
49 |
50 | @Override
51 | public Style getStyle() {
52 | return super.getStyle().setFontSize(size)
53 | .setFontWeight(Style.FontWeight.BOLD)
54 | .setDisplayStyle(Style.DisplayStyle.BLOCK)
55 | .setMarginBottom(margin)
56 | .setMarginTop(margin);
57 |
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/ImageHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 | import java.io.IOException;
19 | import java.net.URL;
20 |
21 | import com.sysdata.htmlspanner.SpanStack;
22 | import com.sysdata.htmlspanner.TagNodeHandler;
23 |
24 | import org.htmlcleaner.TagNode;
25 |
26 | import android.graphics.Bitmap;
27 | import android.graphics.BitmapFactory;
28 | import android.graphics.drawable.BitmapDrawable;
29 | import android.graphics.drawable.Drawable;
30 | import android.text.SpannableStringBuilder;
31 | import android.text.style.ImageSpan;
32 | import android.util.Log;
33 |
34 | import rx.Observable;
35 | import rx.Subscriber;
36 | import rx.schedulers.Schedulers;
37 |
38 | /**
39 | * Handles image tags.
40 | *
41 | * The default implementation tries to load images through a URL.openStream(),
42 | * override loadBitmap() to implement your own loading.
43 | *
44 | * @author Alex Kuiper
45 | *
46 | */
47 | public class ImageHandler extends TagNodeHandler {
48 |
49 | private static final String ERRORTAG = "Image error";
50 | private static final long MAXIMUM_TIME=450;
51 |
52 | @Override
53 | public void handleTagNode(TagNode node, final SpannableStringBuilder builder,
54 | final int start, final int end, final SpanStack stack) {
55 | String src = node.getAttributeByName("src");
56 |
57 | builder.append("\uFFFC");
58 |
59 | synchronized (this) {
60 | // we load the image on a different thread
61 | Observable.just(src).observeOn(Schedulers.io()).subscribe(new Subscriber() {
62 | @Override
63 | public void onCompleted() {
64 | // do nothing
65 | }
66 |
67 | @Override
68 | public void onError(Throwable e) {
69 | Log.e(ERRORTAG, "" + e);
70 | }
71 |
72 | @Override
73 | public void onNext(String s) {
74 | Bitmap bitmap = loadBitmap(s);
75 | if (bitmap != null) {
76 | Drawable drawable = new BitmapDrawable(bitmap);
77 | drawable.setBounds(0, 0, bitmap.getWidth() - 1,
78 | bitmap.getHeight() - 1);
79 | stack.pushSpan(new ImageSpan(drawable), start, builder.length());
80 | }
81 | }
82 | });
83 | // we wait until the image is loaded,
84 | // if the image is not loaded until the maximum time we didn't show it
85 | try {
86 | this.wait(MAXIMUM_TIME);
87 | } catch (InterruptedException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | }
92 |
93 | /**
94 | * Loads a Bitmap from the given url.
95 | *
96 | * @param url
97 | * @return a Bitmap, or null if it could not be loaded.
98 | */
99 | protected Bitmap loadBitmap(String url) {
100 | try {
101 | return BitmapFactory.decodeStream(new URL(url).openStream());
102 | } catch (IOException io) {
103 | return null;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/LinkHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 |
19 | import com.sysdata.htmlspanner.SpanStack;
20 | import com.sysdata.htmlspanner.TagNodeHandler;
21 |
22 | import org.htmlcleaner.TagNode;
23 |
24 | import android.text.SpannableStringBuilder;
25 | import android.text.style.URLSpan;
26 |
27 | /**
28 | * Creates clickable links.
29 | *
30 | * @author Alex Kuiper
31 | *
32 | */
33 | public class LinkHandler extends TagNodeHandler {
34 |
35 | @Override
36 | public void handleTagNode(TagNode node, SpannableStringBuilder builder,
37 | int start, int end, SpanStack spanStack) {
38 |
39 | final String href = node.getAttributeByName("href");
40 | spanStack.pushSpan(new URLSpan(href), start, end);
41 | }
42 | }
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/ListItemHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.sysdata.htmlspanner.handlers;
18 |
19 | import com.sysdata.htmlspanner.SpanStack;
20 | import com.sysdata.htmlspanner.TagNodeHandler;
21 | import com.sysdata.htmlspanner.handlers.attributes.WrappingStyleHandler;
22 | import com.sysdata.htmlspanner.spans.ListItemSpan;
23 | import com.sysdata.htmlspanner.style.Style;
24 |
25 | import org.htmlcleaner.TagNode;
26 |
27 | import android.text.SpannableStringBuilder;
28 |
29 | /**
30 | * Handles items in both numbered and unordered lists.
31 | *
32 | * @author Alex Kuiper
33 | *
34 | */
35 | public class ListItemHandler extends WrappingStyleHandler {
36 |
37 | public ListItemHandler(StyledTextHandler wrappedHandler) {
38 | super(wrappedHandler);
39 | }
40 |
41 | private int getMyIndex(TagNode node) {
42 | if (node.getParent() == null) {
43 | return -1;
44 | }
45 |
46 | int i = 1;
47 |
48 | for (Object child : node.getParent().getAllChildren()) {
49 | if (child == node) {
50 | return i;
51 | }
52 |
53 | if (child instanceof TagNode) {
54 | TagNode childNode = (TagNode) child;
55 | if ("li".equals(childNode.getName())) {
56 | i++;
57 | }
58 | }
59 | }
60 |
61 | return -1;
62 | }
63 |
64 | private String getParentName(TagNode node) {
65 | if (node.getParent() == null) {
66 | return null;
67 | }
68 |
69 | return node.getParent().getName();
70 | }
71 |
72 | @Override
73 | public void handleTagNode(TagNode node, SpannableStringBuilder builder, int start, int end, Style useStyle, SpanStack spanStack) {
74 | if (builder.length() > 0
75 | && builder.charAt(builder.length() - 1) != '\n') {
76 | builder.append("\n");
77 | }
78 |
79 | if ("ol".equals(getParentName(node))) {
80 | ListItemSpan bSpan = new ListItemSpan(getMyIndex(node));
81 | spanStack.pushSpan(bSpan, start, end);
82 | } else if ("ul".equals(getParentName(node))) {
83 | // Unicode bullet character.
84 | ListItemSpan bSpan = new ListItemSpan();
85 | spanStack.pushSpan(bSpan, start, end);
86 | }
87 | super.handleTagNode(node, builder, start, end, useStyle, spanStack);
88 | }
89 | }
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/MonoSpaceHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 | import com.sysdata.htmlspanner.style.Style;
19 |
20 | /**
21 | * Sets monotype font.
22 | *
23 | * @author Alex Kuiper
24 | *
25 | */
26 | public class MonoSpaceHandler extends StyledTextHandler {
27 |
28 | @Override
29 | public Style getStyle() {
30 | return new Style().setFontFamily(
31 | getSpanner().getFontResolver().getMonoSpaceFont() );
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/NewLineHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 | import com.sysdata.htmlspanner.SpanStack;
19 | import org.htmlcleaner.TagNode;
20 |
21 | import android.text.SpannableStringBuilder;
22 | import com.sysdata.htmlspanner.TagNodeHandler;
23 |
24 | /**
25 | * Adds a specified number of newlines.
26 | *
27 | * Used to implement p and br tags.
28 | *
29 | * @author Alex Kuiper
30 | *
31 | */
32 | public class NewLineHandler extends WrappingHandler {
33 |
34 | private int numberOfNewLines;
35 |
36 | /**
37 | * Creates this handler for a specified number of newlines.
38 | *
39 | * @param howMany
40 | */
41 | public NewLineHandler(int howMany, TagNodeHandler wrappedHandler) {
42 | super(wrappedHandler);
43 | this.numberOfNewLines = howMany;
44 | }
45 |
46 | public void handleTagNode(TagNode node, SpannableStringBuilder builder,
47 | int start, int end, SpanStack spanStack) {
48 |
49 | super.handleTagNode(node, builder, start, end, spanStack);
50 |
51 | for (int i = 0; i < numberOfNewLines; i++) {
52 | appendNewLine(builder);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/PreHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Alex Kuiper
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.sysdata.htmlspanner.handlers;
17 |
18 | import com.sysdata.htmlspanner.FontFamily;
19 | import com.sysdata.htmlspanner.SpanStack;
20 | import com.sysdata.htmlspanner.TagNodeHandler;
21 | import com.sysdata.htmlspanner.TextUtil;
22 |
23 | import com.sysdata.htmlspanner.spans.FontFamilySpan;
24 | import org.htmlcleaner.ContentNode;
25 | import org.htmlcleaner.TagNode;
26 |
27 | import android.text.SpannableStringBuilder;
28 |
29 | /**
30 | * Handles pre tags, setting the style to monospace and preserving the
31 | * formatting.
32 | *
33 | * @author Alex Kuiper
34 | *
35 | */
36 | public class PreHandler extends TagNodeHandler {
37 |
38 | private void getPlainText(StringBuffer buffer, Object node) {
39 | if (node instanceof ContentNode) {
40 |
41 | ContentNode contentNode = (ContentNode) node;
42 | String text = TextUtil.replaceHtmlEntities(contentNode.getContent()
43 | .toString(), true);
44 |
45 | buffer.append(text);
46 |
47 | } else if (node instanceof TagNode) {
48 | TagNode tagNode = (TagNode) node;
49 | for (Object child : tagNode.getAllChildren()) {
50 | getPlainText(buffer, child);
51 | }
52 | }
53 | }
54 |
55 | @Override
56 | public void handleTagNode(TagNode node, SpannableStringBuilder builder,
57 | int start, int end, SpanStack spanStack) {
58 |
59 | StringBuffer buffer = new StringBuffer();
60 | getPlainText(buffer, node);
61 |
62 | builder.append(buffer.toString());
63 |
64 | FontFamily monoSpace = getSpanner().getFontResolver().getMonoSpaceFont();
65 | spanStack.pushSpan(new FontFamilySpan(monoSpace), start, builder.length());
66 | appendNewLine(builder);
67 | appendNewLine(builder);
68 | }
69 |
70 | @Override
71 | public boolean rendersContent() {
72 | return true;
73 | }
74 |
75 | }
--------------------------------------------------------------------------------
/HtmlSpanner/src/main/java/com/sysdata/htmlspanner/handlers/StyleNodeHandler.java:
--------------------------------------------------------------------------------
1 | package com.sysdata.htmlspanner.handlers;
2 |
3 | import android.text.SpannableStringBuilder;
4 | import android.util.Log;
5 | import com.osbcp.cssparser.CSSParser;
6 | import com.osbcp.cssparser.Rule;
7 | import com.sysdata.htmlspanner.SpanStack;
8 | import com.sysdata.htmlspanner.TagNodeHandler;
9 | import com.sysdata.htmlspanner.css.CSSCompiler;
10 | import org.htmlcleaner.ContentNode;
11 | import org.htmlcleaner.TagNode;
12 |
13 | /**
14 | * TagNodeHandler that reads
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/sysdata/kt/sdhtmltextview/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.sysdata.kt.sdhtmltextview
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.31'
5 | repositories {
6 | google()
7 | jcenter()
8 | maven { url 'https://dl.bintray.com/sysdata/maven' }
9 | mavenCentral()
10 | maven { url 'http://repo.pageturner-reader.org' }
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:3.1.3'
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
16 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
17 |
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | google()
26 | jcenter()
27 | maven { url 'https://dl.bintray.com/sysdata/maven' }
28 | mavenCentral()
29 | maven { url 'http://repo.pageturner-reader.org' }
30 | }
31 | }
32 |
33 | task clean(type: Delete) {
34 | delete rootProject.buildDir
35 | }
36 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jul 16 10:56:15 CEST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/htmltextview/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'com.jfrog.artifactory-upload'
4 | apply plugin: 'com.github.dcendents.android-maven'
5 |
6 | // This is the library version used when deploying the artifact
7 | version = "1.0.2"
8 |
9 | group = "it.sysdata.mobile"
10 |
11 | buildscript {
12 | dependencies {
13 | repositories {
14 | google()
15 | mavenCentral()
16 | // serve per org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1
17 | maven {
18 | url "https://plugins.gradle.org/m2/"
19 | }
20 | }
21 | // artifactory
22 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
23 | classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
24 | // bintray
25 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
26 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
27 | }
28 | }
29 |
30 | repositories {
31 | google()
32 | mavenCentral()
33 | maven {
34 | url "http://repo.pageturner-reader.org"
35 | }
36 | }
37 |
38 | android {
39 | compileSdkVersion 28
40 |
41 | defaultConfig {
42 | minSdkVersion 19
43 | targetSdkVersion 28
44 | versionCode 1
45 | versionName "1.0"
46 |
47 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
48 |
49 | }
50 |
51 | buildTypes {
52 | release {
53 | minifyEnabled false
54 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
55 | }
56 | }
57 |
58 | }
59 |
60 | dependencies {
61 | implementation fileTree(dir: 'libs', include: ['*.jar'])
62 |
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
65 | testImplementation 'junit:junit:4.12'
66 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
67 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
68 | api project(':htmlspanner')
69 | }
70 |
71 | // pubblicazione maven
72 | Properties properties = new Properties()
73 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
74 | ext {
75 | // GROUP_ID
76 | publishedGroupId = group
77 | // ARTIFACT_ID
78 | artifact = 'htmltextview'
79 | // VERSION_ID
80 | libraryVersion = version
81 |
82 | developerId = 'sysdata-mobile'
83 | developerName = ''
84 | developerEmail = 'team.mobile@sysdata.it'
85 |
86 | bintrayRepo = 'maven'
87 | bintrayName = 'sdHtmlTextView'
88 | libraryName = 'htmltextview'
89 | bintrayOrganization = 'sysdata-mobile'
90 | }
91 |
92 | //apply from: 'publishArtifactory.gradle'
93 | apply from: 'publishBintray.gradle'
94 |
--------------------------------------------------------------------------------
/htmltextview/pom.xml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/htmltextview/pom.xml
--------------------------------------------------------------------------------
/htmltextview/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/htmltextview/publishBintray.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:3.1.3'
8 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
9 | classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1'
10 | }
11 | }
12 |
13 | apply plugin: 'com.android.library'
14 |
15 | ext {
16 | libraryDescription = ''
17 | siteUrl = 'https://github.com/SysdataSpA/SDHtmlTextView'
18 | gitUrl = 'https://github.com/SysdataSpA/SDHtmlTextView.git'
19 |
20 | licenseName = 'The Apache Software License, Version 2.0'
21 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
22 | allLicenses = ["Apache-2.0"]
23 | }
24 |
25 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
26 | apply plugin: 'com.github.dcendents.android-maven'
27 |
28 | group = publishedGroupId // Maven Group ID for the artifact
29 |
30 | install {
31 | repositories.mavenInstaller {
32 | // This generates POM.xml with proper parameters
33 | pom {
34 | project {
35 | packaging 'aar'
36 | groupId publishedGroupId
37 | artifactId artifact
38 |
39 | // Add your description here
40 | name libraryName
41 | description libraryDescription
42 | url siteUrl
43 |
44 | // Set your license
45 | licenses {
46 | license {
47 | name licenseName
48 | url licenseUrl
49 | }
50 | }
51 | developers {
52 | developer {
53 | id developerId
54 | name developerName
55 | email developerEmail
56 | }
57 | }
58 | scm {
59 | connection gitUrl
60 | developerConnection gitUrl
61 | url siteUrl
62 |
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
69 | //apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
70 | apply plugin: 'com.jfrog.bintray'
71 | apply plugin: 'maven'
72 |
73 | version = libraryVersion
74 |
75 | task sourcesJar(type: Jar) {
76 | dependsOn = ['test', 'connectedAndroidTest']
77 | from android.sourceSets.main.java.srcDirs
78 | classifier = 'sources'
79 | }
80 |
81 | task writeNewPom {
82 | pom {
83 | project {
84 | packaging 'aar'
85 | name 'sdHtmlTextView'
86 | url siteUrl
87 | licenses {
88 | license {
89 | name 'The Apache Software License, Version 2.0'
90 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
91 | distribution 'repo'
92 | }
93 | }
94 | }
95 | }.writeTo("$buildDir/poms/pom-default.xml")
96 | }
97 |
98 | artifacts {
99 | archives sourcesJar
100 | }
101 |
102 | // Bintray
103 | Properties properties = new Properties()
104 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
105 |
106 | bintray {
107 | user = properties.getProperty("bintray.user")
108 | key = properties.getProperty("bintray.apikey")
109 |
110 | configurations = ['archives']
111 | pkg {
112 | repo = bintrayRepo
113 | name = bintrayName
114 | desc = libraryDescription
115 | userOrg = bintrayOrganization
116 | websiteUrl = siteUrl
117 | vcsUrl = gitUrl
118 | licenses = allLicenses
119 | publish = true
120 | publicDownloadNumbers = true
121 | version {
122 | desc = libraryDescription
123 | gpg {
124 | sign = true //Determines whether to GPG sign the files. The default is false
125 | passphrase = properties.getProperty("bintray.gpg.password")
126 | //Optional. The passphrase for GPG signing'
127 | }
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/htmltextview/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/htmltextview/src/main/java/com/sysdata/kt/htmltextview/SDHtmlTextView.kt:
--------------------------------------------------------------------------------
1 | package com.sysdata.kt.htmltextview
2 |
3 | import android.content.Context
4 | import android.text.method.LinkMovementMethod
5 | import android.util.AttributeSet
6 | import android.widget.TextView
7 | import com.sysdata.htmlspanner.HtmlSpanner
8 |
9 | class SDHtmlTextView: TextView {
10 |
11 | constructor(context: Context?):this(context, null)
12 |
13 | constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)
14 |
15 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr){
16 | if(attrs != null) {
17 | context?.let { ctx ->
18 | val a = ctx.theme.obtainStyledAttributes(
19 | attrs,
20 | R.styleable.SDHtmlTextView,
21 | defStyleAttr, 0)
22 |
23 | isTableHeaderCentered = a.getBoolean(R.styleable.SDHtmlTextView_tableHeaderCentered, true)
24 |
25 | a.recycle()
26 | }
27 | }
28 | this.movementMethod = LinkMovementMethod.getInstance()
29 |
30 | htmlSpanner = HtmlSpanner.Builder()
31 | .textColor(textColors.defaultColor)
32 | .textSize(textSize)
33 | .backgroundColor(solidColor)
34 | .tableHeaderCenter(isTableHeaderCentered)
35 | .build()
36 | }
37 |
38 | private var htmlSpanner: HtmlSpanner
39 | public var isTableHeaderCentered: Boolean = true
40 |
41 | var htmlText:String? = null
42 | set(value) {
43 | text = htmlSpanner.fromHtml(value)
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/htmltextview/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | htmlTextView
3 |
4 |
--------------------------------------------------------------------------------
/htmltextview/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/release/htmlspanner-release-1.0.3.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/release/htmlspanner-release-1.0.3.aar
--------------------------------------------------------------------------------
/release/htmltextview-release-1.0.3.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SysdataSpA/SDHtmlTextView/f00b246a8e746bee77b5db0836461af1498f62c2/release/htmltextview-release-1.0.3.aar
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':htmltextview', ':htmlspanner'
2 |
--------------------------------------------------------------------------------