Compare commits
79 Commits
param-name
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55abbec0ba | ||
|
|
94c82398ad | ||
|
|
38c08d4724 | ||
|
|
1c164a0773 | ||
|
|
dcc7258c8e | ||
|
|
930ade9354 | ||
|
|
d1c404d5db | ||
|
|
c2177d0584 | ||
|
|
5eb202b0a9 | ||
|
|
4bda3635ab | ||
|
|
f083b2cc9c | ||
|
|
9ad0e428c1 | ||
|
|
83866be83f | ||
|
|
5135cffc3f | ||
|
|
09e08f3465 | ||
|
|
26ba4c3cae | ||
|
|
dc676b767f | ||
|
|
07dcbb3ec2 | ||
|
|
b18459c66f | ||
|
|
aa8fb7c763 | ||
|
|
c4f2429ec1 | ||
|
|
a5aaeff22f | ||
|
|
f4a179160c | ||
|
|
787035f6b1 | ||
|
|
8b08968a6b | ||
|
|
56f61e421f | ||
|
|
afd00597f7 | ||
|
|
8cc0b7c2c7 | ||
|
|
89f0194be0 | ||
|
|
1079a01750 | ||
|
|
f89957eeab | ||
|
|
c07facd490 | ||
|
|
1d43a25457 | ||
|
|
2ecd734239 | ||
|
|
8b2669cab1 | ||
|
|
8c0d03e200 | ||
|
|
15702ac0d7 | ||
|
|
fd41cccfe2 | ||
|
|
31a565235e | ||
|
|
da76ee0d2b | ||
|
|
4a4c6314d8 | ||
|
|
be626b6b96 | ||
|
|
226cfb9a28 | ||
|
|
acf6bff72a | ||
|
|
07427c1433 | ||
|
|
7d98d4f2bd | ||
|
|
94ad6e29a3 | ||
|
|
9338efc7cd | ||
|
|
312cabe69c | ||
|
|
f091000bbe | ||
|
|
2ae40f9e6c | ||
|
|
dd2079a136 | ||
|
|
b0cf8e8c6f | ||
|
|
793dcca03c | ||
|
|
379ddb82bf | ||
|
|
8316035854 | ||
|
|
1fcecb961e | ||
|
|
5c9d62cdf3 | ||
|
|
c31badd3e4 | ||
|
|
629038303c | ||
|
|
0f30bc9d9a | ||
|
|
ae65127dcc | ||
|
|
dae578a523 | ||
|
|
b89435ca7c | ||
|
|
3deb6b4ddb | ||
|
|
023922a7db | ||
|
|
00c0461669 | ||
|
|
cd6e0084ef | ||
|
|
764b5d7759 | ||
|
|
d9c4963ff0 | ||
|
|
3ec15d28a5 | ||
|
|
f1680464d1 | ||
|
|
f497b5c8b5 | ||
|
|
f212895eb2 | ||
|
|
62cafb9b31 | ||
|
|
af7c986dd6 | ||
|
|
3aaab8b0fe | ||
|
|
cf9558b6ab | ||
|
|
f87f9d8647 |
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
text eol=crlf
|
||||
28
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Test all JDKs on all OSes
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
java_version: [1.8, 11, 17]
|
||||
os: [windows-latest, macOS-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Set up JDK ${{ matrix.java_version }}
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java_version }}
|
||||
- name: Make Maven Wrapper executable
|
||||
if: contains(matrix.os, 'win') == false
|
||||
run: chmod +x ./mvnw
|
||||
- name: Build with Maven
|
||||
run: ./mvnw verify --file pom.xml --batch-mode
|
||||
env:
|
||||
MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
94
.gitignore
vendored
@@ -1,101 +1,15 @@
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
### Eclipse ###
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
buildNumber.properties
|
||||
|
||||
### IntelliJ ###
|
||||
*.iml
|
||||
.idea/
|
||||
|
||||
117
.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2007-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
private static final String WRAPPER_VERSION = "0.5.6";
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
|
||||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if(mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if(mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if(!outputFile.getParentFile().exists()) {
|
||||
if(!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
|
||||
String username = System.getenv("MVNW_USERNAME");
|
||||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
||||
2
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
||||
@@ -1,8 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- oracle-java8-installer
|
||||
153
CONTRIBUTING.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Contributing
|
||||
|
||||
This Project is currently accepting Contributions.
|
||||
Have a look at the Issues for Inspiration.
|
||||
|
||||
## Requirements
|
||||
|
||||
- JDK >= 1.8 (see pom.xml)
|
||||
- Maven
|
||||
|
||||
## Project Goals
|
||||
|
||||
As stated in the **README**, the Goal of this Project is to enjoy typesafe, performant HTML generation in Java.
|
||||
|
||||
For preventing performance regressions, there are Tests.
|
||||
|
||||
## Coding Style
|
||||
|
||||
There is a `.editorconfig` and a `eclipse_formatting_profile.xml`
|
||||
|
||||
What sticks out is that end of line is CRLF `'\r\n'` for this Project.
|
||||
|
||||
This means that if you're on Linux `'\n'`, you have to configure git to handle this
|
||||
correctly so that you have the correct EOL in your working directory,
|
||||
and the EOL is also correct in the repository itself.
|
||||
|
||||
For this purpose, j2html has a `.gitattributes` file.
|
||||
|
||||
[Guide to configuring EOL with git](https://docs.github.com/en/github/using-git/configuring-git-to-handle-line-endings)
|
||||
|
||||
If you are on Windows, there should be no Problems.
|
||||
|
||||
### Reformatting of generated Java Code
|
||||
|
||||
As this Projects makes use of Code-Generation techniques in order to generate a more typesafe API without too much manual Work,
|
||||
there is the `j2html-codegen/` directory which contains everything needed to generate the code.
|
||||
|
||||
For simplicity (and also to avoid extra dependencies), they do not format the code correctly.
|
||||
|
||||
So if you change the Code-Generation Code, you may need to reformat the generated files to fit the Coding Style.
|
||||
|
||||
## Contribution Workflow
|
||||
|
||||
The workflow (most of the time) consists of:
|
||||
|
||||
- Comment (on Issue or PR) to find out what needs Work
|
||||
- Get Feedback on your Ideas
|
||||
- Fork this repo
|
||||
- Open a PR
|
||||
- Adjust the PR until it is merged or discarded
|
||||
|
||||
## Project Architecture
|
||||
|
||||
### j2html/src/main/java/j2html/TagCreator.java
|
||||
|
||||
This is **the** central class in J2HTML. It provides the methods
|
||||
for users of J2HTML to generate all HTML Tags.
|
||||
It contains methods like
|
||||
```
|
||||
public static HtmlTag html(DomContent... dc) {
|
||||
return new HtmlTag().with(dc);
|
||||
}
|
||||
```
|
||||
which can be used in Projects using this dependency as
|
||||
```
|
||||
html(
|
||||
head(
|
||||
script("https://example.com/my/js/files.js")
|
||||
),
|
||||
body(
|
||||
div(
|
||||
h1("Hello World")
|
||||
).withClasses("container")
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### How are the different HTML Tags implemented?
|
||||
|
||||
Each HTML Tag has it's own class, which makes it possible for each Tag to have
|
||||
the correct Attributes and Methods to set those Attributes.
|
||||
|
||||
The classes are located in `j2html/src/main/java/j2html/tags/specialized` and follow the naming convention `tag_name + 'Tag.java'`, e.g. `BodyTag.java`.
|
||||
Notice that the first letter of the Tag is in uppercase.
|
||||
|
||||
Each Tag-specific class `implements` interfaces which correspond to the Attributes that can be set on these Tags.
|
||||
|
||||
For Reference which Tags support which Attributes, see [HTML Attribute Reference](https://www.w3schools.com/tags/ref_attributes.asp).
|
||||
|
||||
For Example, `ButtonTag` might implement `IType<ButtonTag>` which says it can have an Attribute `type`, which may later show up like `<button type="submit"></button>`.
|
||||
|
||||
### How are the Attributes of HTML Tags implemented?
|
||||
|
||||
Each Attribute has it's own interface in `src/main/java/j2html/tags/attributes/` and follows the naming convention `"I" + attribute_name + '.java'`, e.g. `IAccept.java`. Notice that the first letter of the Attribute is in uppercase.
|
||||
|
||||
Dissecting `IAccept.java`:
|
||||
|
||||
```
|
||||
public interface IAccept<T extends Tag> extends IInstance<T> {
|
||||
default T withAccept(final String accept_) {
|
||||
return self().attr("accept", accept_);
|
||||
}
|
||||
|
||||
default T withCondAccept(final boolean enable, final String accept_) {
|
||||
if (enable) {
|
||||
self().attr("accept", accept_);
|
||||
}
|
||||
return self();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, **IAccept** extends `IInstance<T>` which provides only the `self()` Method to access an instance of type `T`.
|
||||
All attribute-specific interfaces extend `IInstance<T>`.
|
||||
|
||||
```
|
||||
public interface IInstance<T> {
|
||||
default T self() { return (T) this; }
|
||||
}
|
||||
```
|
||||
|
||||
`IInstance<T>` is cheating the type system because `self()` returns an instance of type `T`, but the implementing class
|
||||
technically does not have to supply it's own type as the type argument. But by convention, in this Project, the implementing class
|
||||
always supplies it's own type as the type argument.
|
||||
|
||||
But in `default` methods in interfaces there is AFAIK no way to obtain the type of the class that is implementing the interface.
|
||||
If you find a way, that would be a great PR.
|
||||
|
||||
### Special classes/interfaces besides TagCreator.java
|
||||
|
||||
There are 3 classes which contain code-generating methods in `j2html-codegen/src/main/java/j2html_codegen/generators/`:
|
||||
|
||||
- `AttributeInterfaceCodeGenerator.java` (generating the interfaces for the attributes)
|
||||
- `SpecializedTagClassCodeGenerator.java` (generating the classes for the tags)
|
||||
- `TagCreatorCodeGenerator.java` (generating some contents of `TagCreator.java`)
|
||||
|
||||
### Other special classes / interfaces in J2HTML
|
||||
|
||||
- **Tag.java** is the base class for every tag and extends DomContent
|
||||
- **EmptyTag.java** is the base class for all Tags which have no contents
|
||||
- **ContainerTag.java** is the base class for all Tags which can contain other tags
|
||||
- **DomContent.java**
|
||||
|
||||
### How is the Code generation for the Attribute specific Interfaces parameterized?
|
||||
|
||||
Attributes differ in their 'type' . Some of them can be set with numbers (which are converted into strings in the html).
|
||||
Others can only be set or not set, others still have 3 states: set, unset, and not present.
|
||||
To model these propertise, a single Attribute can be described by an instance of **AttrD.java**.
|
||||
|
||||
`j2html/src/main/java/j2html/tags/generators/AttributesList.java` contains the different Attributes, their properties,
|
||||
and the Tags they can be set on. It is the starting point for adding new Attributes and customizing their properties.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||

|
||||
[](https://github.com/tipsy/j2html/actions)
|
||||

|
||||

|
||||
|
||||
@@ -13,12 +13,12 @@ The project webpage is [j2html.com](http://j2html.com).
|
||||
<dependency>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html</artifactId>
|
||||
<version>1.2.2</version>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### Or the gradle dependency
|
||||
```
|
||||
compile 'com.j2html:j2html:1.2.2'
|
||||
compile 'com.j2html:j2html:1.6.0'
|
||||
```
|
||||
|
||||
### Import TagCreator and start building HTML
|
||||
|
||||
19
docs/404.html
Normal file
1
docs/CNAME
Normal file
@@ -0,0 +1 @@
|
||||
j2html.com
|
||||
3
docs/README
Normal file
@@ -0,0 +1,3 @@
|
||||
# j2html.com
|
||||
|
||||
Don't edit these files manually, they are generated from `j2html/website`.
|
||||
121
docs/css/prism.css
Normal file
@@ -0,0 +1,121 @@
|
||||
/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+java */
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #f8f8f2;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #272822;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
24
docs/download.html
Normal file
5
docs/download_html.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
curl "http://localhost:8888/" > index.html
|
||||
curl "http://localhost:8888/download.html" > download.html
|
||||
curl "http://localhost:8888/examples.html" > examples.html
|
||||
curl "http://localhost:8888/news.html" > news.html
|
||||
curl "http://localhost:8888/404.html" > 404.html
|
||||
426
docs/examples.html
Normal file
32
docs/img/favicon.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="512px" height="512px" viewBox="0 0 512 512" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Created with Lunacy</desc>
|
||||
<defs>
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="path_1" />
|
||||
<rect width="512" height="512" id="artboard_1" />
|
||||
<clipPath id="clip_1">
|
||||
<use xlink:href="#artboard_1" clip-rule="evenodd" />
|
||||
</clipPath>
|
||||
<clipPath id="mask_1">
|
||||
<use xlink:href="#path_1" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="Artboard-Copy-3" clip-path="url(#clip_1)">
|
||||
<g id="HTML5_Badge">
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="Background" fill="none" stroke="none" />
|
||||
<g clip-path="url(#mask_1)">
|
||||
<path d="M41 460L0 0L451 0L410 460L225 512" transform="translate(30 0)" id="Shape" fill="#1272BF" stroke="none" />
|
||||
<path d="M0 435L149 394L184 0L0 0" transform="translate(256 37)" id="Shape" fill="#FFFFFF" fill-opacity="0.21176471" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="coffee-icon-12" transform="translate(122.26813 68.45154)">
|
||||
<g id="Group">
|
||||
<path d="M109.76 63.5233C72.71 61.7926 37.5831 55.1903 18.2249 46.4086C5.14845 40.4472 -1.64617 32.627 0.340938 25.8965C3.22545 16.2815 18.7377 7.94844 45.8521 1.41021L51.7493 0L56.2363 4.23062C58.7362 6.53823 61.8771 9.16634 63.2232 10.1278C64.6975 11.0893 65.9154 12.4355 66.1718 13.4611C66.3641 14.4226 67.582 16.7302 68.864 18.5891C74.1202 26.2811 84.5686 31.1527 101.812 33.8449C112.452 35.5756 153.028 35.5756 164.117 33.909C181.424 31.2809 192.193 26.3452 197.449 18.5891C198.731 16.7302 199.949 14.4226 200.141 13.4611C200.398 12.4996 201.551 11.0893 202.897 10.1919C204.244 9.35865 207.384 6.66643 209.884 4.35882L214.564 1.95618e-05L220.461 1.41023C251.742 8.78175 269.177 19.9993 265.972 30.7681C264.818 34.55 261.677 38.2678 256.87 41.4728C233.025 57.3056 171.937 66.4719 109.76 63.5233L109.76 63.5233Z" transform="translate(0 276.47668)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M83.9789 173.473C64.877 172.256 51.8006 168.217 47.9546 162.32C47.3777 161.423 46.7367 159.435 46.6084 157.897C46.2879 155.397 45.9033 154.82 43.2752 152.961C38.5959 149.564 29.8142 140.334 25.0708 133.731C20.0069 126.68 12.1225 111.04 9.30215 102.45C3.14853 83.9255 0.199922 64.5031 0.00761933 41.8116C-0.0564799 29.1198 0.199922 27.8378 4.11003 22.838C6.73814 19.633 14.1738 14.6332 20.5197 12.0051C54.3005 -2.09699 127.952 -4.14819 171.732 7.83854C187.565 12.1974 198.334 18.6074 202.436 26.1712C204.038 29.0557 204.359 30.4659 204.615 35.8503L204.622 35.9837C204.936 41.9426 204.946 42.1293 206.282 41.7475C206.987 41.4911 210.833 41.2988 214.679 41.2988C225.384 41.3629 232.371 43.991 238.012 50.1447C250.96 64.2467 246.729 91.297 228.525 110.271C217.371 121.873 203.333 129.116 186.924 131.744L180.193 132.834L177.95 135.718C172.822 142.128 167.373 147.769 162.886 151.423C158.591 154.884 158.079 155.525 157.822 157.961C157.374 161.358 156.092 163.41 152.694 165.846C143.72 172.32 115.452 175.461 83.9789 173.473ZM179.103 35.2734C179.103 41.1706 159.104 46.9396 130.708 49.119C121.285 49.8241 97.4399 50.401 89.6838 50.0805C57.2491 48.6703 33.0833 44.1192 26.7374 38.1579C23.5965 35.2093 25.4554 31.9402 32.0577 28.9274C40.2625 25.1455 55.0056 22.0687 74.2997 20.2098C85.1967 19.1842 119.362 19.1842 130.067 20.2739C160.322 23.2225 179.103 28.9915 179.103 35.2734ZM48.5956 75.2078C49.9416 100.591 56.0312 124.565 65.3898 141.295C66.6077 143.539 67.5051 145.333 67.3128 145.333C66.159 145.333 50.9673 133.09 47.6981 129.501C36.737 117.514 28.8527 101.168 24.3657 81.2332C22.9555 74.695 20.5838 59.4391 20.9684 58.9904C21.0966 58.9263 23.8529 59.8878 27.1861 61.1698C30.5193 62.3877 36.4165 64.1185 40.3266 65.0159C44.1726 65.9133 47.5058 66.6824 47.7622 66.8107C47.9545 67.003 48.3391 70.7208 48.5956 75.2078ZM201.731 105.399C221.41 95.2071 231.089 77.4513 222.884 66.5543C220.256 63.0929 216.474 61.8109 210.064 62.1314C207.115 62.2596 204.423 62.7083 204.039 63.0929C203.654 63.4775 202.757 67.5158 202.116 72.0669C200.577 82.7075 198.205 92.9636 195.129 102.13C194.955 102.641 194.789 103.12 194.634 103.57C193.539 106.749 192.961 108.429 193.474 108.889C194.05 109.405 196 108.388 200.133 106.231C200.633 105.97 201.165 105.693 201.731 105.399Z" transform="translate(30.973198 125.50244)" id="Shape" fill="#FFFFFF" fill-rule="evenodd" stroke="none" />
|
||||
<path d="M1.14148 89.3819C4.64379 86.2444 7.12459 81.9395 8.43796 76.759C9.75133 71.5055 9.6054 66.5439 7.63534 50.4917C4.93565 29.113 10.335 17.4386 27.7007 6.93166C32.2975 4.23196 34.0486 3.28342 39.375 1.09447L41.9288 0L38.6454 2.77266C32.8812 7.66131 29.8896 11.3095 27.3358 16.563C23.5417 24.2243 22.885 30.2074 24.3443 43.633C25.7306 56.7666 25.8036 61.2175 24.4902 66.6169C22.4472 75.2997 15.5885 82.961 5.00862 88.3604C-0.536715 91.1331 -0.901539 91.206 1.14148 89.3819L1.14148 89.3819Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 109.50348 7.280884)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.2619 64.5395C7.44241 59.1401 8.53688 53.3759 6.63979 41.6286C4.15899 25.8682 5.54532 19.1554 12.9148 12.0048C16.0523 8.86735 19.1168 6.82434 24.6621 4.1976C34.2935 -0.472146 36.8472 -1.20179 32.6882 1.78976C27.9455 5.29208 24.5891 8.94032 22.4002 13.0993C20.5031 16.7476 20.4301 17.1853 20.722 26.3789C21.3057 46.7361 21.2328 49.5817 19.8464 52.1355C16.8549 57.6808 9.77728 63.2991 2.18894 66.1447L0 66.9473L2.26191 64.5395L2.2619 64.5395Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 67.97293 38.71814)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.43573 63.7984C7.25141 58.326 7.98106 53.5833 5.86508 40.8875C3.01946 23.5948 6.30288 14.7661 18.1961 7.32363C22.72 4.55097 33.2269 -0.410636 33.7376 0.0271519C33.8836 0.173082 32.2054 1.70534 30.0164 3.38353C25.2737 7.10474 22.2092 11.3367 20.458 16.5902C19.5095 19.6547 19.3635 21.7707 19.7284 27.0971C21.1877 47.3813 21.1877 47.4543 19.4365 51.4674C17.3935 56.356 12.3589 61.0257 5.64618 64.3821C2.80055 65.8414 0.319755 67.0089 0.0278784 67.0089C-0.191007 67.0089 0.903465 65.5496 2.43571 63.7984L2.43573 63.7984Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 160.54498 22.258545)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
33
docs/img/logo.svg
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="1720px" height="512px" viewBox="0 0 1720 512" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Created with Lunacy</desc>
|
||||
<defs>
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="path_1" />
|
||||
<rect width="1720" height="512" id="artboard_1" />
|
||||
<clipPath id="clip_1">
|
||||
<use xlink:href="#artboard_1" clip-rule="evenodd" />
|
||||
</clipPath>
|
||||
<clipPath id="mask_1">
|
||||
<use xlink:href="#path_1" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="Artboard-Copy-2" clip-path="url(#clip_1)">
|
||||
<g id="HTML5_Badge">
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="Background" fill="none" stroke="none" />
|
||||
<g clip-path="url(#mask_1)">
|
||||
<path d="M41 460L0 0L451 0L410 460L225 512" transform="translate(30 0)" id="Shape" fill="#1272BF" stroke="none" />
|
||||
<path d="M0 435L149 394L184 0L0 0" transform="translate(256 37)" id="Shape" fill="#FFFFFF" fill-opacity="0.21176471" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="coffee-icon-12" transform="translate(122.26813 68.45154)">
|
||||
<g id="Group">
|
||||
<path d="M109.76 63.5233C72.71 61.7926 37.5831 55.1903 18.2249 46.4086C5.14845 40.4472 -1.64617 32.627 0.340938 25.8965C3.22545 16.2815 18.7377 7.94844 45.8521 1.41021L51.7493 0L56.2363 4.23062C58.7362 6.53823 61.8771 9.16634 63.2232 10.1278C64.6975 11.0893 65.9154 12.4355 66.1718 13.4611C66.3641 14.4226 67.582 16.7302 68.864 18.5891C74.1202 26.2811 84.5686 31.1527 101.812 33.8449C112.452 35.5756 153.028 35.5756 164.117 33.909C181.424 31.2809 192.193 26.3452 197.449 18.5891C198.731 16.7302 199.949 14.4226 200.141 13.4611C200.398 12.4996 201.551 11.0893 202.897 10.1919C204.244 9.35865 207.384 6.66643 209.884 4.35882L214.564 1.95618e-05L220.461 1.41023C251.742 8.78175 269.177 19.9993 265.972 30.7681C264.818 34.55 261.677 38.2678 256.87 41.4728C233.025 57.3056 171.937 66.4719 109.76 63.5233L109.76 63.5233Z" transform="translate(0 276.47668)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M83.9789 173.473C64.877 172.256 51.8006 168.217 47.9546 162.32C47.3777 161.423 46.7367 159.435 46.6084 157.897C46.2879 155.397 45.9033 154.82 43.2752 152.961C38.5959 149.564 29.8142 140.334 25.0708 133.731C20.0069 126.68 12.1225 111.04 9.30215 102.45C3.14853 83.9255 0.199922 64.5031 0.00761933 41.8116C-0.0564799 29.1198 0.199922 27.8378 4.11003 22.838C6.73814 19.633 14.1738 14.6332 20.5197 12.0051C54.3005 -2.09699 127.952 -4.14819 171.732 7.83854C187.565 12.1974 198.334 18.6074 202.436 26.1712C204.038 29.0557 204.359 30.4659 204.615 35.8503L204.622 35.9837C204.936 41.9426 204.946 42.1293 206.282 41.7475C206.987 41.4911 210.833 41.2988 214.679 41.2988C225.384 41.3629 232.371 43.991 238.012 50.1447C250.96 64.2467 246.729 91.297 228.525 110.271C217.371 121.873 203.333 129.116 186.924 131.744L180.193 132.834L177.95 135.718C172.822 142.128 167.373 147.769 162.886 151.423C158.591 154.884 158.079 155.525 157.822 157.961C157.374 161.358 156.092 163.41 152.694 165.846C143.72 172.32 115.452 175.461 83.9789 173.473ZM179.103 35.2734C179.103 41.1706 159.104 46.9396 130.708 49.119C121.285 49.8241 97.4399 50.401 89.6838 50.0805C57.2491 48.6703 33.0833 44.1192 26.7374 38.1579C23.5965 35.2093 25.4554 31.9402 32.0577 28.9274C40.2625 25.1455 55.0056 22.0687 74.2997 20.2098C85.1967 19.1842 119.362 19.1842 130.067 20.2739C160.322 23.2225 179.103 28.9915 179.103 35.2734ZM48.5956 75.2078C49.9416 100.591 56.0312 124.565 65.3898 141.295C66.6077 143.539 67.5051 145.333 67.3128 145.333C66.159 145.333 50.9673 133.09 47.6981 129.501C36.737 117.514 28.8527 101.168 24.3657 81.2332C22.9555 74.695 20.5838 59.4391 20.9684 58.9904C21.0966 58.9263 23.8529 59.8878 27.1861 61.1698C30.5193 62.3877 36.4165 64.1185 40.3266 65.0159C44.1726 65.9133 47.5058 66.6824 47.7622 66.8107C47.9545 67.003 48.3391 70.7208 48.5956 75.2078ZM201.731 105.399C221.41 95.2071 231.089 77.4513 222.884 66.5543C220.256 63.0929 216.474 61.8109 210.064 62.1314C207.115 62.2596 204.423 62.7083 204.039 63.0929C203.654 63.4775 202.757 67.5158 202.116 72.0669C200.577 82.7075 198.205 92.9636 195.129 102.13C194.955 102.641 194.789 103.12 194.634 103.57C193.539 106.749 192.961 108.429 193.474 108.889C194.05 109.405 196 108.388 200.133 106.231C200.633 105.97 201.165 105.693 201.731 105.399Z" transform="translate(30.973198 125.50244)" id="Shape" fill="#FFFFFF" fill-rule="evenodd" stroke="none" />
|
||||
<path d="M1.14148 89.3819C4.64379 86.2444 7.12459 81.9395 8.43796 76.759C9.75133 71.5055 9.6054 66.5439 7.63534 50.4917C4.93565 29.113 10.335 17.4386 27.7007 6.93166C32.2975 4.23196 34.0486 3.28342 39.375 1.09447L41.9288 0L38.6454 2.77266C32.8812 7.66131 29.8896 11.3095 27.3358 16.563C23.5417 24.2243 22.885 30.2074 24.3443 43.633C25.7306 56.7666 25.8036 61.2175 24.4902 66.6169C22.4472 75.2997 15.5885 82.961 5.00862 88.3604C-0.536715 91.1331 -0.901539 91.206 1.14148 89.3819L1.14148 89.3819Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 109.50348 7.280884)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.2619 64.5395C7.44241 59.1401 8.53688 53.3759 6.63979 41.6286C4.15899 25.8682 5.54532 19.1554 12.9148 12.0048C16.0523 8.86735 19.1168 6.82434 24.6621 4.1976C34.2935 -0.472146 36.8472 -1.20179 32.6882 1.78976C27.9455 5.29208 24.5891 8.94032 22.4002 13.0993C20.5031 16.7476 20.4301 17.1853 20.722 26.3789C21.3057 46.7361 21.2328 49.5817 19.8464 52.1355C16.8549 57.6808 9.77728 63.2991 2.18894 66.1447L0 66.9473L2.26191 64.5395L2.2619 64.5395Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 67.97293 38.71814)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.43573 63.7984C7.25141 58.326 7.98106 53.5833 5.86508 40.8875C3.01946 23.5948 6.30288 14.7661 18.1961 7.32363C22.72 4.55097 33.2269 -0.410636 33.7376 0.0271519C33.8836 0.173082 32.2054 1.70534 30.0164 3.38353C25.2737 7.10474 22.2092 11.3367 20.458 16.5902C19.5095 19.6547 19.3635 21.7707 19.7284 27.0971C21.1877 47.3813 21.1877 47.4543 19.4365 51.4674C17.3935 56.356 12.3589 61.0257 5.64618 64.3821C2.80055 65.8414 0.319755 67.0089 0.0278784 67.0089C-0.191007 67.0089 0.903465 65.5496 2.43571 63.7984L2.43573 63.7984Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 160.54498 22.258545)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<path d="M364 10.8L376.4 0L438 0L422.8 125.2C428.667 115.067 436.267 106.867 445.6 100.6C454.933 94.3334 465.867 91.2 478.4 91.2Q502.8 91.2 519 106.4C529.8 116.533 533.867 132.267 531.2 153.6L521.2 236L544.4 236L540.8 265.2L528.8 275.2L467.2 275.2L479.6 173.6C481.733 158.133 480.667 147.067 476.4 140.4C472.133 133.733 465.067 130.4 455.2 130.4C443.733 130.4 435.067 134 429.2 141.2Q420.4 152 417.2 169.6L404.4 275.2L354.8 275.2L383.6 39.2L360.4 39.2L364 10.8ZM1052 0L1039.6 10.8L1036 39.2L1060.8 39.2L1032 275.2L1094 275.2L1106 265.2L1109.6 236L1086.4 236L1115.2 0L1052 0ZM79.2 62.8L82.0851 35.1857Q82.1542 34.5246 82.2534 33.8673Q82.3527 33.2101 82.482 32.5581Q82.6113 31.9061 82.7704 31.2607Q82.9294 30.6154 83.1178 29.9779Q83.3063 29.3405 83.5237 28.7124Q83.7411 28.0843 83.9872 27.4668Q84.2331 26.8493 84.5072 26.2437Q84.7812 25.6381 85.0827 25.0458Q85.3842 24.4534 85.7125 23.8754Q86.0408 23.2975 86.3953 22.7352Q86.7497 22.1729 87.1295 21.6274Q87.5094 21.0819 87.9138 20.5545Q88.3183 20.027 88.7464 19.5186Q89.1746 19.0101 89.6256 18.5219Q90.0767 18.0336 90.5496 17.5666Q91.0225 17.0995 91.5163 16.6546Q92.0101 16.2097 92.5238 15.7878Q93.0375 15.366 93.57 14.9682Q94.1025 14.5703 94.6526 14.1973Q95.2028 13.8243 95.7694 13.4768Q96.3361 13.1294 96.9181 12.8083Q97.5 12.4872 98.0961 12.1931Q98.6922 11.899 99.3012 11.6325Q99.9101 11.366 100.531 11.1277Q101.151 10.8894 101.782 10.6798Q102.413 10.4702 103.052 10.2897Q103.692 10.1092 104.339 9.95819Q104.987 9.80719 105.64 9.68601Q106.294 9.56483 106.952 9.47372Q107.611 9.38261 108.273 9.32177Q108.934 9.26092 109.598 9.23047Q110.262 9.20001 110.927 9.20001L132.8 9.20001L129.915 36.8144Q129.846 37.4754 129.747 38.1327Q129.647 38.7899 129.518 39.4419Q129.389 40.0939 129.23 40.7393Q129.071 41.3847 128.882 42.0221Q128.694 42.6595 128.476 43.2876Q128.259 43.9157 128.013 44.5332Q127.767 45.1507 127.493 45.7563Q127.219 46.3619 126.917 46.9543Q126.616 47.5466 126.288 48.1246Q125.959 48.7025 125.605 49.2648Q125.25 49.8271 124.87 50.3726Q124.491 50.9181 124.086 51.4456Q123.682 51.9731 123.254 52.4815Q122.825 52.9899 122.374 53.4781Q121.923 53.9664 121.45 54.4334Q120.978 54.9005 120.484 55.3454Q119.99 55.7904 119.476 56.2122Q118.963 56.634 118.43 57.0319Q117.898 57.4297 117.347 57.8027Q116.797 58.1758 116.231 58.5232Q115.664 58.8706 115.082 59.1917Q114.5 59.5128 113.904 59.8069Q113.308 60.101 112.699 60.3675Q112.09 60.634 111.469 60.8723Q110.849 61.1106 110.218 61.3202Q109.587 61.5298 108.948 61.7103Q108.308 61.8908 107.661 62.0418Q107.013 62.1928 106.36 62.314Q105.706 62.4352 105.048 62.5263Q104.389 62.6174 103.727 62.6782Q103.066 62.7391 102.402 62.7695Q101.738 62.8 101.073 62.8L79.2 62.8ZM578.8 94.8L565.2 107.2L561.6 134L585.6 134L574.8 221.2C572.667 239.867 576.867 254.2 587.4 264.2C597.933 274.2 612.8 279.2 632 279.2C649.867 279.2 663.733 274.4 673.6 264.8C683.467 255.2 690.933 240 696 219.2L661.2 207.6Q656 228.4 649.8 234.2C645.667 238.067 641.467 240 637.2 240Q632.752 240 629.894 237.868Q623.241 232.907 625.2 216.4L635.2 134L676.8 134L690.4 121.2L694 94.8L640 94.8L646.8 40.0001L610.8 40.0001L595.2 56L590.4 94.8L578.8 94.8ZM158.4 139.6L198.4 144L207.6 114.4C211.867 112.267 217.2 110.733 223.6 109.8C230 108.867 235.467 108.4 240 108.4C248.8 108.4 256.333 110 262.6 113.2C268.867 116.4 272 122 272 130C272 140.933 265.933 151.733 253.8 162.4Q235.6 178.4 206.2 195.4C186.6 206.733 165.467 219.2 142.8 232.8L143.2 275.2L321.2 275.2L330 204.4L288.8 200.4L284.4 229.6L206.8 229.6C225.2 220.267 243.867 210.667 262.8 200.8C281.733 190.933 297.6 179.4 310.4 166.2Q329.6 146.4 329.6 118.4Q329.6 96 313.2 79.4C302.267 68.3333 282.533 62.8 254 62.8Q240 62.8 218.4 65.8Q196.8 68.8 173.6 78.4L158.4 139.6ZM724 94.8L779.6 94.8L781.2 129.6C787.333 118.133 795.2 108.867 804.8 101.8C814.4 94.7334 826 91.2 839.6 91.2C852.667 91.2 863.6 94.4667 872.4 101C881.2 107.533 886.533 117.6 888.4 131.2Q897.6 113.6 912.2 102.4C921.933 94.9333 933.733 91.2 947.6 91.2C963.867 91.2 976.733 96.2667 986.2 106.4C995.667 116.533 999.067 132.267 996.4 153.6L986.4 236L1009.6 236L1006 265.2L994 275.2L932.4 275.2L944.8 173.6C946.667 158.133 945.733 147.067 942 140.4C938.267 133.733 931.467 130.4 921.6 130.4Q903.6 130.4 896 142.4C890.933 150.4 887.6 160.667 886 173.2L873.6 275.2L824.4 275.2L836.8 173.6C838.667 158.133 837.733 147.067 834 140.4C830.267 133.733 823.467 130.4 813.6 130.4Q795.6 130.4 788 142.4C782.933 150.4 779.6 160.667 778 173.2L765.6 275.2L716 275.2L733.2 134L708 134L711.6 105.6L724 94.8ZM57.2 94.8L44.8 105.6L41.2 134L70.4 134L54 268.8Q48.8 312 35.4 319.2C26.4667 324 15.3333 323.867 2 318.8L0 352Q17.2 364 40 364C58.9333 364 73.3333 354.933 83.2 336.8C93.0667 318.667 99.7333 296 103.2 268.8L124.8 94.8L57.2 94.8Z" transform="translate(592 103.83917)" id="j2html" fill="#222222" fill-rule="evenodd" stroke="none" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
33
docs/index.html
Normal file
7
docs/js/prism.js
Normal file
@@ -0,0 +1,7 @@
|
||||
/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+java */
|
||||
self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=t.util.clone(e[r]));return a;case"Array":return e.map(function(e){return t.util.clone(e)})}return e}},languages:{extend:function(e,n){var a=t.util.clone(t.languages[e]);for(var r in n)a[r]=n[r];return a},insertBefore:function(e,n,a,r){r=r||t.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var s={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var l in a)a.hasOwnProperty(l)&&(s[l]=a[l]);s[o]=i[o]}return t.languages.DFS(t.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=s)}),r[e]=s},DFS:function(e,n,a){for(var r in e)e.hasOwnProperty(r)&&(n.call(e,r,e[r],a||r),"Object"===t.util.type(e[r])?t.languages.DFS(e[r],n):"Array"===t.util.type(e[r])&&t.languages.DFS(e[r],n,r))}},highlightAll:function(e,n){for(var a,r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'),i=0;a=r[i++];)t.highlightElement(a,e===!0,n)},highlightElement:function(a,r,i){for(var l,s,o=a;o&&!e.test(o.className);)o=o.parentNode;if(o&&(l=(o.className.match(e)||[,""])[1],s=t.languages[l]),s){a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=a.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var u=a.textContent;if(u){u=u.replace(/^(?:\r?\n|\r)/,"");var g={element:a,language:l,grammar:s,code:u};if(t.hooks.run("before-highlight",g),r&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){g.highlightedCode=n.stringify(JSON.parse(e.data),l),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(g.element),t.hooks.run("after-highlight",g)},c.postMessage(JSON.stringify({language:g.language,code:g.code}))}else g.highlightedCode=t.highlight(g.code,g.grammar,g.language),t.hooks.run("before-insert",g),g.element.innerHTML=g.highlightedCode,i&&i.call(a),t.hooks.run("after-highlight",g)}}},highlight:function(e,a,r){var i=t.tokenize(e,a);return n.stringify(t.util.encode(i),r)},tokenize:function(e,n){var a=t.Token,r=[e],i=n.rest;if(i){for(var l in i)n[l]=i[l];delete n.rest}e:for(var l in n)if(n.hasOwnProperty(l)&&n[l]){var s=n[l];s="Array"===t.util.type(s)?s:[s];for(var o=0;o<s.length;++o){var u=s[o],g=u.inside,c=!!u.lookbehind,f=0,h=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var d=r[p];if(r.length>e.length)break e;if(!(d instanceof a)){u.lastIndex=0;var m=u.exec(d);if(m){c&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("Array"===t.util.type(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var s="";for(var o in i.attributes)s+=o+'="'+(i.attributes[o]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+s+">"+i.content+"</"+i.tag+">"},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);;
|
||||
Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/i,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/=|>|"/}},punctuation:/\/?>/,"attr-name":{pattern:/[\w:-]+/,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});;
|
||||
Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{punctuation:/[;:]/}},url:/url\((?:(["'])(\\\n|\\?.)*?\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/,string:/("|')(\\\n|\\?.)*?\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,punctuation:/[\{\};:]/,"function":/[-a-z0-9]+(?=\()/i},Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/<style[\w\W]*?>[\w\W]*?<\/style>/i,inside:{tag:{pattern:/<style[\w\W]*?>|<\/style>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css},alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));;
|
||||
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/("|')(\\\n|\\?.)*?\1/,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":{pattern:/[a-z0-9_]+\(/i,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|~|\^|%/,ignore:/&(lt|gt|amp);/i,punctuation:/[{}[\];(),.:]/};;
|
||||
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|-?Infinity)\b/,"function":/(?!\d)[a-z0-9_$]+(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/<script[\w\W]*?>[\w\W]*?<\/script>/i,inside:{tag:{pattern:/<script[\w\W]*?>|<\/script>/i,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript},alias:"language-javascript"}});;
|
||||
Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+[e]?[\d]*[df]\b|\b\d*\.?\d+\b/i,operator:{pattern:/(^|[^\.])(?:\+=|\+\+?|-=|--?|!=?|<{1,2}=?|>{1,3}=?|==?|&=|&&?|\|=|\|\|?|\?|\*=?|\/=?|%=?|\^=?|:|~)/m,lookbehind:!0}});;
|
||||
19
docs/news.html
Normal file
101
j2html-codegen/.gitignore
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
### Eclipse ###
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
buildNumber.properties
|
||||
86
j2html-codegen/pom.xml
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html-parent</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>j2html-codegen</name>
|
||||
<artifactId>j2html-codegen-maven-plugin</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>3.8.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-project</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Note: The use of version properties below is to avoid
|
||||
redefining these versions when using this maven plugin
|
||||
in other projects. Using the more concise dependency-
|
||||
management strategy for versioning doesn't work when
|
||||
another project tries to detect this plugin's dependency
|
||||
versions.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup</groupId>
|
||||
<artifactId>javapoet</artifactId>
|
||||
<version>${javapoet.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.6.4</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
33
j2html-codegen/src/main/java/com/j2html/codegen/App.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import com.j2html.codegen.generators.SpecializedTagClassCodeGenerator;
|
||||
import com.j2html.codegen.generators.AttributeInterfaceCodeGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public final class App
|
||||
{
|
||||
public static void main( String[] args )
|
||||
{
|
||||
final Path relPath = Paths.get("../library/src/main/java/j2html/");
|
||||
final Path absPath = relPath.toAbsolutePath();
|
||||
|
||||
System.out.println("writing in "+absPath);
|
||||
|
||||
//decide if the files should be
|
||||
//deleted or generated
|
||||
final boolean delete = false;
|
||||
|
||||
try {
|
||||
AttributeInterfaceCodeGenerator.generate(absPath, delete);
|
||||
SpecializedTagClassCodeGenerator.generate(absPath, delete);
|
||||
//TagCreatorCodeGenerator.print();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//don't forget to auto-reformat the generated code.
|
||||
}
|
||||
}
|
||||
50
j2html-codegen/src/main/java/com/j2html/codegen/Export.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import com.j2html.codegen.model.AttrD;
|
||||
|
||||
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.containerTags;
|
||||
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.emptyTags;
|
||||
import static com.j2html.codegen.model.AttributesList.attributesDescriptive;
|
||||
import static com.j2html.codegen.model.AttributesList.getCustomAttributesForHtmlTag;
|
||||
import static java.lang.System.*;
|
||||
|
||||
public class Export {
|
||||
|
||||
public static void main(String[] args){
|
||||
for (final String tag : emptyTags()) {
|
||||
out.print("EMPTY-ELEMENT[");
|
||||
out.print(tag);
|
||||
out.print("]");
|
||||
out.println();
|
||||
}
|
||||
for (final String tag : containerTags()) {
|
||||
out.print("ELEMENT[");
|
||||
out.print(tag);
|
||||
out.print("]");
|
||||
out.println();
|
||||
}
|
||||
|
||||
out.println();
|
||||
|
||||
for(AttrD attr : attributesDescriptive()){
|
||||
if(attr.hasArgument){
|
||||
out.print("STRING");
|
||||
}else{
|
||||
out.print("BOOLEAN");
|
||||
}
|
||||
out.print("[");
|
||||
out.print(attr.attr);
|
||||
out.print("]");
|
||||
out.println();
|
||||
for(String tag : attr.tags){
|
||||
out.print("ATTRIBUTE[");
|
||||
out.print(tag);
|
||||
out.print(":");
|
||||
out.print(attr.attr);
|
||||
out.print("]");
|
||||
out.println();
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
199
j2html-codegen/src/main/java/com/j2html/codegen/Generator.java
Normal file
@@ -0,0 +1,199 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import com.j2html.codegen.Model.Node;
|
||||
import com.squareup.javapoet.*;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.j2html.codegen.Model.Metadata.ON_OFF;
|
||||
import static com.j2html.codegen.Model.Metadata.SELF_CLOSING;
|
||||
|
||||
public class Generator {
|
||||
|
||||
public static final ClassName INSTANCE = ClassName.get("j2html.tags", "IInstance");
|
||||
public static final ClassName TAG = ClassName.get("j2html.tags", "Tag");
|
||||
public static final ClassName EMPTY_TAG = ClassName.get("j2html.tags", "EmptyTag");
|
||||
public static final ClassName CONTAINER_TAG = ClassName.get("j2html.tags", "ContainerTag");
|
||||
|
||||
public static void main(String... args) throws IOException {
|
||||
Path path = Paths.get("j2html-codegen", "src", "test", "resources", "html.model");
|
||||
String definitions = new String(Files.readAllBytes(path));
|
||||
Model model = new Model();
|
||||
Parser.parse(definitions, model);
|
||||
|
||||
Path dir = Paths.get("/j2html/generated-source");
|
||||
Files.createDirectories(dir);
|
||||
generate(dir, "j2html.tags.attributes", "j2html.tags.specialized", model);
|
||||
}
|
||||
|
||||
public static void generate(Path root, String attributePkg, String elementPkg, Model model) throws IOException {
|
||||
Map<String, JavaFile> attributes = generateAttributePackage(attributePkg, model);
|
||||
for (JavaFile file : attributes.values()) {
|
||||
file.writeTo(root);
|
||||
}
|
||||
|
||||
Map<String, JavaFile> elements = generateElementPackage(elementPkg, model, attributes);
|
||||
for (JavaFile file : elements.values()) {
|
||||
file.writeTo(root);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, JavaFile> generateElementPackage(String pkg, Model model, Map<String, JavaFile> attributes) {
|
||||
Map<String, JavaFile> files = new HashMap<>();
|
||||
|
||||
// Convert all elements into classes.
|
||||
for (Node element : model.elements()) {
|
||||
ClassName className = ClassName.get(pkg, capitalize(element.name) + "Tag");
|
||||
|
||||
TypeSpec.Builder type = defineElementClass(element, className);
|
||||
|
||||
// Assign attributes to this element.
|
||||
for (Node attribute : element.children) {
|
||||
JavaFile file = attributes.get(attribute.name);
|
||||
type.addSuperinterface(
|
||||
ParameterizedTypeName.get(
|
||||
ClassName.get(file.packageName, file.typeSpec.name),
|
||||
className
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
files.put(
|
||||
element.name,
|
||||
JavaFile.builder(pkg, type.build())
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private static Map<String, JavaFile> generateAttributePackage(String pkg, Model model) {
|
||||
Map<String, JavaFile> files = new HashMap<>();
|
||||
|
||||
// Convert all attributes into classes.
|
||||
for (Node attribute : model.attributes()) {
|
||||
TypeSpec.Builder type = defineAttributeClass(pkg, attribute);
|
||||
|
||||
if (attribute.type.equals(Node.Type.STRING)) {
|
||||
defineStringAttributeMethods(attribute, type);
|
||||
} else if (attribute.type.equals(Node.Type.BOOLEAN) && !attribute.is(ON_OFF)) {
|
||||
defineBooleanAttributeMethods(attribute, type);
|
||||
} else if (attribute.type.equals(Node.Type.BOOLEAN) && attribute.is(ON_OFF)) {
|
||||
defineOnOffAttributeMethods(attribute, type);
|
||||
}
|
||||
|
||||
files.put(
|
||||
attribute.name,
|
||||
JavaFile.builder(pkg, type.build())
|
||||
.skipJavaLangImports(true)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private static TypeSpec.Builder defineElementClass(Node element, ClassName className) {
|
||||
MethodSpec constructor = MethodSpec.constructorBuilder()
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addStatement("super(\"" + element.name + "\")")
|
||||
.build();
|
||||
|
||||
TypeSpec.Builder type = TypeSpec.classBuilder(className)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.superclass(
|
||||
ParameterizedTypeName.get(element.is(SELF_CLOSING) ? EMPTY_TAG : CONTAINER_TAG, className)
|
||||
)
|
||||
.addMethod(constructor);
|
||||
return type;
|
||||
}
|
||||
|
||||
private static TypeSpec.Builder defineAttributeClass(String pkg, Node attribute) {
|
||||
ClassName name = ClassName.get(pkg, "I" + capitalize(attribute.name));
|
||||
return TypeSpec.interfaceBuilder(name)
|
||||
.addSuperinterface(ParameterizedTypeName.get(INSTANCE, TypeVariableName.get("T")))
|
||||
.addTypeVariable(TypeVariableName.get("T", ParameterizedTypeName.get(TAG, TypeVariableName.get("T"))))
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
}
|
||||
|
||||
private static void defineBooleanAttributeMethods(Node attribute, TypeSpec.Builder type) {
|
||||
MethodSpec with = MethodSpec.methodBuilder(methodName("is", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addStatement("return self().attr(\"" + attribute.name + "\")")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
|
||||
.addStatement("return enable ? self().attr(\"" + attribute.name + "\") : self()")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
type.addMethod(with);
|
||||
type.addMethod(withCond);
|
||||
}
|
||||
|
||||
private static void defineOnOffAttributeMethods(Node attribute, TypeSpec.Builder type) {
|
||||
MethodSpec with = MethodSpec.methodBuilder(methodName("is", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addStatement("return self().attr(\"" + attribute.name + "\", \"on\")")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
|
||||
.addStatement("return enable ? self().attr(\"" + attribute.name + "\", \"on\") : self()")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
type.addMethod(with);
|
||||
type.addMethod(withCond);
|
||||
}
|
||||
|
||||
private static void defineStringAttributeMethods(Node attribute, TypeSpec.Builder type) {
|
||||
MethodSpec with = MethodSpec.methodBuilder(methodName("with", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addParameter(String.class, parameter(attribute), Modifier.FINAL)
|
||||
.addStatement("return self().attr(\"" + attribute.name + "\", " + parameter(attribute) + ")")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
MethodSpec withCond = MethodSpec.methodBuilder(methodName("withCond", attribute.name))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||
.addParameter(TypeName.BOOLEAN, "enable", Modifier.FINAL)
|
||||
.addParameter(String.class, parameter(attribute), Modifier.FINAL)
|
||||
.addStatement("return enable ? self().attr(\"" + attribute.name + "\", " + parameter(attribute) + ") : self()")
|
||||
.returns(TypeVariableName.get("T"))
|
||||
.build();
|
||||
|
||||
type.addMethod(with);
|
||||
type.addMethod(withCond);
|
||||
}
|
||||
|
||||
private static String parameter(Node attribute) {
|
||||
return attribute.name + "_";
|
||||
}
|
||||
|
||||
private static String methodName(String... words) {
|
||||
String[] camelCase = new String[words.length];
|
||||
camelCase[0] = words[0];
|
||||
for (int i = 1; i < words.length; i++) {
|
||||
camelCase[i] = capitalize(words[i]);
|
||||
}
|
||||
return String.join("", camelCase);
|
||||
}
|
||||
|
||||
private static String capitalize(String word) {
|
||||
return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class GeneratorUtil {
|
||||
|
||||
public static final void deleteAllFilesInDir(final Path dir) throws IOException {
|
||||
for(final File file : dir.toFile().listFiles()){
|
||||
System.out.println("deleting " + file.toPath());
|
||||
Files.delete(file.toPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Mojo(name = "generate-source-files", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
|
||||
public class J2htmlCodeGeneratorMojo extends AbstractMojo {
|
||||
|
||||
@Parameter(defaultValue = "${project}", required = true, readonly = true)
|
||||
MavenProject project;
|
||||
|
||||
@Parameter(property = "modelFile", required = true)
|
||||
String modelFile;
|
||||
|
||||
@Parameter(property = "attributePackage", required = true)
|
||||
String attributePackage;
|
||||
|
||||
@Parameter(property = "tagPackage", required = true)
|
||||
String tagPackage;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
getLog().debug("Model File: " + modelFile);
|
||||
getLog().debug("Attribute Package: " + attributePackage);
|
||||
getLog().debug("Tag Package: " + tagPackage);
|
||||
|
||||
String outputDirectory = project.getBuild().getDirectory() + "/generated-sources/j2html-codegen";
|
||||
project.addCompileSourceRoot(outputDirectory);
|
||||
getLog().debug("Generating J2Html sources in: " + outputDirectory);
|
||||
|
||||
String definitions;
|
||||
try {
|
||||
definitions = new String(Files.readAllBytes(Paths.get(modelFile)));
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Unable to locate model file: " + modelFile, e);
|
||||
}
|
||||
|
||||
Model model = new Model();
|
||||
try {
|
||||
Parser.parse(definitions, model);
|
||||
}catch (RuntimeException e){
|
||||
throw new MojoFailureException("Unable to parse model file.", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Generator.generate(
|
||||
Paths.get(outputDirectory).toAbsolutePath(),
|
||||
attributePackage,
|
||||
tagPackage,
|
||||
model
|
||||
);
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Failed to generate source files.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
171
j2html-codegen/src/main/java/com/j2html/codegen/Model.java
Normal file
@@ -0,0 +1,171 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.j2html.codegen.Model.Metadata.ON_OFF;
|
||||
import static com.j2html.codegen.Model.Metadata.SELF_CLOSING;
|
||||
import static com.j2html.codegen.Model.Node.Type.*;
|
||||
|
||||
public class Model implements Parser.Listener {
|
||||
|
||||
private Map<String, Node> elements;
|
||||
private Map<String, Node> attributes;
|
||||
|
||||
public Model() {
|
||||
elements = new LinkedHashMap<>();
|
||||
attributes = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
public Collection<Node> elements(){
|
||||
return elements.values();
|
||||
}
|
||||
|
||||
public Collection<Node> attributes(){
|
||||
return attributes.values();
|
||||
}
|
||||
|
||||
public Node addElement(String name) {
|
||||
return add(ELEMENT, name, elements);
|
||||
}
|
||||
|
||||
public Node addBooleanAttribute(String name) {
|
||||
return add(BOOLEAN, name, attributes);
|
||||
}
|
||||
|
||||
public Node addStringAttribute(String name) {
|
||||
return add(STRING, name, attributes);
|
||||
}
|
||||
|
||||
public Node element(String name) {
|
||||
if (!elements.containsKey(name)) {
|
||||
throw new NodeDoesNotExist(name);
|
||||
}
|
||||
return elements.get(name);
|
||||
}
|
||||
|
||||
public Node attribute(String name) {
|
||||
if (!attributes.containsKey(name)) {
|
||||
throw new NodeDoesNotExist(name);
|
||||
}
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
private Node add(Node.Type type, String name, Map<String, Node> nodes) {
|
||||
if (nodes.containsKey(name)) {
|
||||
throw new NodeAlreadyExists(name);
|
||||
}
|
||||
|
||||
Node node = new Node(type, name);
|
||||
nodes.put(name, node);
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lineCommented(int line, String txt) {
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elementDefined(int line, String name) {
|
||||
attempt(() -> addElement(name), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emptyElementDefined(int line, String name) {
|
||||
attempt(() -> addElement(name).annotate(SELF_CLOSING), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void booleanDefined(int line, String name) {
|
||||
attempt(() -> addBooleanAttribute(name), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOffDefined(int line, String name) {
|
||||
attempt(() -> addBooleanAttribute(name).annotate(ON_OFF), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stringDefined(int line, String name) {
|
||||
attempt(() -> addStringAttribute(name), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attributeDefined(int line, String element, String name) {
|
||||
attempt(() -> element(element).addChild(attribute(name)), line);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidLine(int line, String txt) {
|
||||
throw new RuntimeException("Invalid line [" + line + "]: " + txt);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface Unsafe {
|
||||
void call() throws RuntimeException;
|
||||
}
|
||||
|
||||
private void attempt(Unsafe operation, int line) {
|
||||
try {
|
||||
operation.call();
|
||||
} catch (RuntimeException e) {
|
||||
throw new InvalidModel(e, line);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Node {
|
||||
enum Type {
|
||||
ELEMENT,
|
||||
BOOLEAN,
|
||||
STRING
|
||||
}
|
||||
|
||||
public final Type type;
|
||||
public final String name;
|
||||
public final List<Metadata> metadata;
|
||||
public final List<Node> children;
|
||||
|
||||
private Node(Type type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.metadata = new ArrayList<>();
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void annotate(Metadata meta) {
|
||||
metadata.add(meta);
|
||||
}
|
||||
|
||||
public void addChild(Node node) {
|
||||
children.add(node);
|
||||
}
|
||||
|
||||
public boolean is(Metadata annotation){
|
||||
return metadata.contains(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Metadata {
|
||||
SELF_CLOSING,
|
||||
ON_OFF,
|
||||
OBSOLETE
|
||||
}
|
||||
|
||||
public static class InvalidModel extends RuntimeException {
|
||||
public InvalidModel(Exception cause, int line) {
|
||||
super(cause.getMessage() + ". At line " + line, cause);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NodeAlreadyExists extends RuntimeException {
|
||||
public NodeAlreadyExists(String name) {
|
||||
super("Node already exists: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NodeDoesNotExist extends RuntimeException {
|
||||
public NodeDoesNotExist(String name) {
|
||||
super("Node does not exist: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
j2html-codegen/src/main/java/com/j2html/codegen/Parser.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Parser {
|
||||
|
||||
private static final Pattern EMPTY_LINE_PATTERN = Pattern.compile("\\s*");
|
||||
private static final Pattern COMMENT_PATTERN = Pattern.compile("#.*");
|
||||
private static final Pattern NODE_PATTERN = Pattern.compile("(?<type>ELEMENT|EMPTY-ELEMENT|BOOLEAN|ONOFF|STRING)\\[(?<name>\\S+)\\]");
|
||||
private static final Pattern ATTRIBUTE_PATTERN = Pattern.compile("ATTRIBUTE\\[(?<element>\\S+):(?<name>\\S+)\\]");
|
||||
|
||||
public interface Listener {
|
||||
void lineCommented(int line, String txt);
|
||||
|
||||
void elementDefined(int line, String name);
|
||||
|
||||
void emptyElementDefined(int line, String name);
|
||||
|
||||
void booleanDefined(int line, String name);
|
||||
|
||||
void onOffDefined(int line, String name);
|
||||
|
||||
void stringDefined(int line, String name);
|
||||
|
||||
void attributeDefined(int line, String element, String name);
|
||||
|
||||
void invalidLine(int line, String txt);
|
||||
}
|
||||
|
||||
public static void parse(String txt, Listener listener) {
|
||||
String[] lines = txt.split("[\r\n]+");
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
int number = i + 1;
|
||||
String line = lines[i];
|
||||
|
||||
if (match(EMPTY_LINE_PATTERN, line)) continue;
|
||||
|
||||
if (match(COMMENT_PATTERN, line, matcher -> {
|
||||
listener.lineCommented(number, line);
|
||||
})) continue;
|
||||
|
||||
if (match(NODE_PATTERN, line, matcher -> {
|
||||
String type = matcher.group("type");
|
||||
String name = matcher.group("name");
|
||||
switch (type) {
|
||||
case "ELEMENT":
|
||||
listener.elementDefined(number, name);
|
||||
break;
|
||||
case "EMPTY-ELEMENT":
|
||||
listener.emptyElementDefined(number, name);
|
||||
break;
|
||||
case "BOOLEAN":
|
||||
listener.booleanDefined(number, name);
|
||||
break;
|
||||
case "ONOFF":
|
||||
listener.onOffDefined(number, name);
|
||||
break;
|
||||
case "STRING":
|
||||
listener.stringDefined(number, name);
|
||||
break;
|
||||
}
|
||||
})) continue;
|
||||
|
||||
if (match(ATTRIBUTE_PATTERN, line, matcher -> {
|
||||
listener.attributeDefined(
|
||||
number,
|
||||
matcher.group("element"),
|
||||
matcher.group("name")
|
||||
);
|
||||
})) continue;
|
||||
|
||||
listener.invalidLine(number, line);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean match(Pattern pattern, String txt) {
|
||||
return pattern.matcher(txt).matches();
|
||||
}
|
||||
|
||||
private static boolean match(Pattern pattern, String txt, Consumer<Matcher> onMatch) {
|
||||
Matcher matcher = pattern.matcher(txt);
|
||||
if (matcher.matches()) {
|
||||
onMatch.accept(matcher);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.j2html.codegen.generators;
|
||||
|
||||
import com.j2html.codegen.GeneratorUtil;
|
||||
import com.j2html.codegen.model.AttrD;
|
||||
import com.j2html.codegen.model.AttributesList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class AttributeInterfaceCodeGenerator {
|
||||
|
||||
private static final String relPath = "tags/attributes/";
|
||||
|
||||
public static void generate(final Path absPath, final boolean delete) throws IOException {
|
||||
|
||||
//delete all files in the directory for fresh generation
|
||||
final Path dir = Paths.get(absPath.toString(),relPath);
|
||||
GeneratorUtil.deleteAllFilesInDir(dir);
|
||||
|
||||
for (final AttrD attr : AttributesList.attributesDescriptive()) {
|
||||
final Path path = makePath(attr.attr, absPath);
|
||||
final String interfaceName = interfaceNameFromAttribute(attr.attr)+"<T extends Tag<T>>";
|
||||
/*
|
||||
IFormAction<T extends Tag<T>> extends IInstance<T>
|
||||
|
||||
default T withFormAction(String formAction){
|
||||
return self().attr("formaction", formAction);
|
||||
}
|
||||
*/
|
||||
final String interfaceStr = getInterfaceTemplate(
|
||||
interfaceName,
|
||||
Optional.of("IInstance<T>"),
|
||||
Arrays.asList("j2html.tags.Tag","j2html.tags.IInstance"),
|
||||
interfaceNameFromAttribute(attr.attr).substring(1),
|
||||
attr
|
||||
);
|
||||
|
||||
if (!delete) {
|
||||
System.out.println("writing to "+path);
|
||||
Files.write(path, interfaceStr.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String getPackage(){
|
||||
return "package j2html.tags.attributes;\n";
|
||||
}
|
||||
|
||||
private static String makeReturnTypeAndMethodName(final String name){
|
||||
return "default "+ "T "+name;
|
||||
}
|
||||
|
||||
private static String getInterfaceTemplate(
|
||||
final String interfaceName,
|
||||
final Optional<String> optExtends,
|
||||
final List<String> imports,
|
||||
final String interfaceNameSimple,
|
||||
final AttrD attrD
|
||||
){
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(getPackage());
|
||||
sb.append("\n");
|
||||
|
||||
for(String importName : imports){
|
||||
sb.append("import ").append(importName).append(";\n");
|
||||
}
|
||||
sb.append("\n");
|
||||
sb.append("public interface ")
|
||||
.append(interfaceName);
|
||||
|
||||
optExtends.ifPresent(ext -> sb.append(" extends ").append(ext).append(" "));
|
||||
|
||||
sb.append(" {\n");
|
||||
|
||||
//interface contents
|
||||
/*
|
||||
IFormAction<T extends Tag> extends IInstance<T>
|
||||
|
||||
default T withFormAction(String formAction){
|
||||
return self().attr("formaction", formAction);
|
||||
}
|
||||
*/
|
||||
//IMPORTANT: '_' added as suffix to mitigate problems
|
||||
//where attributes are java keywords. Just to make it consistent and avoid special cases.
|
||||
final String attrName = interfaceNameSimple.toLowerCase();
|
||||
final String paramName = attrName+"_";
|
||||
|
||||
//depending on if the attribute has an argument or not,
|
||||
//generate methods according to the convention in Tag.java
|
||||
// arg -> with$ATTR(arg), withCond$ATTR(condition, arg)
|
||||
// no arg -> is$ATTR(), withCond$ATTR(condition)
|
||||
|
||||
//append the 'with$ATTR' method
|
||||
writeAttributeMethod(interfaceNameSimple, attrD, sb, attrName, paramName);
|
||||
writeAttributeMethodCond(interfaceNameSimple, attrD, sb, attrName, paramName);
|
||||
|
||||
sb.append("}\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void addAttributeNoArg(final StringBuilder sb, final String attrName){
|
||||
//generate the code to add an attribute without an argument
|
||||
|
||||
//there are some special attributes
|
||||
//which do take an argument, but where the argument
|
||||
//is boolean (meaning on/off, yes/no and the like)
|
||||
sb.append("self().attr(\"");
|
||||
if (attrName.equals("autocomplete")){
|
||||
sb.append(attrName).append("\",\"on\"");
|
||||
} else {
|
||||
sb.append(attrName).append("\"");
|
||||
}
|
||||
sb.append(");\n");
|
||||
}
|
||||
|
||||
private static void writeAttributeMethodCond(String interfaceNameSimple, AttrD attrD, StringBuilder sb, String attrName, String paramName) {
|
||||
|
||||
sb.append(makeReturnTypeAndMethodName("withCond"+interfaceNameSimple));
|
||||
|
||||
if(attrD.hasArgument){
|
||||
//add a variant where you can specify the argument
|
||||
|
||||
sb.append("(final boolean enable, final String ").append(paramName).append(") {");
|
||||
|
||||
sb.append("if (enable){\n");
|
||||
sb.append("self().attr(\"").append(attrName).append("\", ").append(paramName).append(");\n");
|
||||
sb.append("}\n");
|
||||
|
||||
sb.append("return self();\n");
|
||||
}else{
|
||||
//add a variant where you can toggle the attribute
|
||||
|
||||
sb.append("(final boolean enable) {");
|
||||
sb.append("if (enable){\n");
|
||||
addAttributeNoArg(sb, attrName);
|
||||
sb.append("}\n");
|
||||
sb.append("return self();\n");
|
||||
}
|
||||
sb.append("}\n");
|
||||
}
|
||||
|
||||
private static void writeAttributeMethod(String interfaceNameSimple, AttrD attrD, StringBuilder sb, String attrName, String paramName) {
|
||||
|
||||
sb.append(makeReturnTypeAndMethodName(
|
||||
((attrD.hasArgument)?"with":"is")+interfaceNameSimple)
|
||||
);
|
||||
|
||||
if(attrD.hasArgument){
|
||||
//add a variant where you can specify the argument
|
||||
|
||||
sb.append("(final String ").append(paramName).append(") {")
|
||||
|
||||
.append("return self().attr(\"").append(attrName).append("\", ").append(paramName).append(");\n");
|
||||
}else{
|
||||
//add a variant where you can toggle the attribute
|
||||
|
||||
sb.append("() {");
|
||||
|
||||
addAttributeNoArg(sb, attrName);
|
||||
|
||||
sb.append("return self();\n");
|
||||
}
|
||||
sb.append("}\n");
|
||||
}
|
||||
|
||||
public static String interfaceNameFromAttribute(String attribute){
|
||||
String res = attribute.substring(0,1).toUpperCase()+attribute.substring(1);
|
||||
return "I" + res;
|
||||
}
|
||||
|
||||
private static Path makePath(String tagLowerCase, final Path absPath){
|
||||
final String filename = interfaceNameFromAttribute(tagLowerCase)+".java";
|
||||
return Paths.get(absPath.toString(),relPath,filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.j2html.codegen.generators;
|
||||
|
||||
|
||||
import com.j2html.codegen.GeneratorUtil;
|
||||
import com.j2html.codegen.model.AttributesList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.containerTags;
|
||||
import static com.j2html.codegen.generators.TagCreatorCodeGenerator.emptyTags;
|
||||
|
||||
public final class SpecializedTagClassCodeGenerator {
|
||||
|
||||
private static final String relPath = "tags/specialized";
|
||||
|
||||
public static void generate(final Path absPath, final boolean delete) throws IOException {
|
||||
|
||||
//delete all files in the directory for fresh generation
|
||||
final Path dir = Paths.get(absPath.toString(),relPath);
|
||||
GeneratorUtil.deleteAllFilesInDir(dir);
|
||||
|
||||
//the delete argument serves to give the possibility
|
||||
//to delete the classes that were written before
|
||||
System.out.println("// EmptyTags, generated in " + SpecializedTagClassCodeGenerator.class);
|
||||
|
||||
for (final String tag : emptyTags()) {
|
||||
final String className = classNameFromTag(tag);
|
||||
final Path path = makePath(absPath,tag);
|
||||
|
||||
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
|
||||
|
||||
final String classString =
|
||||
getClassTemplate(
|
||||
className,
|
||||
Optional.of("EmptyTag<"+className+">"),
|
||||
Arrays.asList(
|
||||
"j2html.tags.EmptyTag",
|
||||
"j2html.tags.attributes.*"
|
||||
),
|
||||
tag,
|
||||
interfaceNames
|
||||
);
|
||||
|
||||
/*
|
||||
public InputTag() {
|
||||
super("input");
|
||||
}
|
||||
*/
|
||||
|
||||
if(!delete){
|
||||
System.out.println("writing to "+path);
|
||||
Files.write(path, classString.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("// ContainerTags, generated in " + SpecializedTagClassCodeGenerator.class);
|
||||
|
||||
for (final String tag : containerTags()) {
|
||||
final Path path = makePath(absPath, tag);
|
||||
final String className = classNameFromTag(tag);
|
||||
|
||||
final List<String> interfaceNames = getInterfaceNamesForTag(tag);
|
||||
|
||||
final String classString =
|
||||
getClassTemplate(
|
||||
className,
|
||||
Optional.of("ContainerTag<"+className+">"),
|
||||
Arrays.asList(
|
||||
"j2html.tags.ContainerTag",
|
||||
"j2html.tags.attributes.*"
|
||||
),
|
||||
tag,
|
||||
interfaceNames
|
||||
);
|
||||
|
||||
if(delete){
|
||||
if(Files.exists(path)) {
|
||||
System.out.println("deleting " + path);
|
||||
Files.delete(path);
|
||||
}
|
||||
}else {
|
||||
System.out.println("writing to "+path);
|
||||
Files.write(path, classString.getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
public static String classNameFromTag(String tageNameLowerCase){
|
||||
String res = tageNameLowerCase.substring(0,1).toUpperCase()+tageNameLowerCase.substring(1);
|
||||
return res + "Tag";
|
||||
}
|
||||
|
||||
private static Path makePath(final Path absPath, String tagLowerCase){
|
||||
final String filename = classNameFromTag(tagLowerCase)+".java";
|
||||
return Paths.get(absPath.toString(),relPath,filename);
|
||||
}
|
||||
|
||||
private static String getPackage(){
|
||||
return "package j2html.tags.specialized;\n";
|
||||
}
|
||||
|
||||
private static String getClassTemplate(
|
||||
final String className,
|
||||
final Optional<String> optExtends,
|
||||
final List<String> imports,
|
||||
final String tag,
|
||||
final List<String> interfaces
|
||||
){
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(getPackage());
|
||||
sb.append("\n");
|
||||
|
||||
for(String importName : imports){
|
||||
sb.append("import ").append(importName).append(";\n");
|
||||
}
|
||||
sb.append("\n");
|
||||
sb.append("public final class ")
|
||||
.append(className)
|
||||
.append(" ");
|
||||
|
||||
optExtends.ifPresent(ext -> sb.append("extends ").append(ext).append(" "));
|
||||
|
||||
//add the 'implements' clause
|
||||
if(!interfaces.isEmpty()) {
|
||||
sb.append("\n");
|
||||
sb.append("implements ");
|
||||
|
||||
final List<String> genericInterfaceNames
|
||||
= interfaces.stream().map(iName -> iName+"<"+className+">")
|
||||
.collect(Collectors.toList());
|
||||
sb.append(
|
||||
String.join(",", genericInterfaceNames)
|
||||
);
|
||||
}
|
||||
|
||||
sb.append(" {\n");
|
||||
|
||||
//class contents
|
||||
sb.append("public ")
|
||||
.append(className)
|
||||
.append("() {")
|
||||
.append("super(\"").append(tag).append("\");")
|
||||
.append("}\n");
|
||||
|
||||
sb.append("}\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static List<String> getInterfaceNamesForTag(final String tagNameLowercase){
|
||||
return AttributesList.getCustomAttributesForHtmlTag(tagNameLowercase)
|
||||
.stream()
|
||||
.map(
|
||||
AttributeInterfaceCodeGenerator::interfaceNameFromAttribute
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +1,56 @@
|
||||
package j2html.tags;
|
||||
package com.j2html.codegen.generators;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class TagCreatorCodeGenerator {
|
||||
public final class TagCreatorCodeGenerator {
|
||||
|
||||
public static void print() {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("// EmptyTags, generated in " + TagCreatorCodeGenerator.class);
|
||||
|
||||
for (String tag : emptyTags()) {
|
||||
String emptyA1 = "public static EmptyTag " + tag + "()";
|
||||
String emptyA2 = "{ return new EmptyTag(\"" + tag + "\"); }";
|
||||
final String className = SpecializedTagClassCodeGenerator.classNameFromTag(tag);
|
||||
final String publicstaticTypeMethod = "public static "+className+" "+tag+" ";
|
||||
final String castReturn = " return ("+className+") ";
|
||||
final String construct = " new "+className+"()";
|
||||
|
||||
String emptyA1 = publicstaticTypeMethod + "()";
|
||||
String emptyA2 = "{ return "+construct+"; }";
|
||||
// Attr shorthands
|
||||
String emptyB1 = "public static EmptyTag " + tag + "(Attr.ShortForm shortAttr)";
|
||||
String emptyB2 = "{ return Attr.addTo(new EmptyTag(\"" + tag + "\"), shortAttr); }";
|
||||
String emptyB1 = publicstaticTypeMethod + "(Attr.ShortForm shortAttr)";
|
||||
String emptyB2 = "{ "+castReturn+" Attr.addTo("+construct+", shortAttr); }";
|
||||
// Print
|
||||
System.out.println(String.format("%-80s%1s", emptyA1, emptyA2));
|
||||
System.out.println(String.format("%-80s%1s", emptyB1, emptyB2));
|
||||
System.out.println("");
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
System.out.println("// ContainerTags, generated in " + TagCreatorCodeGenerator.class);
|
||||
|
||||
for (String tag : containerTags()) {
|
||||
String containerA1 = "public static ContainerTag " + tag + "()";
|
||||
String containerA2 = "{ return new ContainerTag(\"" + tag + "\"); }";
|
||||
String containerB1 = "public static ContainerTag " + tag + "(String text)";
|
||||
String containerB2 = "{ return new ContainerTag(\"" + tag + "\").withText(text); }";
|
||||
String containerC1 = "public static ContainerTag " + tag + "(DomContent... dc)";
|
||||
String containerC2 = "{ return new ContainerTag(\"" + tag + "\").with(dc); }";
|
||||
final String className = SpecializedTagClassCodeGenerator.classNameFromTag(tag);
|
||||
final String publicstaticTypeMethod = "public static "+className+" "+tag+" ";
|
||||
final String castReturn = " return ("+className+") ";
|
||||
final String construct = " new "+className+"()";
|
||||
|
||||
String containerA1 = publicstaticTypeMethod+ "()";
|
||||
String containerA2 = "{ "+castReturn + construct + "; }";
|
||||
|
||||
String containerB1 = publicstaticTypeMethod + "(String text)";
|
||||
String containerB2 = "{ "+castReturn + construct + ".withText(text); }";
|
||||
|
||||
String containerC1 = publicstaticTypeMethod + "(DomContent... dc)";
|
||||
String containerC2 = "{ "+castReturn + construct+".with(dc); }";
|
||||
// Attr shorthands
|
||||
String containerD1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr)";
|
||||
String containerD2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\"), shortAttr); }";
|
||||
String containerE1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, String text)";
|
||||
String containerE2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").withText(text), shortAttr); }";
|
||||
String containerF1 = "public static ContainerTag " + tag + "(Attr.ShortForm shortAttr, DomContent... dc)";
|
||||
String containerF2 = "{ return Attr.addTo(new ContainerTag(\"" + tag + "\").with(dc), shortAttr); }";
|
||||
String containerD1 = publicstaticTypeMethod + "(Attr.ShortForm shortAttr)";
|
||||
String containerD2 = "{ "+castReturn+" Attr.addTo("+construct+", shortAttr); }";
|
||||
|
||||
String containerE1 = publicstaticTypeMethod + "(Attr.ShortForm shortAttr, String text)";
|
||||
String containerE2 = "{ "+castReturn+" Attr.addTo("+construct+".withText(text), shortAttr); }";
|
||||
|
||||
String containerF1 = publicstaticTypeMethod + "(Attr.ShortForm shortAttr, DomContent... dc)";
|
||||
String containerF2 = "{ "+castReturn+" Attr.addTo("+construct+".with(dc), shortAttr); }";
|
||||
// Print
|
||||
System.out.println(String.format("%-80s%1s", containerA1, containerA2));
|
||||
System.out.println(String.format("%-80s%1s", containerB1, containerB2));
|
||||
@@ -40,12 +58,12 @@ class TagCreatorCodeGenerator {
|
||||
System.out.println(String.format("%-80s%1s", containerD1, containerD2));
|
||||
System.out.println(String.format("%-80s%1s", containerE1, containerE2));
|
||||
System.out.println(String.format("%-80s%1s", containerF1, containerF2));
|
||||
System.out.println("");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
// This is a method that contains all ContainerTags, there is nothing below it
|
||||
private static List<String> emptyTags() {
|
||||
public static List<String> emptyTags() {
|
||||
return Arrays.asList(
|
||||
"area",
|
||||
"base",
|
||||
@@ -66,7 +84,7 @@ class TagCreatorCodeGenerator {
|
||||
);
|
||||
}
|
||||
|
||||
private static List<String> containerTags() {
|
||||
public static List<String> containerTags() {
|
||||
return Arrays.asList(
|
||||
"a",
|
||||
"abbr",
|
||||
@@ -85,6 +103,7 @@ class TagCreatorCodeGenerator {
|
||||
"cite",
|
||||
"code",
|
||||
"colgroup",
|
||||
"data",
|
||||
"datalist",
|
||||
"dd",
|
||||
"del",
|
||||
@@ -130,6 +149,7 @@ class TagCreatorCodeGenerator {
|
||||
"option",
|
||||
"output",
|
||||
"p",
|
||||
"picture",
|
||||
"pre",
|
||||
"progress",
|
||||
"q",
|
||||
@@ -141,6 +161,7 @@ class TagCreatorCodeGenerator {
|
||||
"script",
|
||||
"section",
|
||||
"select",
|
||||
"slot",
|
||||
"small",
|
||||
"span",
|
||||
"strong",
|
||||
@@ -151,6 +172,7 @@ class TagCreatorCodeGenerator {
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"template",
|
||||
"textarea",
|
||||
"tfoot",
|
||||
"th",
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.j2html.codegen.generators;
|
||||
|
||||
import com.j2html.codegen.wattsi.AttributeDefinition;
|
||||
import com.j2html.codegen.wattsi.ElementDefinition;
|
||||
import com.j2html.codegen.wattsi.WattsiSource;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
public class WattsiGenerator {
|
||||
|
||||
public static void main(String... args) throws IOException {
|
||||
Path source = Paths.get(args[0]);
|
||||
Document doc = Jsoup.parse(source.toFile(), "UTF-8", "https://html.spec.whatwg.org/");
|
||||
WattsiSource wattsi = new WattsiSource(doc);
|
||||
|
||||
List<ElementDefinition> elements = wattsi.elementDefinitions();
|
||||
List<AttributeDefinition> attributes = wattsi.attributeDefinitions();
|
||||
|
||||
// for (ElementDefinition element : elements) {
|
||||
// System.out.println((element.isObsolete() ? "!" : "") + element.name());
|
||||
// for (AttributeDefinition attribute : attributes) {
|
||||
// if (attribute.appliesTo(element)) {
|
||||
// System.out.println(" " + (attribute.isObsolete() ? "!" : "") + attribute.name());
|
||||
// }
|
||||
// }
|
||||
// System.out.println();
|
||||
// }
|
||||
|
||||
for (ElementDefinition element : elements) {
|
||||
ClassName className = ClassName.get(
|
||||
"com.j2html",
|
||||
capitalize(element.name()) + "Tag"
|
||||
);
|
||||
|
||||
TypeSpec.Builder type = TypeSpec.classBuilder(className)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
if (element.isObsolete()) {
|
||||
type.addAnnotation(Deprecated.class);
|
||||
}
|
||||
|
||||
for (AttributeDefinition attribute : attributes) {
|
||||
if (attribute.appliesTo(element)) {
|
||||
String name = methodName("with", attribute.name().split("-"));
|
||||
MethodSpec.Builder setter = MethodSpec.methodBuilder(name)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.returns(className)
|
||||
.addStatement("return this");
|
||||
|
||||
if(attribute.isObsolete()){
|
||||
setter.addAnnotation(Deprecated.class);
|
||||
}
|
||||
|
||||
type.addMethod(setter.build());
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(type.build().toString());
|
||||
}
|
||||
|
||||
// System.out.println(doc.select("dfn"));
|
||||
}
|
||||
|
||||
private static String methodName(String prefix, String... words){
|
||||
String[] tmp = new String[words.length + 1];
|
||||
tmp[0] = prefix;
|
||||
for(int i = 0; i < words.length; i++){
|
||||
tmp[i+1] = words[i];
|
||||
}
|
||||
return methodName(tmp);
|
||||
}
|
||||
|
||||
private static String methodName(String... words){
|
||||
String[] camelCase = new String[words.length];
|
||||
camelCase[0] = words[0];
|
||||
for(int i = 1; i < words.length; i++){
|
||||
camelCase[i] = capitalize(words[i]);
|
||||
}
|
||||
return String.join("", camelCase);
|
||||
}
|
||||
|
||||
private static String capitalize(String word){
|
||||
return word.substring(0,1).toUpperCase() + word.substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.j2html.codegen.model;
|
||||
|
||||
public final class AttrD {
|
||||
//attribute descriptor
|
||||
|
||||
public final String attr;
|
||||
|
||||
public final boolean hasArgument;
|
||||
|
||||
//the html tags that this attribute can be used on
|
||||
public final String[] tags;
|
||||
|
||||
public AttrD(final String attr, boolean hasArgument){
|
||||
this.attr = attr;
|
||||
this.hasArgument = hasArgument;
|
||||
this.tags = new String[]{};
|
||||
}
|
||||
|
||||
public AttrD(final String attr, boolean hasArgument, final String... tags) {
|
||||
this.attr = attr;
|
||||
this.hasArgument = hasArgument;
|
||||
this.tags = tags;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.j2html.codegen.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class AttributesList {
|
||||
|
||||
//https://www.w3schools.com/tags/ref_attributes.asp
|
||||
|
||||
public static List<String> getCustomAttributesForHtmlTag(final String tagLowercase){
|
||||
|
||||
final List<String> attrs = new ArrayList<>();
|
||||
for(AttrD attrD : attributesDescriptive()){
|
||||
if(
|
||||
Arrays.asList(attrD.tags).contains(tagLowercase)
|
||||
){
|
||||
attrs.add(attrD.attr);
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
public static List<AttrD> attributesDescriptive() {
|
||||
return Arrays.asList(
|
||||
new AttrD("accept", true, "input"),
|
||||
//new AttrD("accept-charset","form"), //contains dashes, TODO
|
||||
//new AttrD("accesskey"), //global attribute
|
||||
new AttrD("action", true, "form"),
|
||||
//"align", not supported in HTML5
|
||||
new AttrD("alt", true, "area","img","input"),
|
||||
new AttrD("async", false, "script"),
|
||||
new AttrD("autocomplete", false, "form","input"),
|
||||
new AttrD("autofocus", false, "button","input","select","textarea"),
|
||||
new AttrD("autoplay", false, "audio","video"),
|
||||
//"bgcolor", not supported in HTMTL5
|
||||
//"border", not supported in HTML5
|
||||
new AttrD("charset", true, "meta","script"),
|
||||
new AttrD("checked", false, "input"),
|
||||
new AttrD("cite", true, "blockquote","del","ins","q"),
|
||||
//"class" already implemented in Tag.java // global attribute
|
||||
new AttrD("cols", true, "textarea"),
|
||||
new AttrD("colspan", true, "td","th"),
|
||||
new AttrD("content", true, "meta"),
|
||||
//"contenteditable" global attribute, should be in Tag.java
|
||||
new AttrD("controls", false, "audio","video"),
|
||||
new AttrD("coords", true, "area"),
|
||||
new AttrD("data", true, "object"),
|
||||
new AttrD("datetime", true, "del","ins","time"),
|
||||
new AttrD("default", false, "track"),
|
||||
new AttrD("defer", false, "script"),
|
||||
//new AttrD("dir"), //global attribute
|
||||
new AttrD("dirname", true, "input","textarea"),
|
||||
new AttrD("disabled",false, "button","fieldset","input","optgroup","option","select","textarea"),
|
||||
new AttrD("download",false, "a","area"),
|
||||
//new AttrD("draggable") global attribute, should be in Tag.java
|
||||
new AttrD("enctype", true, "form"),
|
||||
new AttrD("for", true, "label","output"),
|
||||
new AttrD("form", true, "button","fieldset","input","label","meter","object","output","select","textarea"),
|
||||
new AttrD("formaction", true, "button","input"),
|
||||
new AttrD("headers", true, "td","th"),
|
||||
new AttrD("height", true, "canvas","embed","iframe","img","input","object","video"),
|
||||
//new AttrD("hidden"), global attribute
|
||||
new AttrD("high", true, "meter"),
|
||||
new AttrD("href", true, "a","area","base","link"),
|
||||
new AttrD("hreflang", true, "a","area","link"),
|
||||
//"http-equiv", //TODO: '-' is problematic in code generation
|
||||
//"id" global attribute, should be in Tag.java
|
||||
new AttrD("ismap", false, "img"),
|
||||
new AttrD("kind", true, "track"),
|
||||
new AttrD("label", true, "track","option","optgroup"),
|
||||
//"lang" global attribute, should be in Tag.java
|
||||
new AttrD("list", true, "input"),
|
||||
new AttrD("loop", false, "audio","video"),
|
||||
new AttrD("low", true, "meter"),
|
||||
new AttrD("max", true, "input","meter","progress"),
|
||||
new AttrD("maxlength", true, "input","textarea"),
|
||||
new AttrD("media", true, "a","area","link","source","style"),
|
||||
new AttrD("method", true, "form"),
|
||||
new AttrD("min", true, "input","meter"),
|
||||
new AttrD("multiple", false, "input","select"),
|
||||
new AttrD("muted", false, "video","audio"),
|
||||
new AttrD("name", true, "button","fieldset","form","iframe","input","map","meta","object","output","param","select","slot","textarea"),
|
||||
new AttrD("novalidate", false, "form"),
|
||||
new AttrD("onabort", true, "audio","embed","img","object","video"),
|
||||
new AttrD("onafterprint", true, "body"),
|
||||
new AttrD("onbeforeprint", true, "body"),
|
||||
new AttrD("onbeforeunload", true, "body"),
|
||||
//new AttrD("onblur"), global attribute
|
||||
new AttrD("oncanplay", true, "audio","embed","object","video"),
|
||||
new AttrD("oncanplaythrough", true, "audio","video"),
|
||||
/* a bunch of event attributes that are on all visible elements (so should be in Tag.java)
|
||||
"onchange",
|
||||
"onclick",
|
||||
"oncontextmenu",
|
||||
"oncopy",
|
||||
*/
|
||||
new AttrD("oncuechange", true, "track"),
|
||||
/*
|
||||
"oncut",
|
||||
...
|
||||
"ondrop",
|
||||
*/
|
||||
new AttrD("ondurationchange", true, "audio","video"),
|
||||
new AttrD("onemptied", true, "audio","video"),
|
||||
new AttrD("onended", true, "audio","video"),
|
||||
new AttrD("onerror", true, "audio","body","embed","img","object","script","style","video"),
|
||||
//new AttrD("onfocus"),// global attribute
|
||||
new AttrD("onhashchange", true, "body"),
|
||||
// ... a bunch of event attributes visible on all elements
|
||||
new AttrD("onload", true, "body","iframe","img","input","link","script","style"),
|
||||
new AttrD("onloadeddata", true, "audio","video"),
|
||||
new AttrD("onloadedmetadata", true, "audio","video"),
|
||||
new AttrD("onloadstart", true, "audio","video"),
|
||||
// ... a bunch of event attributes visible on all elements
|
||||
new AttrD("onoffline", true, "body"),
|
||||
new AttrD("ononline", true, "body"),
|
||||
new AttrD("onpagehide", true, "body"),
|
||||
new AttrD("onpageshow", true, "body"),
|
||||
//new AttrD("onpaste"),// global attribute
|
||||
new AttrD("onpause", true, "audio","video"),
|
||||
new AttrD("onplay", true, "audio","video"),
|
||||
new AttrD("onplaying", true, "audio","video"),
|
||||
new AttrD("onpopstate", true, "body"),
|
||||
new AttrD("onprogress", true, "audio","video"),
|
||||
new AttrD("onratechange", true, "audio","video"),
|
||||
new AttrD("onreset", true, "form"),
|
||||
new AttrD("onresize", true, "body"),
|
||||
//new AttrD("onscroll"), //global attribute
|
||||
new AttrD("onsearch", true, "input"),
|
||||
new AttrD("onseeked", true, "audio","video"),
|
||||
new AttrD("onseeking", true, "audio","video"),
|
||||
//new AttrD("onselect"), //global attribute
|
||||
new AttrD("onstalled", true, "audio","video"),
|
||||
new AttrD("onstorage", true, "body"),
|
||||
new AttrD("onsubmit", true, "form"),
|
||||
new AttrD("onsuspend", true, "audio","video"),
|
||||
new AttrD("ontimeupdate", true, "audio","video"),
|
||||
new AttrD("ontoggle", true, "details"),
|
||||
new AttrD("onunload", true, "body"),
|
||||
new AttrD("onvolumechanged", true, "audio","video"),
|
||||
new AttrD("onwaiting", true, "audio","video"),
|
||||
//new AttrD("onwheel"), //global attribute
|
||||
new AttrD("open", false, "details"),
|
||||
new AttrD("optimum", true, "meter"),
|
||||
new AttrD("pattern", true, "input"),
|
||||
new AttrD("placeholder", true, "input","textarea"),
|
||||
new AttrD("poster", true, "video"),
|
||||
new AttrD("preload", true, "audio","video"),
|
||||
new AttrD("readonly", false, "input","textarea"),
|
||||
new AttrD("rel", true, "a","area","form","link"),
|
||||
new AttrD("required", false, "input","select","textarea"),
|
||||
new AttrD("reversed", false, "ol"),
|
||||
new AttrD("rows", true, "textarea"),
|
||||
new AttrD("rowspan", true, "td","th"),
|
||||
new AttrD("sandbox", false, "iframe"),
|
||||
new AttrD("scope", true, "th"),
|
||||
new AttrD("selected", false, "option"),
|
||||
new AttrD("shape", true, "area"),
|
||||
new AttrD("size", true, "input","select"),
|
||||
new AttrD("sizes", true, "img","link","source"),
|
||||
new AttrD("span", true, "col","colgroup"),
|
||||
//new AttrD("spellcheck"), //global attribute
|
||||
new AttrD("src", true, "audio","embed","iframe","img","input","script","source","track","video"),
|
||||
new AttrD("srcdoc", true, "iframe"),
|
||||
new AttrD("srclang", true, "track"),
|
||||
new AttrD("srcset", true, "img","source"),
|
||||
new AttrD("start", true, "ol"),
|
||||
new AttrD("step", true, "input"),
|
||||
//new AttrD("style"), //global attribute
|
||||
//new AttrD("tabindex"), //global attribute
|
||||
new AttrD("target", true, "a","area","base","form"),
|
||||
//new AttrD("title"), //global attribute
|
||||
//new AttrD("translate"),// global attribute
|
||||
new AttrD("type", true, "a","button","embed","input","link","menu","object","script","source","style"),
|
||||
new AttrD("usemap", true, "img","object"),
|
||||
new AttrD("value", true, "button","data","input","li","option","meter","progress","param"),
|
||||
new AttrD("width", true, "canvas","embed","iframe","img","input","object","video"),
|
||||
new AttrD("wrap", true, "textarea")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.j2html.codegen.wattsi;
|
||||
|
||||
public interface AttributeDefinition {
|
||||
|
||||
String name();
|
||||
|
||||
boolean appliesTo(ElementDefinition element);
|
||||
|
||||
boolean isObsolete();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.j2html.codegen.wattsi;
|
||||
|
||||
public interface ElementDefinition {
|
||||
|
||||
String name();
|
||||
|
||||
boolean isSelfClosing();
|
||||
|
||||
boolean isObsolete();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package com.j2html.codegen.wattsi;
|
||||
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.nodes.Node;
|
||||
import org.jsoup.nodes.TextNode;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
public class WattsiSource {
|
||||
|
||||
private final Document doc;
|
||||
|
||||
private final Set<Reference> obsolete = new HashSet<>();
|
||||
|
||||
public WattsiSource(Document doc) {
|
||||
this.doc = doc;
|
||||
|
||||
// Find where obsolete elements are defined or referenced.
|
||||
Elements obsoleteElements = doc.select("p:contains(Elements in the following list are entirely obsolete) + dl");
|
||||
|
||||
// Convert definitions into references to record obsolete elements.
|
||||
obsoleteElements.select("dt > dfn[element]")
|
||||
.stream()
|
||||
.map(WattsiElement::new)
|
||||
.map(WattsiElement::reference)
|
||||
.forEach(obsolete::add);
|
||||
|
||||
// Extract references to record obsolete elements.
|
||||
obsoleteElements.select("dt > code")
|
||||
.stream()
|
||||
.map(Element::childNodes)
|
||||
.map(Reference::from)
|
||||
.forEach(obsolete::add);
|
||||
|
||||
// Find where obsolete attributes are defined or referenced.
|
||||
Elements obsoleteAttributes = doc.select("p:contains(The following attributes are obsolete) + dl");
|
||||
|
||||
// Convert definitions into references to record obsolete attributes.
|
||||
obsoleteAttributes.select("dt > dfn[element-attr]").stream()
|
||||
.map(WattsiAttribute::new)
|
||||
.map(WattsiAttribute::reference)
|
||||
.forEach(obsolete::add);
|
||||
|
||||
// System.out.println(obsoleteAttributes.select("dt"));
|
||||
|
||||
// obsoleteAttributes.select("dt > code").stream()
|
||||
// .map(Element::childNodes)
|
||||
// .map(Reference::from)
|
||||
// .forEach(System.err::println);
|
||||
|
||||
// System.out.println(
|
||||
// doc.select("dfn[obsolete]")
|
||||
// );
|
||||
}
|
||||
|
||||
public List<ElementDefinition> elementDefinitions() {
|
||||
return doc.select("dfn[element]").stream()
|
||||
.map(WattsiElement::new)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
public List<AttributeDefinition> attributeDefinitions() {
|
||||
return doc.select("dfn[element-attr]").stream()
|
||||
.map(WattsiAttribute::new)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
public class WattsiElement implements ElementDefinition {
|
||||
private final Element dfn;
|
||||
|
||||
WattsiElement(Element dfn) {
|
||||
if (!"dfn".equals(dfn.tagName())) {
|
||||
throw new IllegalArgumentException("Element cannot be defined from: " + dfn);
|
||||
}
|
||||
if (!dfn.hasAttr("element")) {
|
||||
throw new IllegalArgumentException("Does not define an element: " + dfn);
|
||||
}
|
||||
if (dfn.childrenSize() != 1) {
|
||||
throw new IllegalArgumentException("Element cannot have multiple definitions: " + dfn);
|
||||
}
|
||||
this.dfn = dfn;
|
||||
}
|
||||
|
||||
private Reference reference() {
|
||||
return Reference.from(dfn.childNodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
if (dfn.hasAttr("data-x")) {
|
||||
return dfn.attr("data-x");
|
||||
}
|
||||
|
||||
return Reference.from(dfn.childNodes()).key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelfClosing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObsolete() {
|
||||
return obsolete.contains(reference());
|
||||
}
|
||||
}
|
||||
|
||||
public class WattsiAttribute implements AttributeDefinition {
|
||||
private final Element dfn;
|
||||
|
||||
WattsiAttribute(Element dfn) {
|
||||
if (!"dfn".equals(dfn.tagName())) {
|
||||
throw new IllegalArgumentException("Attribute cannot be defined from: " + dfn);
|
||||
}
|
||||
if (!dfn.hasAttr("element-attr")) {
|
||||
throw new IllegalArgumentException("Does not define an attribute: " + dfn);
|
||||
}
|
||||
if (dfn.childrenSize() != 1) {
|
||||
throw new IllegalArgumentException("Attribute cannot have multiple definitions: " + dfn);
|
||||
}
|
||||
|
||||
this.dfn = dfn;
|
||||
}
|
||||
|
||||
private Reference reference() {
|
||||
return Reference.from(dfn.childNodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return reference().text;
|
||||
}
|
||||
|
||||
private List<String> targets() {
|
||||
if (dfn.hasAttr("for")) {
|
||||
return Arrays.asList(dfn.attr("for").trim().split(","));
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appliesTo(ElementDefinition element) {
|
||||
return targets().contains(element.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObsolete() {
|
||||
return obsolete.contains(reference());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Reference {
|
||||
private final String key;
|
||||
private final String text;
|
||||
|
||||
Reference(String key, String text) {
|
||||
this.key = key;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "[" + text + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Reference reference = (Reference) o;
|
||||
return key.equals(reference.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(key);
|
||||
}
|
||||
|
||||
public static Reference from(List<Node> nodes) {
|
||||
if (nodes.stream().allMatch(n -> n instanceof TextNode)) {
|
||||
String txt = nodes.stream()
|
||||
.map(n -> (TextNode) n)
|
||||
.map(TextNode::text)
|
||||
.collect(Collectors.joining(" "));
|
||||
return new Reference(txt, txt);
|
||||
}
|
||||
|
||||
for (Node node : nodes) {
|
||||
if (node instanceof Element) {
|
||||
Element element = (Element) node;
|
||||
if (element.is("code") || element.is("span")) {
|
||||
if (element.hasAttr("data-x")) {
|
||||
return new Reference(element.attr("data-x").toLowerCase(), element.text());
|
||||
} else {
|
||||
return new Reference(element.text().toLowerCase(), element.text());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
j2html-codegen/src/test/java/com/j2html/codegen/AppTest.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class AppTest
|
||||
{
|
||||
@Test
|
||||
public void shouldAnswerWithTrue()
|
||||
{
|
||||
//dummy, just to conform to the default mvn
|
||||
//directory layout
|
||||
assertTrue( true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import com.j2html.codegen.generators.TagCreatorCodeGenerator;
|
||||
import com.j2html.codegen.wattsi.ElementDefinition;
|
||||
import com.j2html.codegen.wattsi.WattsiSource;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class CodeGeneratorComplianceTests {
|
||||
|
||||
private WattsiSource specification;
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
Path source = Paths.get("src","test","resources","2022-01.wattsi");
|
||||
Document doc = Jsoup.parse(source.toFile(), "UTF-8", "https://html.spec.whatwg.org/");
|
||||
specification = new WattsiSource(doc);
|
||||
}
|
||||
|
||||
private Set<String> generatedElements(){
|
||||
Set<String> elements = new HashSet<>();
|
||||
elements.addAll(TagCreatorCodeGenerator.emptyTags());
|
||||
elements.addAll(TagCreatorCodeGenerator.containerTags());
|
||||
return elements;
|
||||
}
|
||||
|
||||
private Set<String> specifiedElements(WattsiSource source){
|
||||
Set<String> elements = new HashSet<>();
|
||||
for(ElementDefinition element : source.elementDefinitions()){
|
||||
elements.add(element.name());
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// TODO restore this test once a policy has been determined for obsolete elements.
|
||||
public void all_wattsi_elements_are_defined_in_the_code_generator() {
|
||||
Set<String> generated = generatedElements();
|
||||
|
||||
List<String> undefined = specification.elementDefinitions().stream()
|
||||
.filter(element -> !element.isObsolete())
|
||||
.filter(element -> !generated.contains(element.name()))
|
||||
.map(ElementDefinition::name)
|
||||
.collect(toList());
|
||||
|
||||
assertEquals("HTML elements are missing", emptyList(), undefined);
|
||||
// Currently missing (and mostly deprecated):
|
||||
// hgroup
|
||||
}
|
||||
|
||||
@Test
|
||||
public void only_wattsi_elements_are_defined_in_the_code_generator(){
|
||||
Set<String> specified = specifiedElements(specification);
|
||||
|
||||
List<String> invalid = generatedElements().stream()
|
||||
.filter(element -> !specified.contains(element))
|
||||
.collect(toList());
|
||||
|
||||
assertEquals("HTML elements are invalid", emptyList(), invalid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.j2html.codegen;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class ParserTest {
|
||||
|
||||
private void verifyParsing(String txt, Consumer<Parser.Listener> checks) {
|
||||
Parser.Listener listener = mock(Parser.Listener.class);
|
||||
Parser.parse(txt, listener);
|
||||
checks.accept(listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void an_empty_input_has_no_events() {
|
||||
verifyParsing("", listener -> {
|
||||
verifyNoInteractions(listener);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whitespace_has_no_events() {
|
||||
verifyParsing(" \t\t\t\t", listener -> {
|
||||
verifyNoInteractions(listener);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void commented_lines_are_signaled() {
|
||||
verifyParsing("#Comment 1.\n# Comment B?", listener -> {
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).lineCommented(1, "#Comment 1.");
|
||||
order.verify(listener).lineCommented(2, "# Comment B?");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void node_definitions_are_signaled() {
|
||||
verifyParsing("ELEMENT[a]\nEMPTY-ELEMENT[b]\nBOOLEAN[c]\nONOFF[d]\nSTRING[e]", listener -> {
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).elementDefined(1, "a");
|
||||
order.verify(listener).emptyElementDefined(2, "b");
|
||||
order.verify(listener).booleanDefined(3, "c");
|
||||
order.verify(listener).onOffDefined(4, "d");
|
||||
order.verify(listener).stringDefined(5, "e");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attribute_definitions_are_signaled() {
|
||||
verifyParsing("ATTRIBUTE[a:b]", listener -> {
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).attributeDefined(1, "a", "b");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalid_lines_are_signaled() {
|
||||
verifyParsing("lol, I dunno!\nIt Broke...", listener -> {
|
||||
InOrder order = inOrder(listener);
|
||||
order.verify(listener).invalidLine(1, "lol, I dunno!");
|
||||
order.verify(listener).invalidLine(2, "It Broke...");
|
||||
});
|
||||
}
|
||||
}
|
||||
128553
j2html-codegen/src/test/resources/2022-01.wattsi
Normal file
622
j2html-codegen/src/test/resources/html.model
Normal file
@@ -0,0 +1,622 @@
|
||||
EMPTY-ELEMENT[area]
|
||||
EMPTY-ELEMENT[base]
|
||||
EMPTY-ELEMENT[br]
|
||||
EMPTY-ELEMENT[col]
|
||||
EMPTY-ELEMENT[embed]
|
||||
EMPTY-ELEMENT[hr]
|
||||
EMPTY-ELEMENT[img]
|
||||
EMPTY-ELEMENT[input]
|
||||
EMPTY-ELEMENT[keygen]
|
||||
EMPTY-ELEMENT[link]
|
||||
EMPTY-ELEMENT[meta]
|
||||
EMPTY-ELEMENT[param]
|
||||
EMPTY-ELEMENT[source]
|
||||
EMPTY-ELEMENT[track]
|
||||
EMPTY-ELEMENT[wbr]
|
||||
|
||||
ELEMENT[a]
|
||||
ELEMENT[abbr]
|
||||
ELEMENT[address]
|
||||
ELEMENT[article]
|
||||
ELEMENT[aside]
|
||||
ELEMENT[audio]
|
||||
ELEMENT[b]
|
||||
ELEMENT[bdi]
|
||||
ELEMENT[bdo]
|
||||
ELEMENT[blockquote]
|
||||
ELEMENT[body]
|
||||
ELEMENT[button]
|
||||
ELEMENT[canvas]
|
||||
ELEMENT[caption]
|
||||
ELEMENT[cite]
|
||||
ELEMENT[code]
|
||||
ELEMENT[colgroup]
|
||||
ELEMENT[data]
|
||||
ELEMENT[datalist]
|
||||
ELEMENT[dd]
|
||||
ELEMENT[del]
|
||||
ELEMENT[details]
|
||||
ELEMENT[dfn]
|
||||
ELEMENT[dialog]
|
||||
ELEMENT[div]
|
||||
ELEMENT[dl]
|
||||
ELEMENT[dt]
|
||||
ELEMENT[em]
|
||||
ELEMENT[fieldset]
|
||||
ELEMENT[figcaption]
|
||||
ELEMENT[figure]
|
||||
ELEMENT[footer]
|
||||
ELEMENT[form]
|
||||
ELEMENT[h1]
|
||||
ELEMENT[h2]
|
||||
ELEMENT[h3]
|
||||
ELEMENT[h4]
|
||||
ELEMENT[h5]
|
||||
ELEMENT[h6]
|
||||
ELEMENT[head]
|
||||
ELEMENT[header]
|
||||
ELEMENT[html]
|
||||
ELEMENT[i]
|
||||
ELEMENT[iframe]
|
||||
ELEMENT[ins]
|
||||
ELEMENT[kbd]
|
||||
ELEMENT[label]
|
||||
ELEMENT[legend]
|
||||
ELEMENT[li]
|
||||
ELEMENT[main]
|
||||
ELEMENT[map]
|
||||
ELEMENT[mark]
|
||||
ELEMENT[menu]
|
||||
ELEMENT[menuitem]
|
||||
ELEMENT[meter]
|
||||
ELEMENT[nav]
|
||||
ELEMENT[noscript]
|
||||
ELEMENT[object]
|
||||
ELEMENT[ol]
|
||||
ELEMENT[optgroup]
|
||||
ELEMENT[option]
|
||||
ELEMENT[output]
|
||||
ELEMENT[p]
|
||||
ELEMENT[picture]
|
||||
ELEMENT[pre]
|
||||
ELEMENT[progress]
|
||||
ELEMENT[q]
|
||||
ELEMENT[rp]
|
||||
ELEMENT[rt]
|
||||
ELEMENT[ruby]
|
||||
ELEMENT[s]
|
||||
ELEMENT[samp]
|
||||
ELEMENT[script]
|
||||
ELEMENT[section]
|
||||
ELEMENT[select]
|
||||
ELEMENT[slot]
|
||||
ELEMENT[small]
|
||||
ELEMENT[span]
|
||||
ELEMENT[strong]
|
||||
ELEMENT[style]
|
||||
ELEMENT[sub]
|
||||
ELEMENT[summary]
|
||||
ELEMENT[sup]
|
||||
ELEMENT[table]
|
||||
ELEMENT[tbody]
|
||||
ELEMENT[td]
|
||||
ELEMENT[template]
|
||||
ELEMENT[textarea]
|
||||
ELEMENT[tfoot]
|
||||
ELEMENT[th]
|
||||
ELEMENT[thead]
|
||||
ELEMENT[time]
|
||||
ELEMENT[title]
|
||||
ELEMENT[tr]
|
||||
ELEMENT[u]
|
||||
ELEMENT[ul]
|
||||
ELEMENT[var]
|
||||
ELEMENT[video]
|
||||
|
||||
STRING[accept]
|
||||
ATTRIBUTE[input:accept]
|
||||
|
||||
STRING[action]
|
||||
ATTRIBUTE[form:action]
|
||||
|
||||
STRING[alt]
|
||||
ATTRIBUTE[area:alt]
|
||||
ATTRIBUTE[img:alt]
|
||||
ATTRIBUTE[input:alt]
|
||||
|
||||
BOOLEAN[async]
|
||||
ATTRIBUTE[script:async]
|
||||
|
||||
ONOFF[autocomplete]
|
||||
ATTRIBUTE[form:autocomplete]
|
||||
ATTRIBUTE[input:autocomplete]
|
||||
|
||||
BOOLEAN[autofocus]
|
||||
ATTRIBUTE[button:autofocus]
|
||||
ATTRIBUTE[input:autofocus]
|
||||
ATTRIBUTE[select:autofocus]
|
||||
ATTRIBUTE[textarea:autofocus]
|
||||
|
||||
BOOLEAN[autoplay]
|
||||
ATTRIBUTE[audio:autoplay]
|
||||
ATTRIBUTE[video:autoplay]
|
||||
|
||||
STRING[charset]
|
||||
ATTRIBUTE[meta:charset]
|
||||
ATTRIBUTE[script:charset]
|
||||
|
||||
BOOLEAN[checked]
|
||||
ATTRIBUTE[input:checked]
|
||||
|
||||
STRING[cite]
|
||||
ATTRIBUTE[blockquote:cite]
|
||||
ATTRIBUTE[del:cite]
|
||||
ATTRIBUTE[ins:cite]
|
||||
ATTRIBUTE[q:cite]
|
||||
|
||||
STRING[cols]
|
||||
ATTRIBUTE[textarea:cols]
|
||||
|
||||
STRING[colspan]
|
||||
ATTRIBUTE[td:colspan]
|
||||
ATTRIBUTE[th:colspan]
|
||||
|
||||
STRING[content]
|
||||
ATTRIBUTE[meta:content]
|
||||
|
||||
BOOLEAN[controls]
|
||||
ATTRIBUTE[audio:controls]
|
||||
ATTRIBUTE[video:controls]
|
||||
|
||||
STRING[coords]
|
||||
ATTRIBUTE[area:coords]
|
||||
|
||||
STRING[data]
|
||||
ATTRIBUTE[object:data]
|
||||
|
||||
STRING[datetime]
|
||||
ATTRIBUTE[del:datetime]
|
||||
ATTRIBUTE[ins:datetime]
|
||||
ATTRIBUTE[time:datetime]
|
||||
|
||||
BOOLEAN[default]
|
||||
ATTRIBUTE[track:default]
|
||||
|
||||
BOOLEAN[defer]
|
||||
ATTRIBUTE[script:defer]
|
||||
|
||||
STRING[dirname]
|
||||
ATTRIBUTE[input:dirname]
|
||||
ATTRIBUTE[textarea:dirname]
|
||||
|
||||
BOOLEAN[disabled]
|
||||
ATTRIBUTE[button:disabled]
|
||||
ATTRIBUTE[fieldset:disabled]
|
||||
ATTRIBUTE[input:disabled]
|
||||
ATTRIBUTE[optgroup:disabled]
|
||||
ATTRIBUTE[option:disabled]
|
||||
ATTRIBUTE[select:disabled]
|
||||
ATTRIBUTE[textarea:disabled]
|
||||
|
||||
BOOLEAN[download]
|
||||
ATTRIBUTE[a:download]
|
||||
ATTRIBUTE[area:download]
|
||||
|
||||
STRING[enctype]
|
||||
ATTRIBUTE[form:enctype]
|
||||
|
||||
STRING[for]
|
||||
ATTRIBUTE[label:for]
|
||||
ATTRIBUTE[output:for]
|
||||
|
||||
STRING[form]
|
||||
ATTRIBUTE[button:form]
|
||||
ATTRIBUTE[fieldset:form]
|
||||
ATTRIBUTE[input:form]
|
||||
ATTRIBUTE[label:form]
|
||||
ATTRIBUTE[meter:form]
|
||||
ATTRIBUTE[object:form]
|
||||
ATTRIBUTE[output:form]
|
||||
ATTRIBUTE[select:form]
|
||||
ATTRIBUTE[textarea:form]
|
||||
|
||||
STRING[formaction]
|
||||
ATTRIBUTE[button:formaction]
|
||||
ATTRIBUTE[input:formaction]
|
||||
|
||||
STRING[headers]
|
||||
ATTRIBUTE[td:headers]
|
||||
ATTRIBUTE[th:headers]
|
||||
|
||||
STRING[height]
|
||||
ATTRIBUTE[canvas:height]
|
||||
ATTRIBUTE[embed:height]
|
||||
ATTRIBUTE[iframe:height]
|
||||
ATTRIBUTE[img:height]
|
||||
ATTRIBUTE[input:height]
|
||||
ATTRIBUTE[object:height]
|
||||
ATTRIBUTE[video:height]
|
||||
|
||||
STRING[high]
|
||||
ATTRIBUTE[meter:high]
|
||||
|
||||
STRING[href]
|
||||
ATTRIBUTE[a:href]
|
||||
ATTRIBUTE[area:href]
|
||||
ATTRIBUTE[base:href]
|
||||
ATTRIBUTE[link:href]
|
||||
|
||||
STRING[hreflang]
|
||||
ATTRIBUTE[a:hreflang]
|
||||
ATTRIBUTE[area:hreflang]
|
||||
ATTRIBUTE[link:hreflang]
|
||||
|
||||
BOOLEAN[ismap]
|
||||
ATTRIBUTE[img:ismap]
|
||||
|
||||
STRING[kind]
|
||||
ATTRIBUTE[track:kind]
|
||||
|
||||
STRING[label]
|
||||
ATTRIBUTE[track:label]
|
||||
ATTRIBUTE[option:label]
|
||||
ATTRIBUTE[optgroup:label]
|
||||
|
||||
STRING[list]
|
||||
ATTRIBUTE[input:list]
|
||||
|
||||
BOOLEAN[loop]
|
||||
ATTRIBUTE[audio:loop]
|
||||
ATTRIBUTE[video:loop]
|
||||
|
||||
STRING[low]
|
||||
ATTRIBUTE[meter:low]
|
||||
|
||||
STRING[max]
|
||||
ATTRIBUTE[input:max]
|
||||
ATTRIBUTE[meter:max]
|
||||
ATTRIBUTE[progress:max]
|
||||
|
||||
STRING[maxlength]
|
||||
ATTRIBUTE[input:maxlength]
|
||||
ATTRIBUTE[textarea:maxlength]
|
||||
|
||||
STRING[media]
|
||||
ATTRIBUTE[a:media]
|
||||
ATTRIBUTE[area:media]
|
||||
ATTRIBUTE[link:media]
|
||||
ATTRIBUTE[source:media]
|
||||
ATTRIBUTE[style:media]
|
||||
|
||||
STRING[method]
|
||||
ATTRIBUTE[form:method]
|
||||
|
||||
STRING[min]
|
||||
ATTRIBUTE[input:min]
|
||||
ATTRIBUTE[meter:min]
|
||||
|
||||
BOOLEAN[multiple]
|
||||
ATTRIBUTE[input:multiple]
|
||||
ATTRIBUTE[select:multiple]
|
||||
|
||||
BOOLEAN[muted]
|
||||
ATTRIBUTE[video:muted]
|
||||
ATTRIBUTE[audio:muted]
|
||||
|
||||
STRING[name]
|
||||
ATTRIBUTE[button:name]
|
||||
ATTRIBUTE[fieldset:name]
|
||||
ATTRIBUTE[form:name]
|
||||
ATTRIBUTE[iframe:name]
|
||||
ATTRIBUTE[input:name]
|
||||
ATTRIBUTE[map:name]
|
||||
ATTRIBUTE[meta:name]
|
||||
ATTRIBUTE[object:name]
|
||||
ATTRIBUTE[output:name]
|
||||
ATTRIBUTE[param:name]
|
||||
ATTRIBUTE[select:name]
|
||||
ATTRIBUTE[slot:name]
|
||||
ATTRIBUTE[textarea:name]
|
||||
|
||||
BOOLEAN[novalidate]
|
||||
ATTRIBUTE[form:novalidate]
|
||||
|
||||
STRING[onabort]
|
||||
ATTRIBUTE[audio:onabort]
|
||||
ATTRIBUTE[embed:onabort]
|
||||
ATTRIBUTE[img:onabort]
|
||||
ATTRIBUTE[object:onabort]
|
||||
ATTRIBUTE[video:onabort]
|
||||
|
||||
STRING[onafterprint]
|
||||
ATTRIBUTE[body:onafterprint]
|
||||
|
||||
STRING[onbeforeprint]
|
||||
ATTRIBUTE[body:onbeforeprint]
|
||||
|
||||
STRING[onbeforeunload]
|
||||
ATTRIBUTE[body:onbeforeunload]
|
||||
|
||||
STRING[oncanplay]
|
||||
ATTRIBUTE[audio:oncanplay]
|
||||
ATTRIBUTE[embed:oncanplay]
|
||||
ATTRIBUTE[object:oncanplay]
|
||||
ATTRIBUTE[video:oncanplay]
|
||||
|
||||
STRING[oncanplaythrough]
|
||||
ATTRIBUTE[audio:oncanplaythrough]
|
||||
ATTRIBUTE[video:oncanplaythrough]
|
||||
|
||||
STRING[oncuechange]
|
||||
ATTRIBUTE[track:oncuechange]
|
||||
|
||||
STRING[ondurationchange]
|
||||
ATTRIBUTE[audio:ondurationchange]
|
||||
ATTRIBUTE[video:ondurationchange]
|
||||
|
||||
STRING[onemptied]
|
||||
ATTRIBUTE[audio:onemptied]
|
||||
ATTRIBUTE[video:onemptied]
|
||||
|
||||
STRING[onended]
|
||||
ATTRIBUTE[audio:onended]
|
||||
ATTRIBUTE[video:onended]
|
||||
|
||||
STRING[onerror]
|
||||
ATTRIBUTE[audio:onerror]
|
||||
ATTRIBUTE[body:onerror]
|
||||
ATTRIBUTE[embed:onerror]
|
||||
ATTRIBUTE[img:onerror]
|
||||
ATTRIBUTE[object:onerror]
|
||||
ATTRIBUTE[script:onerror]
|
||||
ATTRIBUTE[style:onerror]
|
||||
ATTRIBUTE[video:onerror]
|
||||
|
||||
STRING[onhashchange]
|
||||
ATTRIBUTE[body:onhashchange]
|
||||
|
||||
STRING[onload]
|
||||
ATTRIBUTE[body:onload]
|
||||
ATTRIBUTE[iframe:onload]
|
||||
ATTRIBUTE[img:onload]
|
||||
ATTRIBUTE[input:onload]
|
||||
ATTRIBUTE[link:onload]
|
||||
ATTRIBUTE[script:onload]
|
||||
ATTRIBUTE[style:onload]
|
||||
|
||||
STRING[onloadeddata]
|
||||
ATTRIBUTE[audio:onloadeddata]
|
||||
ATTRIBUTE[video:onloadeddata]
|
||||
|
||||
STRING[onloadedmetadata]
|
||||
ATTRIBUTE[audio:onloadedmetadata]
|
||||
ATTRIBUTE[video:onloadedmetadata]
|
||||
|
||||
STRING[onloadstart]
|
||||
ATTRIBUTE[audio:onloadstart]
|
||||
ATTRIBUTE[video:onloadstart]
|
||||
|
||||
STRING[onoffline]
|
||||
ATTRIBUTE[body:onoffline]
|
||||
|
||||
STRING[ononline]
|
||||
ATTRIBUTE[body:ononline]
|
||||
|
||||
STRING[onpagehide]
|
||||
ATTRIBUTE[body:onpagehide]
|
||||
|
||||
STRING[onpageshow]
|
||||
ATTRIBUTE[body:onpageshow]
|
||||
|
||||
STRING[onpause]
|
||||
ATTRIBUTE[audio:onpause]
|
||||
ATTRIBUTE[video:onpause]
|
||||
|
||||
STRING[onplay]
|
||||
ATTRIBUTE[audio:onplay]
|
||||
ATTRIBUTE[video:onplay]
|
||||
|
||||
STRING[onplaying]
|
||||
ATTRIBUTE[audio:onplaying]
|
||||
ATTRIBUTE[video:onplaying]
|
||||
|
||||
STRING[onpopstate]
|
||||
ATTRIBUTE[body:onpopstate]
|
||||
|
||||
STRING[onprogress]
|
||||
ATTRIBUTE[audio:onprogress]
|
||||
ATTRIBUTE[video:onprogress]
|
||||
|
||||
STRING[onratechange]
|
||||
ATTRIBUTE[audio:onratechange]
|
||||
ATTRIBUTE[video:onratechange]
|
||||
|
||||
STRING[onreset]
|
||||
ATTRIBUTE[form:onreset]
|
||||
|
||||
STRING[onresize]
|
||||
ATTRIBUTE[body:onresize]
|
||||
|
||||
STRING[onsearch]
|
||||
ATTRIBUTE[input:onsearch]
|
||||
|
||||
STRING[onseeked]
|
||||
ATTRIBUTE[audio:onseeked]
|
||||
ATTRIBUTE[video:onseeked]
|
||||
|
||||
STRING[onseeking]
|
||||
ATTRIBUTE[audio:onseeking]
|
||||
ATTRIBUTE[video:onseeking]
|
||||
|
||||
STRING[onstalled]
|
||||
ATTRIBUTE[audio:onstalled]
|
||||
ATTRIBUTE[video:onstalled]
|
||||
|
||||
STRING[onstorage]
|
||||
ATTRIBUTE[body:onstorage]
|
||||
|
||||
STRING[onsubmit]
|
||||
ATTRIBUTE[form:onsubmit]
|
||||
|
||||
STRING[onsuspend]
|
||||
ATTRIBUTE[audio:onsuspend]
|
||||
ATTRIBUTE[video:onsuspend]
|
||||
|
||||
STRING[ontimeupdate]
|
||||
ATTRIBUTE[audio:ontimeupdate]
|
||||
ATTRIBUTE[video:ontimeupdate]
|
||||
|
||||
STRING[ontoggle]
|
||||
ATTRIBUTE[details:ontoggle]
|
||||
|
||||
STRING[onunload]
|
||||
ATTRIBUTE[body:onunload]
|
||||
|
||||
STRING[onvolumechanged]
|
||||
ATTRIBUTE[audio:onvolumechanged]
|
||||
ATTRIBUTE[video:onvolumechanged]
|
||||
|
||||
STRING[onwaiting]
|
||||
ATTRIBUTE[audio:onwaiting]
|
||||
ATTRIBUTE[video:onwaiting]
|
||||
|
||||
BOOLEAN[open]
|
||||
ATTRIBUTE[details:open]
|
||||
|
||||
STRING[optimum]
|
||||
ATTRIBUTE[meter:optimum]
|
||||
|
||||
STRING[pattern]
|
||||
ATTRIBUTE[input:pattern]
|
||||
|
||||
STRING[placeholder]
|
||||
ATTRIBUTE[input:placeholder]
|
||||
ATTRIBUTE[textarea:placeholder]
|
||||
|
||||
STRING[poster]
|
||||
ATTRIBUTE[video:poster]
|
||||
|
||||
STRING[preload]
|
||||
ATTRIBUTE[audio:preload]
|
||||
ATTRIBUTE[video:preload]
|
||||
|
||||
BOOLEAN[readonly]
|
||||
ATTRIBUTE[input:readonly]
|
||||
ATTRIBUTE[textarea:readonly]
|
||||
|
||||
STRING[rel]
|
||||
ATTRIBUTE[a:rel]
|
||||
ATTRIBUTE[area:rel]
|
||||
ATTRIBUTE[form:rel]
|
||||
ATTRIBUTE[link:rel]
|
||||
|
||||
BOOLEAN[required]
|
||||
ATTRIBUTE[input:required]
|
||||
ATTRIBUTE[select:required]
|
||||
ATTRIBUTE[textarea:required]
|
||||
|
||||
BOOLEAN[reversed]
|
||||
ATTRIBUTE[ol:reversed]
|
||||
|
||||
STRING[rows]
|
||||
ATTRIBUTE[textarea:rows]
|
||||
|
||||
STRING[rowspan]
|
||||
ATTRIBUTE[td:rowspan]
|
||||
ATTRIBUTE[th:rowspan]
|
||||
|
||||
BOOLEAN[sandbox]
|
||||
ATTRIBUTE[iframe:sandbox]
|
||||
|
||||
STRING[scope]
|
||||
ATTRIBUTE[th:scope]
|
||||
|
||||
BOOLEAN[selected]
|
||||
ATTRIBUTE[option:selected]
|
||||
|
||||
STRING[shape]
|
||||
ATTRIBUTE[area:shape]
|
||||
|
||||
STRING[size]
|
||||
ATTRIBUTE[input:size]
|
||||
ATTRIBUTE[select:size]
|
||||
|
||||
STRING[sizes]
|
||||
ATTRIBUTE[img:sizes]
|
||||
ATTRIBUTE[link:sizes]
|
||||
ATTRIBUTE[source:sizes]
|
||||
|
||||
STRING[span]
|
||||
ATTRIBUTE[col:span]
|
||||
ATTRIBUTE[colgroup:span]
|
||||
|
||||
STRING[src]
|
||||
ATTRIBUTE[audio:src]
|
||||
ATTRIBUTE[embed:src]
|
||||
ATTRIBUTE[iframe:src]
|
||||
ATTRIBUTE[img:src]
|
||||
ATTRIBUTE[input:src]
|
||||
ATTRIBUTE[script:src]
|
||||
ATTRIBUTE[source:src]
|
||||
ATTRIBUTE[track:src]
|
||||
ATTRIBUTE[video:src]
|
||||
|
||||
STRING[srcdoc]
|
||||
ATTRIBUTE[iframe:srcdoc]
|
||||
|
||||
STRING[srclang]
|
||||
ATTRIBUTE[track:srclang]
|
||||
|
||||
STRING[srcset]
|
||||
ATTRIBUTE[img:srcset]
|
||||
ATTRIBUTE[source:srcset]
|
||||
|
||||
STRING[start]
|
||||
ATTRIBUTE[ol:start]
|
||||
|
||||
STRING[step]
|
||||
ATTRIBUTE[input:step]
|
||||
|
||||
STRING[target]
|
||||
ATTRIBUTE[a:target]
|
||||
ATTRIBUTE[area:target]
|
||||
ATTRIBUTE[base:target]
|
||||
ATTRIBUTE[form:target]
|
||||
|
||||
STRING[type]
|
||||
ATTRIBUTE[a:type]
|
||||
ATTRIBUTE[button:type]
|
||||
ATTRIBUTE[embed:type]
|
||||
ATTRIBUTE[input:type]
|
||||
ATTRIBUTE[link:type]
|
||||
ATTRIBUTE[menu:type]
|
||||
ATTRIBUTE[object:type]
|
||||
ATTRIBUTE[script:type]
|
||||
ATTRIBUTE[source:type]
|
||||
ATTRIBUTE[style:type]
|
||||
|
||||
STRING[usemap]
|
||||
ATTRIBUTE[img:usemap]
|
||||
ATTRIBUTE[object:usemap]
|
||||
|
||||
STRING[value]
|
||||
ATTRIBUTE[button:value]
|
||||
ATTRIBUTE[data:value]
|
||||
ATTRIBUTE[input:value]
|
||||
ATTRIBUTE[li:value]
|
||||
ATTRIBUTE[option:value]
|
||||
ATTRIBUTE[meter:value]
|
||||
ATTRIBUTE[progress:value]
|
||||
ATTRIBUTE[param:value]
|
||||
|
||||
STRING[width]
|
||||
ATTRIBUTE[canvas:width]
|
||||
ATTRIBUTE[embed:width]
|
||||
ATTRIBUTE[iframe:width]
|
||||
ATTRIBUTE[img:width]
|
||||
ATTRIBUTE[input:width]
|
||||
ATTRIBUTE[object:width]
|
||||
ATTRIBUTE[video:width]
|
||||
|
||||
STRING[wrap]
|
||||
ATTRIBUTE[textarea:wrap]
|
||||
101
j2html-ext-mathml/.gitignore
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
### Eclipse ###
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
buildNumber.properties
|
||||
130
j2html-ext-mathml/pom.xml
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html-parent</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>j2html-ext-mathml</name>
|
||||
<artifactId>j2html-ext-mathml</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html-codegen-maven-plugin</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generate-source-files</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<modelFile>${project.basedir}/src/main/models/mathml.model</modelFile>
|
||||
<attributePackage>com.j2html.mathml.attributes</attributePackage>
|
||||
<tagPackage>com.j2html.mathml.tags</tagPackage>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default</id>
|
||||
<goals>
|
||||
<goal>perform</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<pomFileName>pom.xml</pomFileName>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Automatic-Module-Name>com.j2html</Automatic-Module-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!--plugin>
|
||||
<groupId>org.revapi</groupId>
|
||||
<artifactId>revapi-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<oldArtifacts>
|
||||
<artifact>com.j2html:j2html-ext-mathml:1.6.0</artifact>
|
||||
</oldArtifacts>
|
||||
<analysisConfiguration>
|
||||
<revapi.differences>
|
||||
<differences>
|
||||
|
||||
</differences>
|
||||
</revapi.differences>
|
||||
</analysisConfiguration>
|
||||
</configuration>
|
||||
</plugin-->
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
247
j2html-ext-mathml/src/main/java/com/j2html/mathml/MathML.java
Normal file
@@ -0,0 +1,247 @@
|
||||
package com.j2html.mathml;
|
||||
|
||||
import com.j2html.mathml.tags.*;
|
||||
import j2html.tags.DomContent;
|
||||
|
||||
public class MathML {
|
||||
|
||||
public static AnnotationTag annotation(String text) {
|
||||
return new AnnotationTag().withText(text);
|
||||
}
|
||||
|
||||
public static AnnotationTag annotation(DomContent... dc) {
|
||||
return new AnnotationTag().with(dc);
|
||||
}
|
||||
|
||||
public static MactionTag maction(String text) {
|
||||
return new MactionTag().withText(text);
|
||||
}
|
||||
|
||||
public static MactionTag maction(DomContent... dc) {
|
||||
return new MactionTag().with(dc);
|
||||
}
|
||||
|
||||
public static MathTag math(String text) {
|
||||
return new MathTag().withText(text);
|
||||
}
|
||||
|
||||
public static MathTag math(DomContent... dc) {
|
||||
return new MathTag().with(dc);
|
||||
}
|
||||
|
||||
public static MerrorTag merror(String text) {
|
||||
return new MerrorTag().withText(text);
|
||||
}
|
||||
|
||||
public static MerrorTag merror(DomContent... dc) {
|
||||
return new MerrorTag().with(dc);
|
||||
}
|
||||
|
||||
public static MfracTag mfrac(String text) {
|
||||
return new MfracTag().withText(text);
|
||||
}
|
||||
|
||||
public static MfracTag mfrac(DomContent... dc) {
|
||||
return new MfracTag().with(dc);
|
||||
}
|
||||
|
||||
public static MiTag mi(String text) {
|
||||
return new MiTag().withText(text);
|
||||
}
|
||||
|
||||
public static MiTag mi(DomContent... dc) {
|
||||
return new MiTag().with(dc);
|
||||
}
|
||||
|
||||
public static MmultiscriptsTag mmultiscripts(String text) {
|
||||
return new MmultiscriptsTag().withText(text);
|
||||
}
|
||||
|
||||
public static MmultiscriptsTag mmultiscripts(DomContent... dc) {
|
||||
return new MmultiscriptsTag().with(dc);
|
||||
}
|
||||
|
||||
public static MnTag mn(String text) {
|
||||
return new MnTag().withText(text);
|
||||
}
|
||||
|
||||
public static MnTag mn(DomContent... dc) {
|
||||
return new MnTag().with(dc);
|
||||
}
|
||||
|
||||
public static MoTag mo(String text) {
|
||||
return new MoTag().withText(text);
|
||||
}
|
||||
|
||||
public static MoTag mo(DomContent... dc) {
|
||||
return new MoTag().with(dc);
|
||||
}
|
||||
|
||||
public static MoverTag mover(String text) {
|
||||
return new MoverTag().withText(text);
|
||||
}
|
||||
|
||||
public static MoverTag mover(DomContent... dc) {
|
||||
return new MoverTag().with(dc);
|
||||
}
|
||||
|
||||
public static MpaddedTag mpadded(String text) {
|
||||
return new MpaddedTag().withText(text);
|
||||
}
|
||||
|
||||
public static MpaddedTag mpadded(DomContent... dc) {
|
||||
return new MpaddedTag().with(dc);
|
||||
}
|
||||
|
||||
public static MphantomTag mphantom(String text) {
|
||||
return new MphantomTag().withText(text);
|
||||
}
|
||||
|
||||
public static MphantomTag mphantom(DomContent... dc) {
|
||||
return new MphantomTag().with(dc);
|
||||
}
|
||||
|
||||
public static MprescriptsTag mprescripts(String text) {
|
||||
return new MprescriptsTag().withText(text);
|
||||
}
|
||||
|
||||
public static MprescriptsTag mprescripts(DomContent... dc) {
|
||||
return new MprescriptsTag().with(dc);
|
||||
}
|
||||
|
||||
public static MrootTag mroot(String text) {
|
||||
return new MrootTag().withText(text);
|
||||
}
|
||||
|
||||
public static MrootTag mroot(DomContent... dc) {
|
||||
return new MrootTag().with(dc);
|
||||
}
|
||||
|
||||
public static MrowTag mrow(String text) {
|
||||
return new MrowTag().withText(text);
|
||||
}
|
||||
|
||||
public static MrowTag mrow(DomContent... dc) {
|
||||
return new MrowTag().with(dc);
|
||||
}
|
||||
|
||||
public static MsTag ms(String text) {
|
||||
return new MsTag().withText(text);
|
||||
}
|
||||
|
||||
public static MsTag ms(DomContent... dc) {
|
||||
return new MsTag().with(dc);
|
||||
}
|
||||
|
||||
public static MspaceTag mspace(String text) {
|
||||
return new MspaceTag().withText(text);
|
||||
}
|
||||
|
||||
public static MspaceTag mspace(DomContent... dc) {
|
||||
return new MspaceTag().with(dc);
|
||||
}
|
||||
|
||||
public static MsqrtTag msqrt(String text) {
|
||||
return new MsqrtTag().withText(text);
|
||||
}
|
||||
|
||||
public static MsqrtTag msqrt(DomContent... dc) {
|
||||
return new MsqrtTag().with(dc);
|
||||
}
|
||||
|
||||
public static MstyleTag mstyle(String text) {
|
||||
return new MstyleTag().withText(text);
|
||||
}
|
||||
|
||||
public static MstyleTag mstyle(DomContent... dc) {
|
||||
return new MstyleTag().with(dc);
|
||||
}
|
||||
|
||||
public static MsubTag msub(String text) {
|
||||
return new MsubTag().withText(text);
|
||||
}
|
||||
|
||||
public static MsubTag msub(DomContent... dc) {
|
||||
return new MsubTag().with(dc);
|
||||
}
|
||||
|
||||
public static MsubsupTag msubsup(String text) {
|
||||
return new MsubsupTag().withText(text);
|
||||
}
|
||||
|
||||
public static MsubsupTag msubsup(DomContent... dc) {
|
||||
return new MsubsupTag().with(dc);
|
||||
}
|
||||
|
||||
public static MsupTag msup(String text) {
|
||||
return new MsupTag().withText(text);
|
||||
}
|
||||
|
||||
public static MsupTag msup(DomContent... dc) {
|
||||
return new MsupTag().with(dc);
|
||||
}
|
||||
|
||||
public static MtableTag mtable(String text) {
|
||||
return new MtableTag().withText(text);
|
||||
}
|
||||
|
||||
public static MtableTag mtable(DomContent... dc) {
|
||||
return new MtableTag().with(dc);
|
||||
}
|
||||
|
||||
public static MtdTag mtd(String text) {
|
||||
return new MtdTag().withText(text);
|
||||
}
|
||||
|
||||
public static MtdTag mtd(DomContent... dc) {
|
||||
return new MtdTag().with(dc);
|
||||
}
|
||||
|
||||
public static MtextTag mtext(String text) {
|
||||
return new MtextTag().withText(text);
|
||||
}
|
||||
|
||||
public static MtextTag mtext(DomContent... dc) {
|
||||
return new MtextTag().with(dc);
|
||||
}
|
||||
|
||||
public static MtrTag mtr(String text) {
|
||||
return new MtrTag().withText(text);
|
||||
}
|
||||
|
||||
public static MtrTag mtr(DomContent... dc) {
|
||||
return new MtrTag().with(dc);
|
||||
}
|
||||
|
||||
public static MunderTag munder(String text) {
|
||||
return new MunderTag().withText(text);
|
||||
}
|
||||
|
||||
public static MunderTag munder(DomContent... dc) {
|
||||
return new MunderTag().with(dc);
|
||||
}
|
||||
|
||||
public static MunderoverTag munderover(String text) {
|
||||
return new MunderoverTag().withText(text);
|
||||
}
|
||||
|
||||
public static MunderoverTag munderover(DomContent... dc) {
|
||||
return new MunderoverTag().with(dc);
|
||||
}
|
||||
|
||||
public static NoneTag none(String text) {
|
||||
return new NoneTag().withText(text);
|
||||
}
|
||||
|
||||
public static NoneTag none(DomContent... dc) {
|
||||
return new NoneTag().with(dc);
|
||||
}
|
||||
|
||||
public static SemanticsTag semantics(String text) {
|
||||
return new SemanticsTag().withText(text);
|
||||
}
|
||||
|
||||
public static SemanticsTag semantics(DomContent... dc) {
|
||||
return new SemanticsTag().with(dc);
|
||||
}
|
||||
}
|
||||
254
j2html-ext-mathml/src/main/models/mathml.model
Normal file
@@ -0,0 +1,254 @@
|
||||
ELEMENT[annotation]
|
||||
ELEMENT[maction]
|
||||
ELEMENT[math]
|
||||
ELEMENT[merror]
|
||||
ELEMENT[mfrac]
|
||||
ELEMENT[mi]
|
||||
ELEMENT[mmultiscripts]
|
||||
ELEMENT[mn]
|
||||
ELEMENT[mo]
|
||||
ELEMENT[mover]
|
||||
ELEMENT[mpadded]
|
||||
ELEMENT[mphantom]
|
||||
ELEMENT[mprescripts]
|
||||
ELEMENT[mroot]
|
||||
ELEMENT[mrow]
|
||||
ELEMENT[ms]
|
||||
ELEMENT[mspace]
|
||||
ELEMENT[msqrt]
|
||||
ELEMENT[mstyle]
|
||||
ELEMENT[msub]
|
||||
ELEMENT[msubsup]
|
||||
ELEMENT[msup]
|
||||
ELEMENT[mtable]
|
||||
ELEMENT[mtd]
|
||||
ELEMENT[mtext]
|
||||
ELEMENT[mtr]
|
||||
ELEMENT[munder]
|
||||
ELEMENT[munderover]
|
||||
ELEMENT[none]
|
||||
ELEMENT[semantics]
|
||||
|
||||
BOOLEAN[displaystyle]
|
||||
ATTRIBUTE[annotation:displaystyle]
|
||||
ATTRIBUTE[maction:displaystyle]
|
||||
ATTRIBUTE[math:displaystyle]
|
||||
ATTRIBUTE[merror:displaystyle]
|
||||
ATTRIBUTE[mfrac:displaystyle]
|
||||
ATTRIBUTE[mi:displaystyle]
|
||||
ATTRIBUTE[mmultiscripts:displaystyle]
|
||||
ATTRIBUTE[mn:displaystyle]
|
||||
ATTRIBUTE[mo:displaystyle]
|
||||
ATTRIBUTE[mover:displaystyle]
|
||||
ATTRIBUTE[mpadded:displaystyle]
|
||||
ATTRIBUTE[mphantom:displaystyle]
|
||||
ATTRIBUTE[mprescripts:displaystyle]
|
||||
ATTRIBUTE[mroot:displaystyle]
|
||||
ATTRIBUTE[mrow:displaystyle]
|
||||
ATTRIBUTE[ms:displaystyle]
|
||||
ATTRIBUTE[mspace:displaystyle]
|
||||
ATTRIBUTE[msqrt:displaystyle]
|
||||
ATTRIBUTE[mstyle:displaystyle]
|
||||
ATTRIBUTE[msub:displaystyle]
|
||||
ATTRIBUTE[msubsup:displaystyle]
|
||||
ATTRIBUTE[msup:displaystyle]
|
||||
ATTRIBUTE[mtable:displaystyle]
|
||||
ATTRIBUTE[mtd:displaystyle]
|
||||
ATTRIBUTE[mtext:displaystyle]
|
||||
ATTRIBUTE[mtr:displaystyle]
|
||||
ATTRIBUTE[munder:displaystyle]
|
||||
ATTRIBUTE[munderover:displaystyle]
|
||||
ATTRIBUTE[none:displaystyle]
|
||||
ATTRIBUTE[semantics:displaystyle]
|
||||
|
||||
BOOLEAN[mathbackground]
|
||||
ATTRIBUTE[annotation:mathbackground]
|
||||
ATTRIBUTE[maction:mathbackground]
|
||||
ATTRIBUTE[math:mathbackground]
|
||||
ATTRIBUTE[merror:mathbackground]
|
||||
ATTRIBUTE[mfrac:mathbackground]
|
||||
ATTRIBUTE[mi:mathbackground]
|
||||
ATTRIBUTE[mmultiscripts:mathbackground]
|
||||
ATTRIBUTE[mn:mathbackground]
|
||||
ATTRIBUTE[mo:mathbackground]
|
||||
ATTRIBUTE[mover:mathbackground]
|
||||
ATTRIBUTE[mpadded:mathbackground]
|
||||
ATTRIBUTE[mphantom:mathbackground]
|
||||
ATTRIBUTE[mprescripts:mathbackground]
|
||||
ATTRIBUTE[mroot:mathbackground]
|
||||
ATTRIBUTE[mrow:mathbackground]
|
||||
ATTRIBUTE[ms:mathbackground]
|
||||
ATTRIBUTE[mspace:mathbackground]
|
||||
ATTRIBUTE[msqrt:mathbackground]
|
||||
ATTRIBUTE[mstyle:mathbackground]
|
||||
ATTRIBUTE[msub:mathbackground]
|
||||
ATTRIBUTE[msubsup:mathbackground]
|
||||
ATTRIBUTE[msup:mathbackground]
|
||||
ATTRIBUTE[mtable:mathbackground]
|
||||
ATTRIBUTE[mtd:mathbackground]
|
||||
ATTRIBUTE[mtext:mathbackground]
|
||||
ATTRIBUTE[mtr:mathbackground]
|
||||
ATTRIBUTE[munder:mathbackground]
|
||||
ATTRIBUTE[munderover:mathbackground]
|
||||
ATTRIBUTE[none:mathbackground]
|
||||
ATTRIBUTE[semantics:mathbackground]
|
||||
|
||||
BOOLEAN[mathcolor]
|
||||
ATTRIBUTE[annotation:mathcolor]
|
||||
ATTRIBUTE[maction:mathcolor]
|
||||
ATTRIBUTE[math:mathcolor]
|
||||
ATTRIBUTE[merror:mathcolor]
|
||||
ATTRIBUTE[mfrac:mathcolor]
|
||||
ATTRIBUTE[mi:mathcolor]
|
||||
ATTRIBUTE[mmultiscripts:mathcolor]
|
||||
ATTRIBUTE[mn:mathcolor]
|
||||
ATTRIBUTE[mo:mathcolor]
|
||||
ATTRIBUTE[mover:mathcolor]
|
||||
ATTRIBUTE[mpadded:mathcolor]
|
||||
ATTRIBUTE[mphantom:mathcolor]
|
||||
ATTRIBUTE[mprescripts:mathcolor]
|
||||
ATTRIBUTE[mroot:mathcolor]
|
||||
ATTRIBUTE[mrow:mathcolor]
|
||||
ATTRIBUTE[ms:mathcolor]
|
||||
ATTRIBUTE[mspace:mathcolor]
|
||||
ATTRIBUTE[msqrt:mathcolor]
|
||||
ATTRIBUTE[mstyle:mathcolor]
|
||||
ATTRIBUTE[msub:mathcolor]
|
||||
ATTRIBUTE[msubsup:mathcolor]
|
||||
ATTRIBUTE[msup:mathcolor]
|
||||
ATTRIBUTE[mtable:mathcolor]
|
||||
ATTRIBUTE[mtd:mathcolor]
|
||||
ATTRIBUTE[mtext:mathcolor]
|
||||
ATTRIBUTE[mtr:mathcolor]
|
||||
ATTRIBUTE[munder:mathcolor]
|
||||
ATTRIBUTE[munderover:mathcolor]
|
||||
ATTRIBUTE[none:mathcolor]
|
||||
ATTRIBUTE[semantics:mathcolor]
|
||||
|
||||
BOOLEAN[mathsize]
|
||||
ATTRIBUTE[annotation:mathsize]
|
||||
ATTRIBUTE[maction:mathsize]
|
||||
ATTRIBUTE[math:mathsize]
|
||||
ATTRIBUTE[merror:mathsize]
|
||||
ATTRIBUTE[mfrac:mathsize]
|
||||
ATTRIBUTE[mi:mathsize]
|
||||
ATTRIBUTE[mmultiscripts:mathsize]
|
||||
ATTRIBUTE[mn:mathsize]
|
||||
ATTRIBUTE[mo:mathsize]
|
||||
ATTRIBUTE[mover:mathsize]
|
||||
ATTRIBUTE[mpadded:mathsize]
|
||||
ATTRIBUTE[mphantom:mathsize]
|
||||
ATTRIBUTE[mprescripts:mathsize]
|
||||
ATTRIBUTE[mroot:mathsize]
|
||||
ATTRIBUTE[mrow:mathsize]
|
||||
ATTRIBUTE[ms:mathsize]
|
||||
ATTRIBUTE[mspace:mathsize]
|
||||
ATTRIBUTE[msqrt:mathsize]
|
||||
ATTRIBUTE[mstyle:mathsize]
|
||||
ATTRIBUTE[msub:mathsize]
|
||||
ATTRIBUTE[msubsup:mathsize]
|
||||
ATTRIBUTE[msup:mathsize]
|
||||
ATTRIBUTE[mtable:mathsize]
|
||||
ATTRIBUTE[mtd:mathsize]
|
||||
ATTRIBUTE[mtext:mathsize]
|
||||
ATTRIBUTE[mtr:mathsize]
|
||||
ATTRIBUTE[munder:mathsize]
|
||||
ATTRIBUTE[munderover:mathsize]
|
||||
ATTRIBUTE[none:mathsize]
|
||||
ATTRIBUTE[semantics:mathsize]
|
||||
|
||||
BOOLEAN[mathvariant]
|
||||
ATTRIBUTE[annotation:mathvariant]
|
||||
ATTRIBUTE[maction:mathvariant]
|
||||
ATTRIBUTE[math:mathvariant]
|
||||
ATTRIBUTE[merror:mathvariant]
|
||||
ATTRIBUTE[mfrac:mathvariant]
|
||||
ATTRIBUTE[mi:mathvariant]
|
||||
ATTRIBUTE[mmultiscripts:mathvariant]
|
||||
ATTRIBUTE[mn:mathvariant]
|
||||
ATTRIBUTE[mo:mathvariant]
|
||||
ATTRIBUTE[mover:mathvariant]
|
||||
ATTRIBUTE[mpadded:mathvariant]
|
||||
ATTRIBUTE[mphantom:mathvariant]
|
||||
ATTRIBUTE[mprescripts:mathvariant]
|
||||
ATTRIBUTE[mroot:mathvariant]
|
||||
ATTRIBUTE[mrow:mathvariant]
|
||||
ATTRIBUTE[ms:mathvariant]
|
||||
ATTRIBUTE[mspace:mathvariant]
|
||||
ATTRIBUTE[msqrt:mathvariant]
|
||||
ATTRIBUTE[mstyle:mathvariant]
|
||||
ATTRIBUTE[msub:mathvariant]
|
||||
ATTRIBUTE[msubsup:mathvariant]
|
||||
ATTRIBUTE[msup:mathvariant]
|
||||
ATTRIBUTE[mtable:mathvariant]
|
||||
ATTRIBUTE[mtd:mathvariant]
|
||||
ATTRIBUTE[mtext:mathvariant]
|
||||
ATTRIBUTE[mtr:mathvariant]
|
||||
ATTRIBUTE[munder:mathvariant]
|
||||
ATTRIBUTE[munderover:mathvariant]
|
||||
ATTRIBUTE[none:mathvariant]
|
||||
ATTRIBUTE[semantics:mathvariant]
|
||||
|
||||
BOOLEAN[nonce]
|
||||
ATTRIBUTE[annotation:nonce]
|
||||
ATTRIBUTE[maction:nonce]
|
||||
ATTRIBUTE[math:nonce]
|
||||
ATTRIBUTE[merror:nonce]
|
||||
ATTRIBUTE[mfrac:nonce]
|
||||
ATTRIBUTE[mi:nonce]
|
||||
ATTRIBUTE[mmultiscripts:nonce]
|
||||
ATTRIBUTE[mn:nonce]
|
||||
ATTRIBUTE[mo:nonce]
|
||||
ATTRIBUTE[mover:nonce]
|
||||
ATTRIBUTE[mpadded:nonce]
|
||||
ATTRIBUTE[mphantom:nonce]
|
||||
ATTRIBUTE[mprescripts:nonce]
|
||||
ATTRIBUTE[mroot:nonce]
|
||||
ATTRIBUTE[mrow:nonce]
|
||||
ATTRIBUTE[ms:nonce]
|
||||
ATTRIBUTE[mspace:nonce]
|
||||
ATTRIBUTE[msqrt:nonce]
|
||||
ATTRIBUTE[mstyle:nonce]
|
||||
ATTRIBUTE[msub:nonce]
|
||||
ATTRIBUTE[msubsup:nonce]
|
||||
ATTRIBUTE[msup:nonce]
|
||||
ATTRIBUTE[mtable:nonce]
|
||||
ATTRIBUTE[mtd:nonce]
|
||||
ATTRIBUTE[mtext:nonce]
|
||||
ATTRIBUTE[mtr:nonce]
|
||||
ATTRIBUTE[munder:nonce]
|
||||
ATTRIBUTE[munderover:nonce]
|
||||
ATTRIBUTE[none:nonce]
|
||||
ATTRIBUTE[semantics:nonce]
|
||||
|
||||
BOOLEAN[scriptlevel]
|
||||
ATTRIBUTE[annotation:scriptlevel]
|
||||
ATTRIBUTE[maction:scriptlevel]
|
||||
ATTRIBUTE[math:scriptlevel]
|
||||
ATTRIBUTE[merror:scriptlevel]
|
||||
ATTRIBUTE[mfrac:scriptlevel]
|
||||
ATTRIBUTE[mi:scriptlevel]
|
||||
ATTRIBUTE[mmultiscripts:scriptlevel]
|
||||
ATTRIBUTE[mn:scriptlevel]
|
||||
ATTRIBUTE[mo:scriptlevel]
|
||||
ATTRIBUTE[mover:scriptlevel]
|
||||
ATTRIBUTE[mpadded:scriptlevel]
|
||||
ATTRIBUTE[mphantom:scriptlevel]
|
||||
ATTRIBUTE[mprescripts:scriptlevel]
|
||||
ATTRIBUTE[mroot:scriptlevel]
|
||||
ATTRIBUTE[mrow:scriptlevel]
|
||||
ATTRIBUTE[ms:scriptlevel]
|
||||
ATTRIBUTE[mspace:scriptlevel]
|
||||
ATTRIBUTE[msqrt:scriptlevel]
|
||||
ATTRIBUTE[mstyle:scriptlevel]
|
||||
ATTRIBUTE[msub:scriptlevel]
|
||||
ATTRIBUTE[msubsup:scriptlevel]
|
||||
ATTRIBUTE[msup:scriptlevel]
|
||||
ATTRIBUTE[mtable:scriptlevel]
|
||||
ATTRIBUTE[mtd:scriptlevel]
|
||||
ATTRIBUTE[mtext:scriptlevel]
|
||||
ATTRIBUTE[mtr:scriptlevel]
|
||||
ATTRIBUTE[munder:scriptlevel]
|
||||
ATTRIBUTE[munderover:scriptlevel]
|
||||
ATTRIBUTE[none:scriptlevel]
|
||||
ATTRIBUTE[semantics:scriptlevel]
|
||||
42
j2html-ext-mathml/src/test/java/MathMLTests.java
Normal file
@@ -0,0 +1,42 @@
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.j2html.mathml.MathML.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class MathMLTests {
|
||||
|
||||
@Test
|
||||
public void all_tags_render_containers(){
|
||||
assertEquals("<annotation></annotation>", annotation().render());
|
||||
assertEquals("<maction></maction>", maction().render());
|
||||
assertEquals("<math></math>", math().render());
|
||||
assertEquals("<merror></merror>", merror().render());
|
||||
assertEquals("<mfrac></mfrac>", mfrac().render());
|
||||
assertEquals("<mi></mi>", mi().render());
|
||||
assertEquals("<mmultiscripts></mmultiscripts>", mmultiscripts().render());
|
||||
assertEquals("<mn></mn>", mn().render());
|
||||
assertEquals("<mo></mo>", mo().render());
|
||||
assertEquals("<mover></mover>", mover().render());
|
||||
assertEquals("<mpadded></mpadded>", mpadded().render());
|
||||
assertEquals("<mphantom></mphantom>", mphantom().render());
|
||||
assertEquals("<mprescripts></mprescripts>", mprescripts().render());
|
||||
assertEquals("<mroot></mroot>", mroot().render());
|
||||
assertEquals("<mrow></mrow>", mrow().render());
|
||||
assertEquals("<ms></ms>", ms().render());
|
||||
assertEquals("<mspace></mspace>", mspace().render());
|
||||
assertEquals("<msqrt></msqrt>", msqrt().render());
|
||||
assertEquals("<mstyle></mstyle>", mstyle().render());
|
||||
assertEquals("<msub></msub>", msub().render());
|
||||
assertEquals("<msubsup></msubsup>", msubsup().render());
|
||||
assertEquals("<msup></msup>", msup().render());
|
||||
assertEquals("<mtable></mtable>", mtable().render());
|
||||
assertEquals("<mtd></mtd>", mtd().render());
|
||||
assertEquals("<mtext></mtext>", mtext().render());
|
||||
assertEquals("<mtr></mtr>", mtr().render());
|
||||
assertEquals("<munder></munder>", munder().render());
|
||||
assertEquals("<munderover></munderover>", munderover().render());
|
||||
assertEquals("<none></none>", none().render());
|
||||
assertEquals("<semantics></semantics>", semantics().render());
|
||||
}
|
||||
|
||||
}
|
||||
96
j2html-website/.gitignore
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
21
j2html-website/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# j2html.com source code
|
||||
|
||||
## Running
|
||||
|
||||
Run this as any maven project.
|
||||
Website is available on http://localhost:8888/.
|
||||
|
||||
## Deploying
|
||||
|
||||
In order to "deploy" the website, the static files in the `j2html/docs` must be updated.
|
||||
You can either download the files manually from your browser, or use curl:
|
||||
|
||||
```sh
|
||||
curl "http://localhost:8888/" > index.html
|
||||
curl "http://localhost:8888/download.html" > download.html
|
||||
curl "http://localhost:8888/examples.html" > examples.html
|
||||
curl "http://localhost:8888/news.html" > news.html
|
||||
curl "http://localhost:8888/404.html" > 404.html
|
||||
```
|
||||
|
||||
Changes will be deployed automatically once they have been merged.
|
||||
BIN
j2html-website/gfx/j2html-logo.sketch
Normal file
BIN
j2html-website/gfx/~`~j2html-logo.sketch
Normal file
83
j2html-website/pom.xml
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html-parent</artifactId>
|
||||
<version>1.6.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>j2html-website</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.javalin</groupId>
|
||||
<artifactId>javalin</artifactId>
|
||||
<version>4.0.0.ALPHA2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.26</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<finalName>j2html-website</finalName>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<mainClass>app.Main</mainClass>
|
||||
<classpathPrefix>dependency-jars/</classpathPrefix>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<!-- This tells Maven to include all dependencies -->
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>app.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
22
j2html-website/src/main/java/app/Main.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package app;
|
||||
|
||||
import app.controllers.PageController;
|
||||
import io.javalin.Javalin;
|
||||
import io.javalin.http.staticfiles.Location;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Javalin app = Javalin.create(config ->
|
||||
config.addStaticFiles("website/src/main/resources/public", Location.EXTERNAL)
|
||||
).start(8888);
|
||||
|
||||
app.get("/", PageController::serveIndex);
|
||||
app.get("/download.html", PageController::serveDownload);
|
||||
app.get("/examples.html", PageController::serveExamples);
|
||||
app.get("/news.html", PageController::serveNews);
|
||||
app.get("/404.html", PageController::serve404);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package app.controllers;
|
||||
|
||||
import app.views.pages.DownloadView;
|
||||
import app.views.pages.ExamplesView;
|
||||
import app.views.pages.IndexView;
|
||||
import app.views.pages.NewsView;
|
||||
import app.views.pages.PageNotFoundView;
|
||||
import io.javalin.http.Context;
|
||||
|
||||
public class PageController {
|
||||
|
||||
public static void serveIndex(Context ctx) {
|
||||
ctx.html(IndexView.render());
|
||||
}
|
||||
|
||||
public static void serveDownload(Context ctx) {
|
||||
ctx.html(DownloadView.render());
|
||||
}
|
||||
|
||||
public static void serveExamples(Context ctx) {
|
||||
ctx.html(ExamplesView.render());
|
||||
}
|
||||
|
||||
public static void serveNews(Context ctx) {
|
||||
ctx.html(NewsView.render());
|
||||
}
|
||||
|
||||
public static void serve404(Context ctx) {
|
||||
ctx.html(PageNotFoundView.render());
|
||||
}
|
||||
}
|
||||
24
j2html-website/src/main/java/app/debug/Employee.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package app.debug;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Employee {
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final String title;
|
||||
|
||||
Employee(int id, String name, String title) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public static List<Employee> employees = new ArrayList<Employee>(Arrays.asList(
|
||||
new Employee(1, "David", "Creator of Bad Libraries"),
|
||||
new Employee(2, "Christian", "Fanboi of Jenkins"),
|
||||
new Employee(3, "Paul", "Hater of Lambda Expressions")
|
||||
));
|
||||
|
||||
}
|
||||
96
j2html-website/src/main/java/app/views/MainView.java
Normal file
@@ -0,0 +1,96 @@
|
||||
package app.views;
|
||||
|
||||
import j2html.tags.DomContent;
|
||||
import static j2html.TagCreator.a;
|
||||
import static j2html.TagCreator.attrs;
|
||||
import static j2html.TagCreator.body;
|
||||
import static j2html.TagCreator.br;
|
||||
import static j2html.TagCreator.div;
|
||||
import static j2html.TagCreator.document;
|
||||
import static j2html.TagCreator.fileAsString;
|
||||
import static j2html.TagCreator.footer;
|
||||
import static j2html.TagCreator.h1;
|
||||
import static j2html.TagCreator.head;
|
||||
import static j2html.TagCreator.header;
|
||||
import static j2html.TagCreator.html;
|
||||
import static j2html.TagCreator.img;
|
||||
import static j2html.TagCreator.join;
|
||||
import static j2html.TagCreator.li;
|
||||
import static j2html.TagCreator.link;
|
||||
import static j2html.TagCreator.main;
|
||||
import static j2html.TagCreator.meta;
|
||||
import static j2html.TagCreator.nav;
|
||||
import static j2html.TagCreator.p;
|
||||
import static j2html.TagCreator.scriptWithInlineFile;
|
||||
import static j2html.TagCreator.scriptWithInlineFile_min;
|
||||
import static j2html.TagCreator.span;
|
||||
import static j2html.TagCreator.styleWithInlineFile_min;
|
||||
import static j2html.TagCreator.title;
|
||||
import static j2html.TagCreator.ul;
|
||||
|
||||
public class MainView {
|
||||
|
||||
public static String render(String title, String heading, DomContent... tags) {
|
||||
return document(
|
||||
html(
|
||||
head(
|
||||
meta().withCharset("UTF-8"),
|
||||
meta().withName("viewport").withContent("width=device-width, initial-scale=1"),
|
||||
meta().withName("description").withContent("j2html - Fast and fluent Java HTML builder. Build type-safe HTML 5 with Java 8 expression!"),
|
||||
title(title + " - Java HTML builder"),
|
||||
link().withRel("icon").withHref("/img/favicon.svg"),
|
||||
link().withRel("stylesheet").withHref("https://fonts.googleapis.com/css2?family=Lato&family=Patua+One&display=swap"),
|
||||
styleWithInlineFile_min("/public/css/prism.css"),
|
||||
styleWithInlineFile_min("/public/css/main.css")
|
||||
),
|
||||
body(
|
||||
fileAsString("/html/googleTagManager.html"),
|
||||
fileAsString("/html/githubBanner.html"),
|
||||
header(attrs(".top-header"),
|
||||
nav(attrs(".width-limit"),
|
||||
a().withId("logo").withHref("/").with(
|
||||
span(img().withSrc("/img/logo.svg").withAlt("j2html logo"))
|
||||
),
|
||||
ul(
|
||||
li(a("Home").withHref("/")),
|
||||
li(a("Download").withHref("/download.html")),
|
||||
li(a("Examples").withHref("/examples.html")),
|
||||
li(a("News").withHref("/news.html"))
|
||||
)
|
||||
)
|
||||
|
||||
),
|
||||
header(attrs(".banner"),
|
||||
h1(attrs(".width-limit"), heading)
|
||||
),
|
||||
main(attrs(".width-limit"),
|
||||
tags //content from other template
|
||||
),
|
||||
div(attrs("#javalin-suggestion"), join(
|
||||
span("✖").withClass("close"),
|
||||
"Want a simple and modern web framework?",
|
||||
br(),
|
||||
"Try our other project:",
|
||||
a("https://javalin.io").withHref("https://javalin.io?from=j2html")
|
||||
)),
|
||||
footer(join(
|
||||
"This page was created using",
|
||||
a("j2html").withHref("https://github.com/tipsy/j2html").withTarget("_blank"),
|
||||
"and",
|
||||
a("Javalin").withHref("https://javalin.io/").withTarget("_blank"),
|
||||
". Webpage source on",
|
||||
a("Github").withHref("https://github.com/j2html/j2html-webpage").withTarget("_blank"),
|
||||
".",
|
||||
br(),
|
||||
p(attrs(".lols"), "A static page generator or a template engine would be better suited than a HTML builder for creating this page, but we had to do it.")
|
||||
)),
|
||||
scriptWithInlineFile("/public/js/prism.js"),
|
||||
scriptWithInlineFile_min("/public/js/codeCompare.js"),
|
||||
scriptWithInlineFile_min("/public/js/javalinSuggestion.js")
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
52
j2html-website/src/main/java/app/views/Partials.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package app.views;
|
||||
|
||||
import j2html.tags.ContainerTag;
|
||||
import j2html.tags.Text;
|
||||
import static j2html.TagCreator.a;
|
||||
import static j2html.TagCreator.attrs;
|
||||
import static j2html.TagCreator.code;
|
||||
import static j2html.TagCreator.div;
|
||||
import static j2html.TagCreator.fileAsEscapedString;
|
||||
import static j2html.TagCreator.join;
|
||||
import static j2html.TagCreator.li;
|
||||
import static j2html.TagCreator.p;
|
||||
import static j2html.TagCreator.pre;
|
||||
import static j2html.TagCreator.ul;
|
||||
|
||||
public class Partials {
|
||||
|
||||
public static ContainerTag codeSnippet(String language, Text snippet) {
|
||||
return pre(
|
||||
code().withClass("language-" + language).with(
|
||||
snippet
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static ContainerTag javaComparison(String filename) {
|
||||
return div().withClasses("code-compare", "nowith").with(
|
||||
ul(
|
||||
li("version 1.0.0 +").withClass("nowith-switch active"),
|
||||
li("earlier versions").withClass("with-switch")
|
||||
),
|
||||
pre(attrs(".nowith-pre"),
|
||||
code(attrs(".language-java"),
|
||||
fileAsEscapedString("/codeExamples/" + filename + "_new.java")
|
||||
)
|
||||
),
|
||||
pre(attrs(".with-pre"),
|
||||
code(attrs(".language-java"),
|
||||
fileAsEscapedString("/codeExamples/" + filename + ".java")
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public static ContainerTag mavenLink(String version) {
|
||||
return p(join(
|
||||
"j2html", version, "is available for download on",
|
||||
a("Maven Central").withHref("http://search.maven.org/#artifactdetails%7Ccom.j2html%7Cj2html%7C" + version + "%7Cjar").withTarget("_blank"),
|
||||
"."
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package app.views.pages;
|
||||
|
||||
import app.views.MainView;
|
||||
import static app.views.Partials.codeSnippet;
|
||||
import static j2html.TagCreator.*;
|
||||
|
||||
public class DownloadView {
|
||||
public static String render() {
|
||||
return MainView.render(
|
||||
"Download j2html",
|
||||
"Maven and GitHub",
|
||||
section(attrs("#download"),
|
||||
h2("Maven dependency"),
|
||||
p("To experience the joy of generating HTML with a Java HTML builder, add the j2html dependency to your POM:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/mavenDep.xml")),
|
||||
a().withId("upgrade"),
|
||||
h2("Steps for upgrading"),
|
||||
p("From 1.4.0 to 1.5.0"),
|
||||
ul(
|
||||
li(
|
||||
join("Change return types from", code("Tag"), ",", code("ContainerTag"), "or", code("EmptyTag"), "to the specific tag being returned.")
|
||||
),
|
||||
li(
|
||||
join("Change missing method calls on tags, such as", code("withRole(\"value\")"), "to", code(".attr(\"role\", \"value\")"), ".")
|
||||
),
|
||||
li(
|
||||
join("Method parameters of", code("Tag"), ",", code("ContainerTag"), "or", code("EmptyTag"), "should have a wildcard (<?>) added, or be changed to a specific tag.")
|
||||
),
|
||||
li(
|
||||
join("Replace ambiguous method references like ", code("each(list, TagCreator::li)"), " with lambdas such as", code("each(list, str -> li(str))"), ".")
|
||||
)
|
||||
),
|
||||
h2("Clone the repo on GitHub"),
|
||||
p(join(
|
||||
"Please clone and/or fork the repo on",
|
||||
a("GitHub").withHref("https://github.com/tipsy/j2html").withTarget("_blank"),
|
||||
", make changes, and create pull requests! We will go through pull requests every sunday, so don't be shy."
|
||||
))
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
121
j2html-website/src/main/java/app/views/pages/ExamplesView.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package app.views.pages;
|
||||
|
||||
import app.views.MainView;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import static app.views.Partials.codeSnippet;
|
||||
import static app.views.Partials.javaComparison;
|
||||
import static j2html.TagCreator.a;
|
||||
import static j2html.TagCreator.attrs;
|
||||
import static j2html.TagCreator.each;
|
||||
import static j2html.TagCreator.em;
|
||||
import static j2html.TagCreator.fileAsEscapedString;
|
||||
import static j2html.TagCreator.h2;
|
||||
import static j2html.TagCreator.p;
|
||||
import static j2html.TagCreator.section;
|
||||
import static j2html.TagCreator.table;
|
||||
import static j2html.TagCreator.tbody;
|
||||
import static j2html.TagCreator.td;
|
||||
import static j2html.TagCreator.text;
|
||||
import static j2html.TagCreator.tr;
|
||||
|
||||
public class ExamplesView {
|
||||
private static List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 10);
|
||||
|
||||
public static String render() {
|
||||
return MainView.render(
|
||||
"Examples of how to use j2html",
|
||||
"Reclaim control of your HTML",
|
||||
section(attrs("#examples"),
|
||||
h2(attrs("#basic-example"), "Basic example"),
|
||||
p("Creating a basic HTML structure in j2html is pretty similar to plain HTML. This Java code:"),
|
||||
javaComparison("basic"),
|
||||
p("Becomes this HTML:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/basic.html")),
|
||||
p(
|
||||
text(
|
||||
"It's literally impossible to forget to close a div, mistype an attribute name, or forget an attribute quote! " +
|
||||
"Remember to include the Java wrapping code though, j2html is not a template language, all files are .java. " +
|
||||
"To see how the wrapping code could look, check out the "
|
||||
),
|
||||
a("getting started example").withHref("/"),
|
||||
text(".")
|
||||
),
|
||||
|
||||
h2(attrs("#core-concepts"), "Core concepts"),
|
||||
codeSnippet("java", fileAsEscapedString("/codeExamples/coreConcepts.java")),
|
||||
|
||||
h2(attrs("#loops"), "Loops, each() and filter()"),
|
||||
p("Using Java 8's lambda syntax, you can write loops (via streams) inside your HTML-builder:"),
|
||||
javaComparison("forLoopLambda"),
|
||||
|
||||
p("j2html also offers a custom each method, which is slightly more powerful:"),
|
||||
javaComparison("each"),
|
||||
|
||||
p("If you need to filter your collection, j2html has a built in filter function too:"),
|
||||
javaComparison("filter"),
|
||||
|
||||
p(
|
||||
"Since this is pure Java, all the Employee methods (getName, getImgPath, getTitle) are available to you, " +
|
||||
"and you get autocomplete suggestions and compile time errors."
|
||||
),
|
||||
p("Given three random employees, all the above approaches would give the same HTML:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/forLoop.html")),
|
||||
|
||||
h2(attrs("#2d-table-example"), "Two dimensional table example"),
|
||||
javaComparison("2dTable"),
|
||||
p("The code above is generating this table:"),
|
||||
table(attrs("#table-example"),
|
||||
tbody(
|
||||
each(numbers, i -> tr(
|
||||
each(numbers, j -> td(
|
||||
String.valueOf(i * j)
|
||||
))
|
||||
))
|
||||
)
|
||||
),
|
||||
|
||||
h2(attrs("#partials"), "Partials"),
|
||||
p("You can create partials for elements you use a lot:"),
|
||||
javaComparison("partial"),
|
||||
p("The equivalent HTML would be:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/partial.html")),
|
||||
p("You can then use these partials, for example in a registration form:"),
|
||||
javaComparison("view"),
|
||||
p("Pretty clean, right? The rendered HTML is more verbose:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/view.html")),
|
||||
p(
|
||||
text("Imagine if you wanted labels in addition. The Java snippet would look almost identical: You could create a partial called"),
|
||||
em(" passwordAndLabel() "),
|
||||
text(
|
||||
"and nothing but the method name would change. The resulting HTML however, would be twice or thrice as big, " +
|
||||
"depending on whether or not you wrapped the input and label in another tag."
|
||||
)
|
||||
),
|
||||
|
||||
h2(attrs("#dynamic-views"), "Dynamic views"),
|
||||
p(
|
||||
"Once you've set up partials, you can call them from wherever, which greatly reduces potential errors. " +
|
||||
"Let's say we want to include the form from the partials-example in our webpage. " +
|
||||
"We want a header above and a footer below. A lot of templating languages make you do this: "
|
||||
),
|
||||
codeSnippet("java", fileAsEscapedString("/codeExamples/otherTemplates.vm")),
|
||||
p(
|
||||
"This is a pain to work with. You have no idea what the header and footer expects, and you have no way to affect how they treat your content. " +
|
||||
"You can easily break the site by forgetting to close divs, or by forgetting to include either the header or the footer in one of your views. " +
|
||||
"In j2html you can specify the context in which a view is rendered, and supply the rendering method with type safe parameters! " +
|
||||
"If we want to insert our form in a header/footer frame, we simply create a MainView and make it take our view as an argument:"
|
||||
),
|
||||
|
||||
javaComparison("main"),
|
||||
p("Which will result in the rendered HTML:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/main.html")),
|
||||
p(
|
||||
"We would now get a compilation error if we forgot to include a title, and there is 0 chance of forgetting either header or footer, mistyping paths" +
|
||||
", forgetting to close divs, or anything else."
|
||||
)
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
64
j2html-website/src/main/java/app/views/pages/IndexView.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package app.views.pages;
|
||||
|
||||
import app.views.MainView;
|
||||
import static app.views.Partials.codeSnippet;
|
||||
import static j2html.TagCreator.a;
|
||||
import static j2html.TagCreator.attrs;
|
||||
import static j2html.TagCreator.fileAsEscapedString;
|
||||
import static j2html.TagCreator.h2;
|
||||
import static j2html.TagCreator.h3;
|
||||
import static j2html.TagCreator.li;
|
||||
import static j2html.TagCreator.p;
|
||||
import static j2html.TagCreator.section;
|
||||
import static j2html.TagCreator.text;
|
||||
import static j2html.TagCreator.ul;
|
||||
|
||||
public class IndexView {
|
||||
public static String render() {
|
||||
return MainView.render(
|
||||
"Fast and fluent Java HTML5 builder",
|
||||
"Fast and fluent Java HTML5 builder",
|
||||
section(attrs("#index"),
|
||||
h2("Getting started with j2html"),
|
||||
p("Import TagCreator to get started. j2html's syntax is fluent and closely matched to HTML:"),
|
||||
codeSnippet("java", fileAsEscapedString("/codeExamples/minimal.java")),
|
||||
p("The Java code above becomes the HTML below:"),
|
||||
codeSnippet("markup", fileAsEscapedString("/codeExamples/minimal.html")),
|
||||
p(
|
||||
text("Check out some more "),
|
||||
a("examples").withHref("/examples.html"),
|
||||
text(".")
|
||||
),
|
||||
|
||||
h2("Intended use"),
|
||||
h3("Consider using j2html if:"),
|
||||
ul(
|
||||
li("You love type safety. You love catching errors at compile time instead of waiting for some poor user to notice that something is wrong"),
|
||||
li("You like to dynamically reuse your view code"),
|
||||
li(
|
||||
text("You think template engines are too slow. This index page was rendered 100 000 times in less than a second on an i5-4670. That's about a thousand times faster than Apache '"),
|
||||
a("Velocity").withHref("http://velocity.apache.org/").withTarget("_blank"),
|
||||
text("' (hah!)")
|
||||
)
|
||||
),
|
||||
|
||||
h3("Be careful about using j2html if:"),
|
||||
ul(
|
||||
li("You don't know Java and HTML well"),
|
||||
li("You're creating a classic \"website\" that has a lot of static HTML (if it's all generated then it's fine)"),
|
||||
li("Your application has a lot of text and you don't use language files / a database (string concatenation would get very annoying)"),
|
||||
li("You use a CSS framework which relies on a lot of copy pasting HTML from docs. You'll have to translate these snippets to j2html")
|
||||
),
|
||||
|
||||
h2("Why did you make this library?"),
|
||||
p(
|
||||
"First: j2html is a Java HTML builder. It's not a template engine, and it doesn't want to compete with template engines. "
|
||||
+ "We were looking for a good way to create HTML for a complex login solution which had many different forms "
|
||||
+ "(with different configurations, depending on user state and user actions, etc.), but very little actual HTML per page. "
|
||||
+ "The result was j2html. We decided to release the Java HTML builder we made, since it seems better "
|
||||
+ "than all the other Java HTML builders we found while researching the subject. Hopefully someone will find it useful!"
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
191
j2html-website/src/main/java/app/views/pages/NewsView.java
Normal file
@@ -0,0 +1,191 @@
|
||||
package app.views.pages;
|
||||
|
||||
import app.views.MainView;
|
||||
import j2html.TagCreator;
|
||||
import j2html.tags.DomContent;
|
||||
import j2html.tags.specialized.ArticleTag;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static app.views.Partials.mavenLink;
|
||||
import static j2html.TagCreator.*;
|
||||
|
||||
public class NewsView {
|
||||
|
||||
private static ArticleTag newsPost(
|
||||
String title,
|
||||
String version,
|
||||
boolean breaking,
|
||||
DomContent... listItems
|
||||
) {
|
||||
List<DomContent> list = Arrays.asList(listItems);
|
||||
return article(
|
||||
h2(title).withId("j2html-" + version + "-released"),
|
||||
mavenLink(version),
|
||||
iff(breaking,
|
||||
p(
|
||||
a("This version contains breaking changes. Please view the upgrade guide.").withHref("download.html#upgrade")
|
||||
)
|
||||
),
|
||||
p("Changes:"),
|
||||
ul(
|
||||
each(list, el -> TagCreator.li(el))
|
||||
));
|
||||
}
|
||||
|
||||
public static String render() {
|
||||
return MainView.render(
|
||||
"News about j2html",
|
||||
"News and releases",
|
||||
section(attrs("#news"),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.6.0 adds support for web components and newer HTML elements. (Jun 2022)",
|
||||
"1.6.0",
|
||||
false,
|
||||
join("Added", code("TagCreator::data"), "to provide machine-readable translations."),
|
||||
join("Added", code("TagCreator::picture"), "to provide alternative versions of an image for different display/device scenarios."),
|
||||
join("Added", code("TagCreator::slot"), "to provide placeholders for web components."),
|
||||
join("Added", code("TagCreator::template"), "to provide templating of content fragments for web components."),
|
||||
join("Added global attributes used for web components.")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.5.0 enhances factory methods and class types, overhauls HTML rendering, introduces support for Java modules and fixes several bugs (Jun 2021)",
|
||||
"1.5.0",
|
||||
true,
|
||||
join("Added", code("Automatic-Module-Name"), "to manifest to support JDK 9+"),
|
||||
join("Added", code("TagCreator::each(DomContent...)")),
|
||||
join("Added", code("TagCreator::each(Collection, BiFunction)")),
|
||||
join("Added", code("HtmlBuilder"), "interface, with implementations for ", code("FlatHtml"), "and", code("IndentedHtml")),
|
||||
join("Added", code("Config.defaults()"), "for customizable configuration instances and", code("Config.global()"), "for (backwards-compatible) static global configuration"),
|
||||
join("Deprecated old rendering methods. Libraries that use custom Tag implementations should switch to using ", code("HtmlBuilder")),
|
||||
join("Fixed the use of", code("rawHtml()"), "when constructing the Tag tree"),
|
||||
join("Fixed text escaping for", code("style()"), "and", code("script()")),
|
||||
join("Fixed formatting of children for", code("textarea()"), "and", code("pre()")),
|
||||
join("Fixed appending an unnecessary delimiter to the end of text with", code("join()")),
|
||||
join("Thanks to", a("Oliver Becker").withHref("https://github.com/obecker"), "for many code improvements")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.4.0 adds a couple of convenient methods (Jan 2019)",
|
||||
"1.4.0",
|
||||
false,
|
||||
join("Added", code("TagCreator::each(Map, BiFunction)")),
|
||||
join("Added", code("Stream<DomContent>"), "variants of", code("each"), "and", code("with"))
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.3.0 has a couple of features and fixes (May 2018)",
|
||||
"1.3.0",
|
||||
false,
|
||||
join("Added support for", code("Map"), "in", code("each()")),
|
||||
join("Added osgi metadata"),
|
||||
join("Added support for", code("Optional"), "in", code("iff()")),
|
||||
join("Fixed bugs in ", code("renderFormatted()"))
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.2.2 has performance improvements (Dec 2017)",
|
||||
"1.2.2",
|
||||
false,
|
||||
join("There have been some massive performance improvements. Big thanks to", a("kicktipp").withHref("https://github.com/kicktipp"), ".")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.2.1 fixes some bugs (Nov 2017)",
|
||||
"1.2.1",
|
||||
false,
|
||||
join("Fix", em("\"bad closing tag (<!DOCTYPE html/>) when closeEmptyTags is true\""), "bug"),
|
||||
join("Fix", em("\"can't load static resources from jar\""), "bug"),
|
||||
join("Fix", em("\"CSSMin stripping last character of CSS rule if rule doesn't end in semi-colon\""), "bug")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.2.0 already? (Sep 2017)",
|
||||
"1.2.0",
|
||||
false,
|
||||
join("Added option to render formatted HTML, ex", code("body(...).renderFormatted()")),
|
||||
join("Added option to configure HTML-formatting-indent via", code("Config.indenter = (int, string) -> {...}")),
|
||||
join("Added option to configure CSS-minification via", code("Config.cssMinifier = string -> {...}")),
|
||||
join("Added option to configure JS-minification via", code("Config.jsMinifier = string -> {...}")),
|
||||
join("Added option to close empty tags via", code("Config.closeEmptyTags = true")),
|
||||
join(code("attr()"), "can now take take any object, not just strings")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.1.0 is out! (Aug 2017)",
|
||||
"1.1.0",
|
||||
false,
|
||||
join("Added a option to customize TextEscaper via", code("Config.textEscaper = text -> {}"))
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 1.0.0 is here! (May 2017)",
|
||||
"1.0.0",
|
||||
false,
|
||||
join("v1 is officially done. We will be doing", a("semantic versioning").withHref("http://semver.org/").withTarget("_blank"), "from now on."),
|
||||
join("All tag methods (", code("div()"), ",", code("p()"), "etc ) can now accept an arbitrary number of", code("DomContent"), "as arguments, eliminating the need for", code("with()"), "in most cases."),
|
||||
join("Added a shorthand-attribute overloads to all TagCreator methods:", br(), code("div(attrs(\"#id.class\")"), "becomes", code("<div id=\"id\" class=\"class\"></div>")),
|
||||
join("Added a", code("join()"), "method to more easily join sentences with inline HTML, like:", br(), code("join(\"Added a\", code(\"join()\"), \"method to more ea...")),
|
||||
join("Added a", code("document()"), "method that takes a", code("html()"), " tag and renders a HTML declaration followed by the html content"),
|
||||
join("Added support for Java 7 and Java 6. Some functionality (each/filter) will not work on these versions, but everything else should.")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 0.99 released! (Apr 2017)",
|
||||
"0.99",
|
||||
false,
|
||||
join("Added generic", code("iff()"), "/", code("iffElse()"), "methods for performing if's in method calls."),
|
||||
join("Added", code("withClasses()"), "to add multiple classes to element. Works well with", code("iff()"), "."),
|
||||
join("HTML-escaping is now a lot faster (and a lot faster than StringUtils)"),
|
||||
join("Static files can now be fetched from anywhere, not just classpath")
|
||||
),
|
||||
|
||||
newsPost(
|
||||
"j2html 0.88 released! (Jan 2017)",
|
||||
"0.88",
|
||||
false,
|
||||
text("Closure and StringUtils dependencies removed in favor of custom implementations. Most users seem interested in a very lightweight library."),
|
||||
code("unsafeHtml()"), text(" is now "), code("rawHtml()"),
|
||||
text("Added "), code(".equals()"), text(" to Tag-class. Two Tags are equal if they render the same HTML")
|
||||
),
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
h2("j2html 0.7 released!").withId("j2html-0.7-released"),
|
||||
mavenLink("0.7"),
|
||||
p("Changes:"),
|
||||
ul(
|
||||
li("New file-api (avilable from TagCreator class):").with(
|
||||
dl(
|
||||
dt("fileAsString(String path)"),
|
||||
dd("returns a file's content as a String (useful for including static HTML such as Google Analytics code)"),
|
||||
|
||||
dt("fileAsEscapedString(String path)"),
|
||||
dd("returns fileAsString(path) escaped (useful for including the code-examples on this website)"),
|
||||
|
||||
dt("styleWithInlineFile(String path)"),
|
||||
dd("returns <style>fileAsString(path)</style>"),
|
||||
|
||||
dt("styleWithInlineFile_min(String path)"),
|
||||
dd("returns <style>fileAsString(path)</style>, minimized using CSSMin"),
|
||||
|
||||
dt("scriptWithInlineFile(String path)"),
|
||||
dd("returns <script>fileAsString(path)</script>"),
|
||||
|
||||
dt("scriptWithInlineFile_min(String path)"),
|
||||
dd("returns <script>fileAsString(path)</script>, minimized using Google Closure")
|
||||
)
|
||||
),
|
||||
li("Java 7 support (j2html previously only worked with Java 8)"),
|
||||
li("Use apache stringutils for escaping")
|
||||
),
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
h2("j2html 0.5.0 is on Maven! (Late May 2015)").withId("j2html-on-maven"),
|
||||
mavenLink("0.5.0"),
|
||||
p("We've finished the herculean task of releasing on Maven Central.")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package app.views.pages;
|
||||
|
||||
import app.views.MainView;
|
||||
import static j2html.TagCreator.attrs;
|
||||
import static j2html.TagCreator.h2;
|
||||
import static j2html.TagCreator.p;
|
||||
import static j2html.TagCreator.section;
|
||||
|
||||
public class PageNotFoundView {
|
||||
public static String render() {
|
||||
return MainView.render(
|
||||
"Page not found",
|
||||
"Page not found",
|
||||
section(attrs("#not-found"),
|
||||
h2("Use the menu to get back on track!"),
|
||||
p(attrs(".error-code"), "Error code 404")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
11
j2html-website/src/main/resources/codeExamples/2dTable.java
Normal file
@@ -0,0 +1,11 @@
|
||||
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 10);
|
||||
...
|
||||
table().withId("table-example").with(
|
||||
tbody().with(
|
||||
each(numbers, i -> tr().with(
|
||||
each(numbers, j -> td().with(
|
||||
String.valueOf(i * j)
|
||||
))
|
||||
))
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 10);
|
||||
...
|
||||
table(attr("#table-example"),
|
||||
tbody(
|
||||
each(numbers, i -> tr(
|
||||
each(numbers, j -> td(
|
||||
String.valueOf(i * j)
|
||||
))
|
||||
))
|
||||
)
|
||||
)
|
||||
11
j2html-website/src/main/resources/codeExamples/basic.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Title</title>
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<main id="main" class="content">
|
||||
<h1>Heading!</h1>
|
||||
</main>
|
||||
</body>
|
||||
<html>
|
||||
11
j2html-website/src/main/resources/codeExamples/basic.java
Normal file
@@ -0,0 +1,11 @@
|
||||
html().with(
|
||||
head().with(
|
||||
title("Title"),
|
||||
link().withRel("stylesheet").withHref("/css/main.css")
|
||||
),
|
||||
body().with(
|
||||
main().withId("main").withClass("content").with(
|
||||
h1("Heading!")
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
html(
|
||||
head(
|
||||
title("Title"),
|
||||
link().withRel("stylesheet").withHref("/css/main.css")
|
||||
),
|
||||
body(
|
||||
main(attrs("#main.content"),
|
||||
h1("Heading!")
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
TagCreator.class // Static utility class for creating all tags
|
||||
import static j2html.TagCreator.*; // Use static star import
|
||||
|
||||
|
||||
Config.class // Holds all configuration. Offers global configuration or customizable instances
|
||||
Config.closeEmptyTags = true // Global options are public, static and mutable.
|
||||
Config.global() // Copy all static Config fields into an instance. Instances are immutable
|
||||
Config.defaults() // A Config with defaults that are independent of global options
|
||||
Config.global().withEmptyTagsClosed(true) // A Config that is different from the global options
|
||||
Config.defaults().withEmptyTagsClosed(true) // A Config that is different from the default options
|
||||
|
||||
|
||||
TagCreator.join() // Method for joining small snippets, like:
|
||||
p(join("This paragraph has", b("bold"), "and", i("italic"), "text."))
|
||||
|
||||
|
||||
TagCreator.iff(boolean condition, T ifValue) // If-expression for use in method calls
|
||||
div().withClasses("menu-element", iff(isActive, "active"))
|
||||
|
||||
|
||||
TagCreator.iffElse(boolean condition, T ifValue, T elseValue) // If/else-expression for use in method calls
|
||||
div().withClasses("menu-element", iffElse(isActive, "active", "not-active"))
|
||||
|
||||
|
||||
Tag.class // Is extended by ContainerTag (ex <div></div> and EmptyTag (ex <br>)
|
||||
Tag.attr(String attribute, Object value) // Set an attribute on the tag
|
||||
Tag.withXyz(String value) // Calls attr with predefined attribute (ex .withId, .withClass, etc.)
|
||||
Tag.render(HtmlBuilder builder) // Render HTML using the given builder.
|
||||
Tag.render() // Shortcut for rendering flat HTML into a string using global Config.
|
||||
ContainerTag.renderFormatted() // Shortcut for rendering indented HTML into a string using global Config.
|
||||
|
||||
HtmlBuilder.class // Interface for composing HTML. Implemented by FlatHtml and IndentedHtml
|
||||
FlatHtml.into(Appendable) // Render into a stream, file, etc. without indentation or line breaks
|
||||
FlatHtml.into(Appendable appendable, Config config) // Customize rendering of flat html
|
||||
IndentedHtml.into(Appendable) // Render human-readable HTML into an stream, file, etc.
|
||||
IndentedHtml.into(Appendable appendable, Config config) // Customize rendering of intended html
|
||||
ul(li("one"), li("two")).render(IndentedHtml.inMemory()).toString() // Similar to renderFormatted()
|
||||
ul(li("one"), li("two")).render(IndentedHtml.into(filewriter)) // Write HTML into a file
|
||||
15
j2html-website/src/main/resources/codeExamples/each.java
Normal file
@@ -0,0 +1,15 @@
|
||||
// each() lets you iterate through a collection and returns the generated HTML
|
||||
// as a DomContent object, meaning you can add siblings, which is not possible
|
||||
// using the stream api in the previous example
|
||||
body().with(
|
||||
div().withId("employees").with(
|
||||
p("Some sibling element"),
|
||||
each(employees, employee ->
|
||||
div().withClass("employee").with(
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
15
j2html-website/src/main/resources/codeExamples/each_new.java
Normal file
@@ -0,0 +1,15 @@
|
||||
// each() lets you iterate through a collection and returns the generated HTML
|
||||
// as a DomContent object, meaning you can add siblings, which is not possible
|
||||
// using the stream api in the previous example
|
||||
body(
|
||||
div(attrs("#employees"),
|
||||
p("Some sibling element"),
|
||||
each(employees, employee ->
|
||||
div(attrs(".employee"),
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
15
j2html-website/src/main/resources/codeExamples/filter.java
Normal file
@@ -0,0 +1,15 @@
|
||||
// filter() is meant to be used with each(). It just calls the normal
|
||||
// stream().filter() method, but hides all the boilerplate Java code
|
||||
// to keep your j2html code neat
|
||||
body().with(
|
||||
div().withId("employees").with(
|
||||
p("Some sibling element"),
|
||||
each(filter(employees, employee -> employee != null), employee ->
|
||||
div().withClass("employee").with(
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
// filter() is meant to be used with each(). It just calls the normal
|
||||
// stream().filter() method, but hides all the boilerplate Java code
|
||||
// to keep your j2html code neat
|
||||
body(
|
||||
div(attrs("#employees"),
|
||||
p("Some sibling element"),
|
||||
each(filter(employees, employee -> employee != null), employee ->
|
||||
div(attrs(".employee"),
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
19
j2html-website/src/main/resources/codeExamples/forLoop.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<body>
|
||||
<div id="employees">
|
||||
<div class="employee">
|
||||
<h2>David</h2>
|
||||
<img src="/img/david.png">
|
||||
<p>Creator of Bad Libraries</p>
|
||||
</div>
|
||||
<div class="employee">
|
||||
<h2>Christian</h2>
|
||||
<img src="/img/christian.png">
|
||||
<p>Fanboi of Jenkins</p>
|
||||
</div>
|
||||
<div class="employee">
|
||||
<h2>Paul</h2>
|
||||
<img src="/img/paul.png">
|
||||
<p>Hater of Lambda Expressions</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1,11 @@
|
||||
body().with(
|
||||
div().withId("employees").with(
|
||||
employees.stream().map(employee ->
|
||||
div().withClass("employee").with(
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
).toArray(ContainerTag[]::new)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
body(
|
||||
div(attrs("#employees"),
|
||||
employees.stream().map(employee ->
|
||||
div(attrs(".employee"),
|
||||
h2(employee.getName()),
|
||||
img().withSrc(employee.getImgPath()),
|
||||
p(employee.getTitle())
|
||||
)
|
||||
).toArray(ContainerTag[]::new)
|
||||
)
|
||||
)
|
||||
22
j2html-website/src/main/resources/codeExamples/main.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Signup page</title>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
...
|
||||
</header>
|
||||
<main>
|
||||
<h1>Please sign up</h1>
|
||||
<form method="post">
|
||||
<input type="email" id="email" name="email" placeholder="Email address" required>
|
||||
<input type="password" id="choosePassword" name="choosePassword" placeholder="Choose password" required>
|
||||
<input type="password" id="repeatPassword" name="repeatPassword" placeholder="Repeat password" required>
|
||||
<button type="submit">Sign up</button>
|
||||
</form>
|
||||
</main>
|
||||
<footer>
|
||||
...
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
32
j2html-website/src/main/resources/codeExamples/main.java
Normal file
@@ -0,0 +1,32 @@
|
||||
public class MainView {
|
||||
public static String render(String pageTitle, Tag... tags) {
|
||||
return document().render() +
|
||||
html().with(
|
||||
head().with(
|
||||
title(pageTitle)
|
||||
),
|
||||
body().with(
|
||||
header().with(
|
||||
...
|
||||
),
|
||||
main().with(
|
||||
tags //the view from the partials example
|
||||
),
|
||||
footer().with(
|
||||
...
|
||||
)
|
||||
)
|
||||
).render();
|
||||
}
|
||||
}
|
||||
|
||||
MainView.render(
|
||||
"Signup page",
|
||||
h1("Please sign up"),
|
||||
form().withMethod("post").with(
|
||||
emailInput("Email address"),
|
||||
choosePasswordInput("Choose Password"),
|
||||
repeatPasswordInput("Repeat Password"),
|
||||
submitButton("Sign up")
|
||||
)
|
||||
);
|
||||
33
j2html-website/src/main/resources/codeExamples/main_new.java
Normal file
@@ -0,0 +1,33 @@
|
||||
public class MainView {
|
||||
public static String render(String pageTitle, Tag... tags) {
|
||||
return document(
|
||||
html(
|
||||
head(
|
||||
title(pageTitle)
|
||||
),
|
||||
body(
|
||||
header(
|
||||
...
|
||||
),
|
||||
main(
|
||||
tags //the view from the partials example
|
||||
),
|
||||
footer(
|
||||
...
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
MainView.render(
|
||||
"Signup page",
|
||||
h1("Please sign up"),
|
||||
form().withMethod("post").with(
|
||||
emailInput("Email address"),
|
||||
choosePasswordInput("Choose Password"),
|
||||
repeatPasswordInput("Repeat Password"),
|
||||
submitButton("Sign up")
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
<dependency>
|
||||
<groupId>com.j2html</groupId>
|
||||
<artifactId>j2html</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
@@ -0,0 +1,4 @@
|
||||
<body>
|
||||
<h1>Hello, World!</h1>
|
||||
<img src="/img/hello.png">
|
||||
</body>
|
||||
10
j2html-website/src/main/resources/codeExamples/minimal.java
Normal file
@@ -0,0 +1,10 @@
|
||||
import static j2html.TagCreator.*;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
body(
|
||||
h1("Hello, World!"),
|
||||
img().withSrc("/img/hello.png")
|
||||
).render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include("/path/to/header")
|
||||
#setTitle("Signup page")
|
||||
<h1>Please sign up</h1>
|
||||
<form>
|
||||
...
|
||||
</form>
|
||||
#include("/path/to/footer")
|
||||
33
j2html-website/src/main/resources/codeExamples/partial.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<input
|
||||
type="password"
|
||||
id="enterPassword"
|
||||
name="enterPassword"
|
||||
placeholder="Enter password"
|
||||
required
|
||||
>
|
||||
|
||||
<input
|
||||
type="password"
|
||||
id="choosePassword"
|
||||
name="choosePassword"
|
||||
placeholder="Choose password"
|
||||
required
|
||||
>
|
||||
|
||||
<input
|
||||
type="password"
|
||||
id="repeatPassword"
|
||||
name="repeatPassword"
|
||||
placeholder="Repeat password"
|
||||
required
|
||||
>
|
||||
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="Email"
|
||||
required
|
||||
>
|
||||
|
||||
<button type="submit">Text</button>
|
||||
33
j2html-website/src/main/resources/codeExamples/partial.java
Normal file
@@ -0,0 +1,33 @@
|
||||
public static Tag enterPasswordInput(String placeholder) {
|
||||
return passwordInput("enterPassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag choosePasswordInput(String placeholder) {
|
||||
return passwordInput("choosePassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag repeatPasswordInput(String placeholder) {
|
||||
return passwordInput("repeatPassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag passwordInput(String identifier, String placeholder) {
|
||||
return input()
|
||||
.withType("password")
|
||||
.withId(identifier)
|
||||
.withName(identifier)
|
||||
.withPlaceholder(placeholder)
|
||||
.isRequired();
|
||||
}
|
||||
|
||||
public static Tag emailInput(String placeholder) {
|
||||
return input()
|
||||
.withType("email")
|
||||
.withId("email")
|
||||
.withName("email")
|
||||
.withPlaceholder(placeholder)
|
||||
.isRequired();
|
||||
}
|
||||
|
||||
public static Tag submitButton(String text) {
|
||||
return button().withType("submit").withText(text);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
public static Tag enterPasswordInput(String placeholder) {
|
||||
return passwordInput("enterPassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag choosePasswordInput(String placeholder) {
|
||||
return passwordInput("choosePassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag repeatPasswordInput(String placeholder) {
|
||||
return passwordInput("repeatPassword", placeholder);
|
||||
}
|
||||
|
||||
public static Tag passwordInput(String identifier, String placeholder) {
|
||||
return input()
|
||||
.withType("password")
|
||||
.withId(identifier)
|
||||
.withName(identifier)
|
||||
.withPlaceholder(placeholder)
|
||||
.isRequired();
|
||||
}
|
||||
|
||||
public static Tag emailInput(String placeholder) {
|
||||
return input()
|
||||
.withType("email")
|
||||
.withId("email")
|
||||
.withName("email")
|
||||
.withPlaceholder(placeholder)
|
||||
.isRequired();
|
||||
}
|
||||
|
||||
public static Tag submitButton(String text) {
|
||||
return button(text).withType("submit");
|
||||
}
|
||||
7
j2html-website/src/main/resources/codeExamples/view.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<h1>Please sign up</h1>
|
||||
<form method="post">
|
||||
<input type="email" id="email" name="email" placeholder="Email address" required>
|
||||
<input type="password" id="choosePassword" name="choosePassword" placeholder="Choose password" required>
|
||||
<input type="password" id="repeatPassword" name="repeatPassword" placeholder="Repeat password" required>
|
||||
<button type="submit">Sign up</button>
|
||||
</form>
|
||||
7
j2html-website/src/main/resources/codeExamples/view.java
Normal file
@@ -0,0 +1,7 @@
|
||||
h1("Please sign up"),
|
||||
form().withMethod("post").with(
|
||||
emailInput("Email address"),
|
||||
choosePasswordInput("Choose Password"),
|
||||
repeatPasswordInput("Repeat Password"),
|
||||
submitButton("Sign up")
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
h1("Please sign up"),
|
||||
form().withMethod("post").with(
|
||||
emailInput("Email address"),
|
||||
choosePasswordInput("Choose Password"),
|
||||
repeatPasswordInput("Repeat Password"),
|
||||
submitButton("Sign up")
|
||||
)
|
||||
3
j2html-website/src/main/resources/html/githubBanner.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<a id="fork-me" href="https://github.com/tipsy/j2html" target="_blank">
|
||||
<img style="position:fixed;top:0;right:0;border:0;z-index:99999" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJUAAACVCAMAAABmfEh9AAAAllBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPEhwAAAAFBgkAAAARFR8fIiwRFB4YHCUQEx0RFB4SFiERFB8QEx3s7e4eIStPUlpKTFUvMjwOEhs8P0hfYmlXWmE5PUUZHSfd3uAnKjTAwcRnanB2eH5CRU6TlZqxs7bP0NKFh4yUlpqipKiUlpujpKiipKdzB4/DAAAAFXRSTlMAAwgBDREiKBYbL5wdQBjb3ZzclY3cWcIvAAAGZ0lEQVR42u2c3W7bMAyF02bL2q5bu7WLqDhW7Si24p902/u/3EglljxXQX1jixclsIv0QvhAHvAQZLJFF8vl1dX19afn/Ub9ej+2L5ufd6v725vPn66vr66ulsvFBOGoPj/LLJHvY8kkf/j2ZTUtlqe6ed6+JCOytX/ZPCLW/aRYnur2aZeo3QisjXogrO+TYjmq1ROqZgQWlvpxaiyisljf71dP+yQfJflk8mwtfbK+/NhnmxGSx1L/nBhraZP1ySbr7sc2O4xrEIMiTpqsu6+7zWGU5PNpi0hUfaxRkl9jqR9nxZLjJJ8d5s3W/mWU5Dfq56xY4z1x3iJuxnrinFg/xnrizJLfJZeLuMboJK9mbxDyIpPjkpvD48ySz4NQLpwnzopFY2CYqfzti7ibXfLZIQQlSoBjT1sRJL8bUgmCaiyWHwOjemKXqVIWYDwWljqmJ56h6jSVfyR+YOGJlCpbvipNhXBUbgycVfKqR3UuX0JUGNE8kcZA2VEphMLyZdIYabGieeJX74mYKyNEmiYaQCuLFdMTcy8sIUSuwWT6lYpI4SUfwRM9Vk1lbLQYYO3m90TVyxa1hgqqVEmHFdkTCaLRWQVa5rrAdMla+WzNPwYeXLaUBihyVBfUUhaAVh1zDNx1yZJllpLk20IWzqjjeaJXfK5J8ghVuQYRzxNdtpoOKt0674kjeVqNdFjqBAUatLJUMT3x0GtbCFXAqymVK2GkMZA80WH9gaqFLbVSGwxWI1ZbRhSFEAGsaKsRy7GFVlgsZT8yWI1YqkKtiUrpo+sPzhPjrEYsFv4jKGiMw/JjYCxPpCCotoDSYnFYjVgqRV3eQNNhRfdEwtoSVK51A+2wiBsVbww0BAWZBC08VuTVCAkroXQl8DdFLD6eaMCmK9+bTLzxxIdonqgIqixpGJTRPdGNgYIknwG0GZT4kcW5gLBQ8g0UugRzVhaLMVCIFF5lAXq7tsHhXGCxdCNlUboJItYYSEXMlOvxJTRK9AabqOeCg+ywslbYSExyIovuiQRxnpuPAICDDY/VSId1hCKrQHVtnsVqZJ1AIdMSTJqc2zyL1YiBhBr9voLOfTisRkqoMg2mAizksEHk8TwRxU5QhdGwdZKPey6wA7PZViQurOW6i/irESEMQckGc+UjqidaAtEiVAGtEJ7KST6KJ67dDuLYdfrWyp7BamTdnqFkDRj2vMJgNbI2lDFKmW6zGtqe5OOcC7z7EFSxRbhae6r1PoviiV71BhpJh6iyPCk++oXMUmm0HwyB8bvlcC74dXJqZLLZSkD/3yDirUYkNGmaN3maJsJkwmJFXo2c+kPdApi0hDaV557K4FyATFAilM6roupafTRPlJ3eZXGCMgAVZuuo4nnifuM9UQmCkgWQY1fQSPpjrNWIz5Y6QVVlhVBaifieaLFKldZ01SeoPBVSRfXEXYclEqgt1On0oxHrwmrEUU05BjptQZNQprStZf/uIwee6F6bYwwsa0nly7UmKHHxWyOeap4x0ICmFg9WWvSX4DcpHdWUReydC2StTpe7WuZdkw+sRgYPTrcacZonKF2i2nOkCntij2omTxQERWovpNsmvfl1weC56TzR33wwS9S5ZFoqGrjK3hioHk5Yg9em9ESnLZUa6lwlNFIc7br5/3PB7c3gsUk90WurAWnNOq3cDrzvibfDxyYdAx1WDcZ0UKStwbngPvDcHOeCGk5QUGSOynviKvDaHGOgqBHKb2wGP6i5Cz43xwldpd3GJnAuWIRj+hO6MABJKvu58p4YemtiT/RYr0b3Tyte8oGX5pK8qAGg9WL3sV1cjum/NVKabjk5iMvPTbwa6e//IlBdWo14qAhU75wLkCkC1bs/qIlFFfZEBlSBMZADVcgTGVCFJM+A6o3kk5wDVWg1woAq4IkcqEKeyIAq4Ik7BlSBMZADVWgMZEAV8EQOVCFPZEAV8EQOVAFP5EAV8kQGVIHVCAeqt5LfSAZUAU/kQBX6JiUDqtBqhAFVwBM5UIU8kQHVW8krDlShcwEDqoAncqAaYqEncqAaYpEnMqD6D2v15QnHQA5Ufaz71eqJxsAFg/BY35HriXbIHMJhEdftM+6QWUSHRVw3+L+VLXhEh4VcGM8LJnHGQjCKBZcgLOKysWATiEXBjAqxiMvGglEsMfhRWS4bC3bBk+ojPuIjPiIc/wAQkAE6ZqHsywAAAABJRU5ErkJggg==" alt="Fork me on GitHub">
|
||||
</a>
|
||||
@@ -0,0 +1,7 @@
|
||||
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-W4XBCK"
|
||||
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-W4XBCK');</script>
|
||||
328
j2html-website/src/main/resources/public/css/main.css
Normal file
@@ -0,0 +1,328 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
font-family: arial, sans-serif;
|
||||
overflow-y: scroll;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
h1, h2, h3, nav a {
|
||||
font-family: 'Patua One', cursive;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
h1 + p, h2 + p, h3 + p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
h2, h3 {
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
pre + p {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#news h2:not(:first-of-type) {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #1272BF;
|
||||
}
|
||||
|
||||
p,
|
||||
li {
|
||||
font-family: "Lato", Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
|
||||
dt {
|
||||
font-family: monospace;
|
||||
font-weight: 700;
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.width-limit {
|
||||
padding: 0 20px;
|
||||
max-width: 940px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#github-stars {
|
||||
position: absolute;
|
||||
right: 27px;
|
||||
top: 10px;
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
font-size: 20px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#logo img {
|
||||
display: block;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.top-header nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.top-header ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.top-header li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.top-header ul li a {
|
||||
display: inline-block;
|
||||
padding: 8px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
background: #1272BF;
|
||||
margin: 0;
|
||||
color: white;
|
||||
padding: 0 25px;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
border-top: 3px solid #0d4d80;
|
||||
border-bottom: 3px solid #0d4d80;
|
||||
}
|
||||
|
||||
.banner h1 {
|
||||
font-size: 40px;
|
||||
text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
p code,
|
||||
li code {
|
||||
font-size: 85%;
|
||||
font-family: monospace;
|
||||
background: rgba(30, 177, 204, 0.1);
|
||||
border: 1px solid rgba(26, 142, 167, 0.49);
|
||||
padding: 1px 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
footer {
|
||||
font-size: 13px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
background: #f5f5f5;
|
||||
border-top: 1px solid #ddd;
|
||||
padding: 0 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.lols {
|
||||
text-align: center;
|
||||
font-size: 9px;
|
||||
margin: 0;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
#table-example {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
background: rgb(255, 255, 255);
|
||||
border-spacing: 5px 20px;
|
||||
font-weight: 700;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
#fork-me {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.banner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-header nav ul li {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.top-header nav ul li a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 460px) {
|
||||
#logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-header nav ul li {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.top-header nav ul li a {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prism */
|
||||
|
||||
.code-compare ul {
|
||||
background: #272822;
|
||||
border-radius: 5px 5px 0 0;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid #464644;
|
||||
padding: 0;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.code-compare ul li {
|
||||
color: #999;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
font-size: 13px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.code-compare ul li + li {
|
||||
border-left: 1px solid #464644;
|
||||
}
|
||||
|
||||
.code-compare pre {
|
||||
display: none;
|
||||
margin-top: 0;
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
.code-compare.with .with-switch,
|
||||
.code-compare.nowith .nowith-switch {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.code-compare.with .with-pre,
|
||||
.code-compare.nowith .nowith-pre {
|
||||
display: block;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #272822;
|
||||
padding: 15px !important;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
pre::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
pre::-webkit-scrollbar-thumb {
|
||||
background: #777;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
pre::-webkit-scrollbar-thumb:hover {
|
||||
background: #999;
|
||||
}
|
||||
|
||||
pre::-webkit-scrollbar-track {
|
||||
background: #333;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
pre::-webkit-scrollbar-button {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
#javalin-suggestion {
|
||||
line-height: 2;
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
right: 30px;
|
||||
padding: 20px 40px 20px 20px;
|
||||
background: #fff;
|
||||
box-shadow: 4px 4px 0 0px rgba(0, 0, 0, .2);
|
||||
z-index: 1;
|
||||
display: none;
|
||||
font-size: 17px;
|
||||
max-width: calc(100% - 60px);
|
||||
border: 2px solid #009ebe;
|
||||
}
|
||||
|
||||
#javalin-suggestion .close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#javalin-suggestion a {
|
||||
font-weight: 700;
|
||||
}
|
||||
121
j2html-website/src/main/resources/public/css/prism.css
Normal file
@@ -0,0 +1,121 @@
|
||||
/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+java */
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
* @author ocodia
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #f8f8f2;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Consolas, Monaco, 'Andale Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #272822;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.number {
|
||||
color: #ae81ff;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #a6e22e;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string,
|
||||
.token.variable {
|
||||
color: #f8f8f2;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.function {
|
||||
color: #e6db74;
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: #66d9ef;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
BIN
j2html-website/src/main/resources/public/img/favicon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
32
j2html-website/src/main/resources/public/img/favicon.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="512px" height="512px" viewBox="0 0 512 512" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Created with Lunacy</desc>
|
||||
<defs>
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="path_1" />
|
||||
<rect width="512" height="512" id="artboard_1" />
|
||||
<clipPath id="clip_1">
|
||||
<use xlink:href="#artboard_1" clip-rule="evenodd" />
|
||||
</clipPath>
|
||||
<clipPath id="mask_1">
|
||||
<use xlink:href="#path_1" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="Artboard-Copy-3" clip-path="url(#clip_1)">
|
||||
<g id="HTML5_Badge">
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="Background" fill="none" stroke="none" />
|
||||
<g clip-path="url(#mask_1)">
|
||||
<path d="M41 460L0 0L451 0L410 460L225 512" transform="translate(30 0)" id="Shape" fill="#1272BF" stroke="none" />
|
||||
<path d="M0 435L149 394L184 0L0 0" transform="translate(256 37)" id="Shape" fill="#FFFFFF" fill-opacity="0.21176471" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="coffee-icon-12" transform="translate(122.26813 68.45154)">
|
||||
<g id="Group">
|
||||
<path d="M109.76 63.5233C72.71 61.7926 37.5831 55.1903 18.2249 46.4086C5.14845 40.4472 -1.64617 32.627 0.340938 25.8965C3.22545 16.2815 18.7377 7.94844 45.8521 1.41021L51.7493 0L56.2363 4.23062C58.7362 6.53823 61.8771 9.16634 63.2232 10.1278C64.6975 11.0893 65.9154 12.4355 66.1718 13.4611C66.3641 14.4226 67.582 16.7302 68.864 18.5891C74.1202 26.2811 84.5686 31.1527 101.812 33.8449C112.452 35.5756 153.028 35.5756 164.117 33.909C181.424 31.2809 192.193 26.3452 197.449 18.5891C198.731 16.7302 199.949 14.4226 200.141 13.4611C200.398 12.4996 201.551 11.0893 202.897 10.1919C204.244 9.35865 207.384 6.66643 209.884 4.35882L214.564 1.95618e-05L220.461 1.41023C251.742 8.78175 269.177 19.9993 265.972 30.7681C264.818 34.55 261.677 38.2678 256.87 41.4728C233.025 57.3056 171.937 66.4719 109.76 63.5233L109.76 63.5233Z" transform="translate(0 276.47668)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M83.9789 173.473C64.877 172.256 51.8006 168.217 47.9546 162.32C47.3777 161.423 46.7367 159.435 46.6084 157.897C46.2879 155.397 45.9033 154.82 43.2752 152.961C38.5959 149.564 29.8142 140.334 25.0708 133.731C20.0069 126.68 12.1225 111.04 9.30215 102.45C3.14853 83.9255 0.199922 64.5031 0.00761933 41.8116C-0.0564799 29.1198 0.199922 27.8378 4.11003 22.838C6.73814 19.633 14.1738 14.6332 20.5197 12.0051C54.3005 -2.09699 127.952 -4.14819 171.732 7.83854C187.565 12.1974 198.334 18.6074 202.436 26.1712C204.038 29.0557 204.359 30.4659 204.615 35.8503L204.622 35.9837C204.936 41.9426 204.946 42.1293 206.282 41.7475C206.987 41.4911 210.833 41.2988 214.679 41.2988C225.384 41.3629 232.371 43.991 238.012 50.1447C250.96 64.2467 246.729 91.297 228.525 110.271C217.371 121.873 203.333 129.116 186.924 131.744L180.193 132.834L177.95 135.718C172.822 142.128 167.373 147.769 162.886 151.423C158.591 154.884 158.079 155.525 157.822 157.961C157.374 161.358 156.092 163.41 152.694 165.846C143.72 172.32 115.452 175.461 83.9789 173.473ZM179.103 35.2734C179.103 41.1706 159.104 46.9396 130.708 49.119C121.285 49.8241 97.4399 50.401 89.6838 50.0805C57.2491 48.6703 33.0833 44.1192 26.7374 38.1579C23.5965 35.2093 25.4554 31.9402 32.0577 28.9274C40.2625 25.1455 55.0056 22.0687 74.2997 20.2098C85.1967 19.1842 119.362 19.1842 130.067 20.2739C160.322 23.2225 179.103 28.9915 179.103 35.2734ZM48.5956 75.2078C49.9416 100.591 56.0312 124.565 65.3898 141.295C66.6077 143.539 67.5051 145.333 67.3128 145.333C66.159 145.333 50.9673 133.09 47.6981 129.501C36.737 117.514 28.8527 101.168 24.3657 81.2332C22.9555 74.695 20.5838 59.4391 20.9684 58.9904C21.0966 58.9263 23.8529 59.8878 27.1861 61.1698C30.5193 62.3877 36.4165 64.1185 40.3266 65.0159C44.1726 65.9133 47.5058 66.6824 47.7622 66.8107C47.9545 67.003 48.3391 70.7208 48.5956 75.2078ZM201.731 105.399C221.41 95.2071 231.089 77.4513 222.884 66.5543C220.256 63.0929 216.474 61.8109 210.064 62.1314C207.115 62.2596 204.423 62.7083 204.039 63.0929C203.654 63.4775 202.757 67.5158 202.116 72.0669C200.577 82.7075 198.205 92.9636 195.129 102.13C194.955 102.641 194.789 103.12 194.634 103.57C193.539 106.749 192.961 108.429 193.474 108.889C194.05 109.405 196 108.388 200.133 106.231C200.633 105.97 201.165 105.693 201.731 105.399Z" transform="translate(30.973198 125.50244)" id="Shape" fill="#FFFFFF" fill-rule="evenodd" stroke="none" />
|
||||
<path d="M1.14148 89.3819C4.64379 86.2444 7.12459 81.9395 8.43796 76.759C9.75133 71.5055 9.6054 66.5439 7.63534 50.4917C4.93565 29.113 10.335 17.4386 27.7007 6.93166C32.2975 4.23196 34.0486 3.28342 39.375 1.09447L41.9288 0L38.6454 2.77266C32.8812 7.66131 29.8896 11.3095 27.3358 16.563C23.5417 24.2243 22.885 30.2074 24.3443 43.633C25.7306 56.7666 25.8036 61.2175 24.4902 66.6169C22.4472 75.2997 15.5885 82.961 5.00862 88.3604C-0.536715 91.1331 -0.901539 91.206 1.14148 89.3819L1.14148 89.3819Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 109.50348 7.280884)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.2619 64.5395C7.44241 59.1401 8.53688 53.3759 6.63979 41.6286C4.15899 25.8682 5.54532 19.1554 12.9148 12.0048C16.0523 8.86735 19.1168 6.82434 24.6621 4.1976C34.2935 -0.472146 36.8472 -1.20179 32.6882 1.78976C27.9455 5.29208 24.5891 8.94032 22.4002 13.0993C20.5031 16.7476 20.4301 17.1853 20.722 26.3789C21.3057 46.7361 21.2328 49.5817 19.8464 52.1355C16.8549 57.6808 9.77728 63.2991 2.18894 66.1447L0 66.9473L2.26191 64.5395L2.2619 64.5395Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 67.97293 38.71814)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.43573 63.7984C7.25141 58.326 7.98106 53.5833 5.86508 40.8875C3.01946 23.5948 6.30288 14.7661 18.1961 7.32363C22.72 4.55097 33.2269 -0.410636 33.7376 0.0271519C33.8836 0.173082 32.2054 1.70534 30.0164 3.38353C25.2737 7.10474 22.2092 11.3367 20.458 16.5902C19.5095 19.6547 19.3635 21.7707 19.7284 27.0971C21.1877 47.3813 21.1877 47.4543 19.4365 51.4674C17.3935 56.356 12.3589 61.0257 5.64618 64.3821C2.80055 65.8414 0.319755 67.0089 0.0278784 67.0089C-0.191007 67.0089 0.903465 65.5496 2.43571 63.7984L2.43573 63.7984Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 160.54498 22.258545)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
BIN
j2html-website/src/main/resources/public/img/logo.fw.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
j2html-website/src/main/resources/public/img/logo.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
33
j2html-website/src/main/resources/public/img/logo.svg
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="1720px" height="512px" viewBox="0 0 1720 512" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
|
||||
<desc>Created with Lunacy</desc>
|
||||
<defs>
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="path_1" />
|
||||
<rect width="1720" height="512" id="artboard_1" />
|
||||
<clipPath id="clip_1">
|
||||
<use xlink:href="#artboard_1" clip-rule="evenodd" />
|
||||
</clipPath>
|
||||
<clipPath id="mask_1">
|
||||
<use xlink:href="#path_1" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="Artboard-Copy-2" clip-path="url(#clip_1)">
|
||||
<g id="HTML5_Badge">
|
||||
<path d="M0 0L512 0L512 512L0 512L0 0Z" id="Background" fill="none" stroke="none" />
|
||||
<g clip-path="url(#mask_1)">
|
||||
<path d="M41 460L0 0L451 0L410 460L225 512" transform="translate(30 0)" id="Shape" fill="#1272BF" stroke="none" />
|
||||
<path d="M0 435L149 394L184 0L0 0" transform="translate(256 37)" id="Shape" fill="#FFFFFF" fill-opacity="0.21176471" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="coffee-icon-12" transform="translate(122.26813 68.45154)">
|
||||
<g id="Group">
|
||||
<path d="M109.76 63.5233C72.71 61.7926 37.5831 55.1903 18.2249 46.4086C5.14845 40.4472 -1.64617 32.627 0.340938 25.8965C3.22545 16.2815 18.7377 7.94844 45.8521 1.41021L51.7493 0L56.2363 4.23062C58.7362 6.53823 61.8771 9.16634 63.2232 10.1278C64.6975 11.0893 65.9154 12.4355 66.1718 13.4611C66.3641 14.4226 67.582 16.7302 68.864 18.5891C74.1202 26.2811 84.5686 31.1527 101.812 33.8449C112.452 35.5756 153.028 35.5756 164.117 33.909C181.424 31.2809 192.193 26.3452 197.449 18.5891C198.731 16.7302 199.949 14.4226 200.141 13.4611C200.398 12.4996 201.551 11.0893 202.897 10.1919C204.244 9.35865 207.384 6.66643 209.884 4.35882L214.564 1.95618e-05L220.461 1.41023C251.742 8.78175 269.177 19.9993 265.972 30.7681C264.818 34.55 261.677 38.2678 256.87 41.4728C233.025 57.3056 171.937 66.4719 109.76 63.5233L109.76 63.5233Z" transform="translate(0 276.47668)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M83.9789 173.473C64.877 172.256 51.8006 168.217 47.9546 162.32C47.3777 161.423 46.7367 159.435 46.6084 157.897C46.2879 155.397 45.9033 154.82 43.2752 152.961C38.5959 149.564 29.8142 140.334 25.0708 133.731C20.0069 126.68 12.1225 111.04 9.30215 102.45C3.14853 83.9255 0.199922 64.5031 0.00761933 41.8116C-0.0564799 29.1198 0.199922 27.8378 4.11003 22.838C6.73814 19.633 14.1738 14.6332 20.5197 12.0051C54.3005 -2.09699 127.952 -4.14819 171.732 7.83854C187.565 12.1974 198.334 18.6074 202.436 26.1712C204.038 29.0557 204.359 30.4659 204.615 35.8503L204.622 35.9837C204.936 41.9426 204.946 42.1293 206.282 41.7475C206.987 41.4911 210.833 41.2988 214.679 41.2988C225.384 41.3629 232.371 43.991 238.012 50.1447C250.96 64.2467 246.729 91.297 228.525 110.271C217.371 121.873 203.333 129.116 186.924 131.744L180.193 132.834L177.95 135.718C172.822 142.128 167.373 147.769 162.886 151.423C158.591 154.884 158.079 155.525 157.822 157.961C157.374 161.358 156.092 163.41 152.694 165.846C143.72 172.32 115.452 175.461 83.9789 173.473ZM179.103 35.2734C179.103 41.1706 159.104 46.9396 130.708 49.119C121.285 49.8241 97.4399 50.401 89.6838 50.0805C57.2491 48.6703 33.0833 44.1192 26.7374 38.1579C23.5965 35.2093 25.4554 31.9402 32.0577 28.9274C40.2625 25.1455 55.0056 22.0687 74.2997 20.2098C85.1967 19.1842 119.362 19.1842 130.067 20.2739C160.322 23.2225 179.103 28.9915 179.103 35.2734ZM48.5956 75.2078C49.9416 100.591 56.0312 124.565 65.3898 141.295C66.6077 143.539 67.5051 145.333 67.3128 145.333C66.159 145.333 50.9673 133.09 47.6981 129.501C36.737 117.514 28.8527 101.168 24.3657 81.2332C22.9555 74.695 20.5838 59.4391 20.9684 58.9904C21.0966 58.9263 23.8529 59.8878 27.1861 61.1698C30.5193 62.3877 36.4165 64.1185 40.3266 65.0159C44.1726 65.9133 47.5058 66.6824 47.7622 66.8107C47.9545 67.003 48.3391 70.7208 48.5956 75.2078ZM201.731 105.399C221.41 95.2071 231.089 77.4513 222.884 66.5543C220.256 63.0929 216.474 61.8109 210.064 62.1314C207.115 62.2596 204.423 62.7083 204.039 63.0929C203.654 63.4775 202.757 67.5158 202.116 72.0669C200.577 82.7075 198.205 92.9636 195.129 102.13C194.955 102.641 194.789 103.12 194.634 103.57C193.539 106.749 192.961 108.429 193.474 108.889C194.05 109.405 196 108.388 200.133 106.231C200.633 105.97 201.165 105.693 201.731 105.399Z" transform="translate(30.973198 125.50244)" id="Shape" fill="#FFFFFF" fill-rule="evenodd" stroke="none" />
|
||||
<path d="M1.14148 89.3819C4.64379 86.2444 7.12459 81.9395 8.43796 76.759C9.75133 71.5055 9.6054 66.5439 7.63534 50.4917C4.93565 29.113 10.335 17.4386 27.7007 6.93166C32.2975 4.23196 34.0486 3.28342 39.375 1.09447L41.9288 0L38.6454 2.77266C32.8812 7.66131 29.8896 11.3095 27.3358 16.563C23.5417 24.2243 22.885 30.2074 24.3443 43.633C25.7306 56.7666 25.8036 61.2175 24.4902 66.6169C22.4472 75.2997 15.5885 82.961 5.00862 88.3604C-0.536715 91.1331 -0.901539 91.206 1.14148 89.3819L1.14148 89.3819Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 109.50348 7.280884)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.2619 64.5395C7.44241 59.1401 8.53688 53.3759 6.63979 41.6286C4.15899 25.8682 5.54532 19.1554 12.9148 12.0048C16.0523 8.86735 19.1168 6.82434 24.6621 4.1976C34.2935 -0.472146 36.8472 -1.20179 32.6882 1.78976C27.9455 5.29208 24.5891 8.94032 22.4002 13.0993C20.5031 16.7476 20.4301 17.1853 20.722 26.3789C21.3057 46.7361 21.2328 49.5817 19.8464 52.1355C16.8549 57.6808 9.77728 63.2991 2.18894 66.1447L0 66.9473L2.26191 64.5395L2.2619 64.5395Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 67.97293 38.71814)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
<path d="M2.43573 63.7984C7.25141 58.326 7.98106 53.5833 5.86508 40.8875C3.01946 23.5948 6.30288 14.7661 18.1961 7.32363C22.72 4.55097 33.2269 -0.410636 33.7376 0.0271519C33.8836 0.173082 32.2054 1.70534 30.0164 3.38353C25.2737 7.10474 22.2092 11.3367 20.458 16.5902C19.5095 19.6547 19.3635 21.7707 19.7284 27.0971C21.1877 47.3813 21.1877 47.4543 19.4365 51.4674C17.3935 56.356 12.3589 61.0257 5.64618 64.3821C2.80055 65.8414 0.319755 67.0089 0.0278784 67.0089C-0.191007 67.0089 0.903465 65.5496 2.43571 63.7984L2.43573 63.7984Z" transform="matrix(0.9848077 -0.17364818 0.17364818 0.9848077 160.54498 22.258545)" id="Shape" fill="#FFFFFF" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
<path d="M364 10.8L376.4 0L438 0L422.8 125.2C428.667 115.067 436.267 106.867 445.6 100.6C454.933 94.3334 465.867 91.2 478.4 91.2Q502.8 91.2 519 106.4C529.8 116.533 533.867 132.267 531.2 153.6L521.2 236L544.4 236L540.8 265.2L528.8 275.2L467.2 275.2L479.6 173.6C481.733 158.133 480.667 147.067 476.4 140.4C472.133 133.733 465.067 130.4 455.2 130.4C443.733 130.4 435.067 134 429.2 141.2Q420.4 152 417.2 169.6L404.4 275.2L354.8 275.2L383.6 39.2L360.4 39.2L364 10.8ZM1052 0L1039.6 10.8L1036 39.2L1060.8 39.2L1032 275.2L1094 275.2L1106 265.2L1109.6 236L1086.4 236L1115.2 0L1052 0ZM79.2 62.8L82.0851 35.1857Q82.1542 34.5246 82.2534 33.8673Q82.3527 33.2101 82.482 32.5581Q82.6113 31.9061 82.7704 31.2607Q82.9294 30.6154 83.1178 29.9779Q83.3063 29.3405 83.5237 28.7124Q83.7411 28.0843 83.9872 27.4668Q84.2331 26.8493 84.5072 26.2437Q84.7812 25.6381 85.0827 25.0458Q85.3842 24.4534 85.7125 23.8754Q86.0408 23.2975 86.3953 22.7352Q86.7497 22.1729 87.1295 21.6274Q87.5094 21.0819 87.9138 20.5545Q88.3183 20.027 88.7464 19.5186Q89.1746 19.0101 89.6256 18.5219Q90.0767 18.0336 90.5496 17.5666Q91.0225 17.0995 91.5163 16.6546Q92.0101 16.2097 92.5238 15.7878Q93.0375 15.366 93.57 14.9682Q94.1025 14.5703 94.6526 14.1973Q95.2028 13.8243 95.7694 13.4768Q96.3361 13.1294 96.9181 12.8083Q97.5 12.4872 98.0961 12.1931Q98.6922 11.899 99.3012 11.6325Q99.9101 11.366 100.531 11.1277Q101.151 10.8894 101.782 10.6798Q102.413 10.4702 103.052 10.2897Q103.692 10.1092 104.339 9.95819Q104.987 9.80719 105.64 9.68601Q106.294 9.56483 106.952 9.47372Q107.611 9.38261 108.273 9.32177Q108.934 9.26092 109.598 9.23047Q110.262 9.20001 110.927 9.20001L132.8 9.20001L129.915 36.8144Q129.846 37.4754 129.747 38.1327Q129.647 38.7899 129.518 39.4419Q129.389 40.0939 129.23 40.7393Q129.071 41.3847 128.882 42.0221Q128.694 42.6595 128.476 43.2876Q128.259 43.9157 128.013 44.5332Q127.767 45.1507 127.493 45.7563Q127.219 46.3619 126.917 46.9543Q126.616 47.5466 126.288 48.1246Q125.959 48.7025 125.605 49.2648Q125.25 49.8271 124.87 50.3726Q124.491 50.9181 124.086 51.4456Q123.682 51.9731 123.254 52.4815Q122.825 52.9899 122.374 53.4781Q121.923 53.9664 121.45 54.4334Q120.978 54.9005 120.484 55.3454Q119.99 55.7904 119.476 56.2122Q118.963 56.634 118.43 57.0319Q117.898 57.4297 117.347 57.8027Q116.797 58.1758 116.231 58.5232Q115.664 58.8706 115.082 59.1917Q114.5 59.5128 113.904 59.8069Q113.308 60.101 112.699 60.3675Q112.09 60.634 111.469 60.8723Q110.849 61.1106 110.218 61.3202Q109.587 61.5298 108.948 61.7103Q108.308 61.8908 107.661 62.0418Q107.013 62.1928 106.36 62.314Q105.706 62.4352 105.048 62.5263Q104.389 62.6174 103.727 62.6782Q103.066 62.7391 102.402 62.7695Q101.738 62.8 101.073 62.8L79.2 62.8ZM578.8 94.8L565.2 107.2L561.6 134L585.6 134L574.8 221.2C572.667 239.867 576.867 254.2 587.4 264.2C597.933 274.2 612.8 279.2 632 279.2C649.867 279.2 663.733 274.4 673.6 264.8C683.467 255.2 690.933 240 696 219.2L661.2 207.6Q656 228.4 649.8 234.2C645.667 238.067 641.467 240 637.2 240Q632.752 240 629.894 237.868Q623.241 232.907 625.2 216.4L635.2 134L676.8 134L690.4 121.2L694 94.8L640 94.8L646.8 40.0001L610.8 40.0001L595.2 56L590.4 94.8L578.8 94.8ZM158.4 139.6L198.4 144L207.6 114.4C211.867 112.267 217.2 110.733 223.6 109.8C230 108.867 235.467 108.4 240 108.4C248.8 108.4 256.333 110 262.6 113.2C268.867 116.4 272 122 272 130C272 140.933 265.933 151.733 253.8 162.4Q235.6 178.4 206.2 195.4C186.6 206.733 165.467 219.2 142.8 232.8L143.2 275.2L321.2 275.2L330 204.4L288.8 200.4L284.4 229.6L206.8 229.6C225.2 220.267 243.867 210.667 262.8 200.8C281.733 190.933 297.6 179.4 310.4 166.2Q329.6 146.4 329.6 118.4Q329.6 96 313.2 79.4C302.267 68.3333 282.533 62.8 254 62.8Q240 62.8 218.4 65.8Q196.8 68.8 173.6 78.4L158.4 139.6ZM724 94.8L779.6 94.8L781.2 129.6C787.333 118.133 795.2 108.867 804.8 101.8C814.4 94.7334 826 91.2 839.6 91.2C852.667 91.2 863.6 94.4667 872.4 101C881.2 107.533 886.533 117.6 888.4 131.2Q897.6 113.6 912.2 102.4C921.933 94.9333 933.733 91.2 947.6 91.2C963.867 91.2 976.733 96.2667 986.2 106.4C995.667 116.533 999.067 132.267 996.4 153.6L986.4 236L1009.6 236L1006 265.2L994 275.2L932.4 275.2L944.8 173.6C946.667 158.133 945.733 147.067 942 140.4C938.267 133.733 931.467 130.4 921.6 130.4Q903.6 130.4 896 142.4C890.933 150.4 887.6 160.667 886 173.2L873.6 275.2L824.4 275.2L836.8 173.6C838.667 158.133 837.733 147.067 834 140.4C830.267 133.733 823.467 130.4 813.6 130.4Q795.6 130.4 788 142.4C782.933 150.4 779.6 160.667 778 173.2L765.6 275.2L716 275.2L733.2 134L708 134L711.6 105.6L724 94.8ZM57.2 94.8L44.8 105.6L41.2 134L70.4 134L54 268.8Q48.8 312 35.4 319.2C26.4667 324 15.3333 323.867 2 318.8L0 352Q17.2 364 40 364C58.9333 364 73.3333 354.933 83.2 336.8C93.0667 318.667 99.7333 296 103.2 268.8L124.8 94.8L57.2 94.8Z" transform="translate(592 103.83917)" id="j2html" fill="#222222" fill-rule="evenodd" stroke="none" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
BIN
j2html-website/src/main/resources/public/img/logo_teal.fw.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
j2html-website/src/main/resources/public/img/logo_teal.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |