提交 31ed2e1e authored 作者: Thomas Mueller's avatar Thomas Mueller

HTML railroad diagrams

上级 c4ae4586
...@@ -24,9 +24,14 @@ Data Types ...@@ -24,9 +24,14 @@ Data Types
<c:forEach var="item" items="dataTypes"> <c:forEach var="item" items="dataTypes">
<h3 id="${item.link}" class="notranslate">${item.topic}</h3> <h3 id="${item.link}" class="notranslate">${item.topic}</h3>
<!-- railroad-start -->
${item.railroad}
<!-- railroad-end -->
<!-- syntax-start
<pre> <pre>
${item.syntax} ${item.syntax}
</pre> </pre>
syntax-end -->
<p>${item.text}</p> <p>${item.text}</p>
<b>Example:</b> <b>Example:</b>
<p class="notranslate">${item.example}</p> <p class="notranslate">${item.example}</p>
......
...@@ -54,9 +54,14 @@ Functions ...@@ -54,9 +54,14 @@ Functions
<c:forEach var="item" items="functionsAll"> <c:forEach var="item" items="functionsAll">
<h3 id="${item.link}" class="notranslate">${item.topic}</h3> <h3 id="${item.link}" class="notranslate">${item.topic}</h3>
<!-- railroad-start -->
${item.railroad}
<!-- railroad-end -->
<!-- syntax-start
<pre> <pre>
${item.syntax} ${item.syntax}
</pre> </pre>
syntax-end -->
<p>${item.text}</p> <p>${item.text}</p>
<b>Example:</b> <b>Example:</b>
<p class="notranslate">${item.example}</p> <p class="notranslate">${item.example}</p>
......
...@@ -52,9 +52,14 @@ SQL Grammar ...@@ -52,9 +52,14 @@ SQL Grammar
<c:forEach var="item" items="commands"> <c:forEach var="item" items="commands">
<h3 id="${item.link}" class="notranslate">${item.topic}</h3> <h3 id="${item.link}" class="notranslate">${item.topic}</h3>
<!-- railroad-start -->
${item.railroad}
<!-- railroad-end -->
<!-- syntax-start
<pre> <pre>
${item.syntax} ${item.syntax}
</pre> </pre>
syntax-end -->
<p>${item.text}</p> <p>${item.text}</p>
<b>Example:</b> <b>Example:</b>
<p class="notranslate">${item.example}</p> <p class="notranslate">${item.example}</p>
...@@ -62,9 +67,14 @@ ${item.syntax} ...@@ -62,9 +67,14 @@ ${item.syntax}
<c:forEach var="item" items="otherGrammar"> <c:forEach var="item" items="otherGrammar">
<h3 id="${item.link}" class="notranslate">${item.topic}</h3> <h3 id="${item.link}" class="notranslate">${item.topic}</h3>
<!-- railroad-start -->
${item.railroad}
<!-- railroad-end -->
<!-- syntax-start
<pre> <pre>
${item.syntax} ${item.syntax}
</pre> </pre>
syntax-end -->
<p>${item.text}</p> <p>${item.text}</p>
<b>Example:</b> <b>Example:</b>
<p class="notranslate">${item.example}</p> <p class="notranslate">${item.example}</p>
......
...@@ -210,3 +210,90 @@ td.content { ...@@ -210,3 +210,90 @@ td.content {
.compareN { .compareN {
color: #800; color: #800;
} }
.railroad {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
}
.c {
padding: 1px 3px;
margin: 0px 0px;
border: 2px solid;
-moz-border-radius: 0.4em;
border-radius: 0.4em;
background-color: #fff;
}
.ts {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ts.png);
width: 16px;
}
.ls {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ls.png);
width: 16px;
}
.ks {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ks.png);
width: 16px;
}
.te {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-te.png);
width: 16px;
}
.le {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-le.png);
width: 16px;
}
.ke {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ke.png);
width: 16px;
}
.d {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-d.png);
background-repeat: repeat-x;
min-width: 16px;
}
...@@ -127,3 +127,90 @@ em.u { ...@@ -127,3 +127,90 @@ em.u {
.compareN { .compareN {
color: #800; color: #800;
} }
.railroad {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
}
.c {
padding: 1px 3px;
margin: 0px 0px;
border: 2px solid;
-moz-border-radius: 0.4em;
border-radius: 0.4em;
background-color: #fff;
}
.ts {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ts.png);
width: 16px;
}
.ls {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ls.png);
width: 16px;
}
.ks {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ks.png);
width: 16px;
}
.te {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-te.png);
width: 16px;
}
.le {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-le.png);
width: 16px;
}
.ke {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-ke.png);
width: 16px;
}
.d {
border: 0px;
padding: 0px;
margin: 0px;
border-collapse: collapse;
vertical-align: top;
height: 24px;
background-image: url(images/div-d.png);
background-repeat: repeat-x;
min-width: 16px;
}
...@@ -8120,7 +8120,7 @@ Bugfixes ...@@ -8120,7 +8120,7 @@ Bugfixes
Page store: new storage mechanism Page store: new storage mechanism
@roadmap_1009_li @roadmap_1009_li
[Requires page store] Support large updates (use the transaction log for rollback). [Requires page store] Support large updates (use the transaction log for rollback instead of persistent UndoLog.file).
@roadmap_1010_li @roadmap_1010_li
[Requires page store] Shutdown compact [Requires page store] Shutdown compact
......
...@@ -8120,7 +8120,7 @@ H2 コンソール アプリケーション ...@@ -8120,7 +8120,7 @@ H2 コンソール アプリケーション
#Page store: new storage mechanism #Page store: new storage mechanism
@roadmap_1009_li @roadmap_1009_li
#[Requires page store] Support large updates (use the transaction log for rollback). #[Requires page store] Support large updates (use the transaction log for rollback instead of persistent UndoLog.file).
@roadmap_1010_li @roadmap_1010_li
#[Requires page store] Shutdown compact #[Requires page store] Shutdown compact
......
...@@ -2705,7 +2705,7 @@ roadmap_1005_li=Enable the system property h2.pageStore by default. ...@@ -2705,7 +2705,7 @@ roadmap_1005_li=Enable the system property h2.pageStore by default.
roadmap_1006_h2=Priority 1 roadmap_1006_h2=Priority 1
roadmap_1007_li=Bugfixes roadmap_1007_li=Bugfixes
roadmap_1008_li=Page store\: new storage mechanism roadmap_1008_li=Page store\: new storage mechanism
roadmap_1009_li=[Requires page store] Support large updates (use the transaction log for rollback). roadmap_1009_li=[Requires page store] Support large updates (use the transaction log for rollback instead of persistent UndoLog.file).
roadmap_1010_li=[Requires page store] Shutdown compact roadmap_1010_li=[Requires page store] Shutdown compact
roadmap_1011_li=More tests with MULTI_THREADED\=1 roadmap_1011_li=More tests with MULTI_THREADED\=1
roadmap_1012_li=RECOVER\=1 should automatically recover, \=2 should run the recovery tool if required roadmap_1012_li=RECOVER\=1 should automatically recover, \=2 should run the recovery tool if required
......
...@@ -31,6 +31,11 @@ import org.h2.util.StringUtils; ...@@ -31,6 +31,11 @@ import org.h2.util.StringUtils;
public class Bnf { public class Bnf {
private final Random random = new Random(); private final Random random = new Random();
/**
* The rule map. The key is lowercase, and all spaces
* are replaces with underscore.
*/
private final HashMap<String, RuleHead> ruleMap = New.hashMap(); private final HashMap<String, RuleHead> ruleMap = New.hashMap();
private String syntax; private String syntax;
private String currentToken; private String currentToken;
...@@ -68,10 +73,11 @@ public class Bnf { ...@@ -68,10 +73,11 @@ public class Bnf {
private RuleHead addRule(String topic, String section, Rule rule) { private RuleHead addRule(String topic, String section, Rule rule) {
RuleHead head = new RuleHead(section, topic, rule); RuleHead head = new RuleHead(section, topic, rule);
if (ruleMap.get(StringUtils.toLowerEnglish(topic)) != null) { String key = StringUtils.toLowerEnglish(topic.trim().replace(' ', '_'));
if (ruleMap.get(key) != null) {
throw new AssertionError("already exists: " + topic); throw new AssertionError("already exists: " + topic);
} }
ruleMap.put(StringUtils.toLowerEnglish(topic), head); ruleMap.put(key, head);
return head; return head;
} }
...@@ -88,9 +94,7 @@ public class Bnf { ...@@ -88,9 +94,7 @@ public class Bnf {
if (section.startsWith("System")) { if (section.startsWith("System")) {
continue; continue;
} }
String topic = StringUtils.toLowerEnglish(rs.getString("TOPIC").trim()); String topic = rs.getString("TOPIC");
topic = StringUtils.replaceAll(topic, " ", "_");
// topic = StringUtils.replaceAll(topic, "_", "");
syntax = rs.getString("SYNTAX").trim(); syntax = rs.getString("SYNTAX").trim();
currentTopic = section; currentTopic = section;
if (section.startsWith("Function")) { if (section.startsWith("Function")) {
...@@ -131,6 +135,32 @@ public class Bnf { ...@@ -131,6 +135,32 @@ public class Bnf {
addFixedRule("@digit@", RuleFixed.DIGIT); addFixedRule("@digit@", RuleFixed.DIGIT);
} }
/**
* Get the HTML railroad for a given syntax.
*
* @param syntax the syntax
* @return the HTML formatted railroad
*/
public String getRailroadHtml(String syntax) {
syntax = StringUtils.replaceAll(syntax, "\n ", " ");
String[] syntaxList = StringUtils.arraySplit(syntax, '\n', true);
StringBuilder buff = new StringBuilder();
for (String s : syntaxList) {
this.syntax = s;
tokens = tokenize();
index = 0;
Rule rule = parseRule();
rule.setLinks(ruleMap);
String html = rule.getHtmlRailroad(this, false);
html = StringUtils.replaceAll(html, "</code></td><td class=\"d\"><code class=\"c\">", " ");
if (buff.length() > 0) {
buff.append("<br />");
}
buff.append(html);
}
return buff.toString();
}
/** /**
* Get the HTML documentation for a given syntax. * Get the HTML documentation for a given syntax.
* *
...@@ -138,40 +168,77 @@ public class Bnf { ...@@ -138,40 +168,77 @@ public class Bnf {
* @return the HTML formatted text * @return the HTML formatted text
*/ */
public String getSyntaxHtml(String bnf) { public String getSyntaxHtml(String bnf) {
bnf = StringUtils.replaceAll(bnf, "\n ", "\n");
StringTokenizer tokenizer = getTokenizer(bnf); StringTokenizer tokenizer = getTokenizer(bnf);
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
while (tokenizer.hasMoreTokens()) { while (tokenizer.hasMoreTokens()) {
String s = tokenizer.nextToken(); String s = tokenizer.nextToken();
if (s.length() == 1 || StringUtils.toUpperEnglish(s).equals(s)) { if (s.length() == 1 || StringUtils.toUpperEnglish(s).equals(s)) {
buff.append(s); buff.append(StringUtils.xmlText(s));
continue; continue;
} }
RuleHead found = null; buff.append(getLink(s));
for (int i = 0; i < s.length(); i++) { }
String test = StringUtils.toLowerEnglish(s.substring(i)); String s = buff.toString();
RuleHead r = ruleMap.get(test); // ensure it works within XHTML comments
if (r != null) { s = StringUtils.replaceAll(s, "--", "&#45;-");
found = r; return s;
break; }
}
} /**
if (found == null || found.getRule() instanceof RuleFixed) { * Convert convert ruleLink to rule_link.
buff.append(s); *
continue; * @param token the token
} * @return the rule map key
String page = "grammar.html"; */
if (found.getSection().startsWith("Data Types")) { static String getRuleMapKey(String token) {
page = "datatypes.html"; StringBuilder buff = new StringBuilder();
} else if (found.getSection().startsWith("Functions")) { for (char ch : token.toCharArray()) {
page = "functions.html"; if (Character.isUpperCase(ch)) {
buff.append('_').append(Character.toLowerCase(ch));
} else {
buff.append(ch);
} }
String link = StringUtils.urlEncode(found.getTopic().toLowerCase());
buff.append("<a href=\"").append(page).append("#").
append(link).append("\">").append(s).append("</a>");
} }
return buff.toString(); return buff.toString();
} }
/**
* Get the HTML link for the given token, or the token itself if no link
* exists.
*
* @param token the token
* @return the HTML link
*/
String getLink(String token) {
RuleHead found = null;
String key = getRuleMapKey(token);
for (int i = 0; i < token.length(); i++) {
String test = StringUtils.toLowerEnglish(key.substring(i));
RuleHead r = ruleMap.get(test);
if (r != null) {
found = r;
break;
}
}
if (found == null) {
return token;
}
String page = "grammar.html";
if (found.getSection().startsWith("Data Types")) {
page = "datatypes.html";
} else if (found.getSection().startsWith("Functions")) {
page = "functions.html";
} else if (token.equals("@func@")) {
return "<a href=\"functions.html\">Function</a>";
} else if (found.getRule() instanceof RuleFixed) {
return found.getRule().getHtmlRailroad(this, false);
}
String link = found.getTopic().toLowerCase().replace(' ', '_');
link = page + "#" + StringUtils.urlEncode(link);
return "<a href=\"" + link + "\">" + token + "</a>";
}
private Rule parseRule() { private Rule parseRule() {
read(); read();
return parseOr(); return parseOr();
...@@ -216,9 +283,9 @@ public class Bnf { ...@@ -216,9 +283,9 @@ public class Bnf {
} }
} else if ("@commaDots@".equals(currentToken)) { } else if ("@commaDots@".equals(currentToken)) {
r = new RuleList(new RuleElement(",", currentTopic), lastRepeat, false); r = new RuleList(new RuleElement(",", currentTopic), lastRepeat, false);
r = new RuleRepeat(r); r = new RuleRepeat(r, true);
} else if ("@dots@".equals(currentToken)) { } else if ("@dots@".equals(currentToken)) {
r = new RuleRepeat(lastRepeat); r = new RuleRepeat(lastRepeat, false);
} else { } else {
r = new RuleElement(currentToken, currentTopic); r = new RuleElement(currentToken, currentTopic);
} }
......
...@@ -62,4 +62,13 @@ public interface Rule { ...@@ -62,4 +62,13 @@ public interface Rule {
*/ */
boolean matchRemove(Sentence sentence); boolean matchRemove(Sentence sentence);
/**
* Get the HTML railroad.
*
* @param config the configuration
* @param topLevel true if line break are permitted
* @return the railroad
*/
String getHtmlRailroad(Bnf config, boolean topLevel);
} }
...@@ -33,6 +33,16 @@ public class RuleElement implements Rule { ...@@ -33,6 +33,16 @@ public class RuleElement implements Rule {
return name; return name;
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
String x;
if (keyword) {
x = StringUtils.xmlText(name.trim());
} else {
x = config.getLink(name.trim());
}
return "<code class=\"c\">" + x + "</code>";
}
public String random(Bnf config, int level) { public String random(Bnf config, int level) {
if (keyword) { if (keyword) {
return name.length() > 1 ? " " + name + " " : name; return name.length() > 1 ? " " + name + " " : name;
...@@ -58,17 +68,8 @@ public class RuleElement implements Rule { ...@@ -58,17 +68,8 @@ public class RuleElement implements Rule {
if (keyword) { if (keyword) {
return; return;
} }
StringBuilder buff = new StringBuilder(); String test = Bnf.getRuleMapKey(name);
for (char c : name.toCharArray()) { for (int i = 0; i < test.length(); i++) {
if (Character.isUpperCase(c)) {
buff.append('_');
buff.append(Character.toLowerCase(c));
} else {
buff.append(c);
}
}
String test = buff.toString();
for (int i = 0; i < name.length(); i++) {
String t = test.substring(i); String t = test.substring(i);
RuleHead r = ruleMap.get(t); RuleHead r = ruleMap.get(t);
if (r != null) { if (r != null) {
......
...@@ -59,6 +59,41 @@ public class RuleFixed implements Rule { ...@@ -59,6 +59,41 @@ public class RuleFixed implements Rule {
} }
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
return getHtmlText();
}
public String getHtmlText() {
switch(type) {
case YMD:
return "2000-01-01";
case HMS:
return "12:00";
case NANOS:
return "0";
case ANY_UNTIL_EOL:
case ANY_EXCEPT_SINGLE_QUOTE:
case ANY_EXCEPT_DOUBLE_QUOTE:
case ANY_WORD:
case ANY_EXCEPT_2_DOLLAR:
case ANY_UNTIL_END: {
return "anything";
}
case HEX_START:
return "0x";
case CONCAT:
return "||";
case AZ_UNDERSCORE:
return "A-Z | _";
case AF:
return "A-F";
case DIGIT:
return "0-9";
default:
throw new AssertionError("type="+type);
}
}
public String random(Bnf config, int level) { public String random(Bnf config, int level) {
Random r = config.getRandom(); Random r = config.getRandom();
switch(type) { switch(type) {
......
...@@ -53,6 +53,40 @@ public class RuleList implements Rule { ...@@ -53,6 +53,40 @@ public class RuleList implements Rule {
return buff.toString(); return buff.toString();
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
StringBuilder buff = new StringBuilder();
if (or) {
buff.append("<table class=\"railroad\">");
int i = 0;
for (Rule r : list) {
String a = i == 0 ? "t" : i == list.size() - 1 ? "l" : "k";
i++;
buff.append("<tr class=\"railroad\"><td class=\"" + a + "s\"></td><td class=\"d\">");
buff.append(r.getHtmlRailroad(config, false));
buff.append("</td><td class=\"" + a + "e\"></td></tr>");
}
buff.append("</table>");
} else {
if (!topLevel) {
buff.append("<table class=\"railroad\">");
buff.append("<tr class=\"railroad\">");
}
for (Rule r : list) {
if (!topLevel) {
buff.append("<td class=\"d\">");
}
buff.append(r.getHtmlRailroad(config, false));
if (!topLevel) {
buff.append("</td>");
}
}
if (!topLevel) {
buff.append("</tr></table>");
}
}
return buff.toString();
}
public String random(Bnf config, int level) { public String random(Bnf config, int level) {
if (or) { if (or) {
if (level > 10) { if (level > 10) {
......
...@@ -23,6 +23,16 @@ public class RuleOptional implements Rule { ...@@ -23,6 +23,16 @@ public class RuleOptional implements Rule {
return "[" + rule.toString() + "]"; return "[" + rule.toString() + "]";
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
StringBuilder buff = new StringBuilder();
buff.append("<table class=\"railroad\">");
buff.append("<tr class=\"railroad\"><td class=\"ts\"></td><td class=\"d\">&nbsp;</td><td class=\"te\"></td></tr>");
buff.append("<tr class=\"railroad\"><td class=\"ls\"></td><td class=\"d\">");
buff.append(rule.getHtmlRailroad(config, false));
buff.append("</td><td class=\"le\"></td></tr></table>");
return buff.toString();
}
public String name() { public String name() {
return null; return null;
} }
......
...@@ -13,16 +13,41 @@ import java.util.HashMap; ...@@ -13,16 +13,41 @@ import java.util.HashMap;
*/ */
public class RuleRepeat implements Rule { public class RuleRepeat implements Rule {
private Rule rule; private static final boolean RAILROAD_DOTS = true;
RuleRepeat(Rule rule) { private final Rule rule;
private final boolean comma;
RuleRepeat(Rule rule, boolean comma) {
this.rule = rule; this.rule = rule;
this.comma = comma;
} }
public String toString() { public String toString() {
return "..."; return "...";
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
StringBuilder buff = new StringBuilder();
if (RAILROAD_DOTS) {
buff.append("<code class=\"c\">");
if (comma) {
buff.append(", ");
}
buff.append("...</code>");
} else {
buff.append("<table class=\"railroad\">");
buff.append("<tr class=\"railroad\"><td class=\"te\"></td>");
buff.append("<td class=\"d\">");
buff.append(rule.getHtmlRailroad(config, false));
buff.append("</td><td class=\"ts\"></td></tr>");
buff.append("<tr class=\"railroad\"><td class=\"ls\"></td>");
buff.append("<td class=\"d\">&nbsp;</td>");
buff.append("<td class=\"le\"></td></tr></table>");
}
return buff.toString();
}
public String name() { public String name() {
return rule.name(); return rule.name();
} }
......
...@@ -476,4 +476,9 @@ public class DbContextRule implements Rule { ...@@ -476,4 +476,9 @@ public class DbContextRule implements Rule {
} }
return best; return best;
} }
public String getHtmlRailroad(Bnf config, boolean topLevel) {
return null;
}
} }
...@@ -133,7 +133,7 @@ public class PageParser { ...@@ -133,7 +133,7 @@ public class PageParser {
break; break;
} }
case '$': case '$':
if (p.charAt(i + 1) == '{') { if (p.length() > i + 1 && p.charAt(i + 1) == '{') {
i += 2; i += 2;
int j = p.indexOf('}', i); int j = p.indexOf('}', i);
if (j < 0) { if (j < 0) {
......
...@@ -297,9 +297,12 @@ java org.h2.test.TestAll timer ...@@ -297,9 +297,12 @@ java org.h2.test.TestAll timer
/* /*
serialized patches
check if sources.jar is not in installer and zip, but in h2web check if sources.jar is not in installer and zip, but in h2web
documentation: rolling review at history.html documentation: rolling review at history.html
html sql railroads math utils compareTo?
toArray?
mvcc merge problem mvcc merge problem
......
...@@ -59,28 +59,30 @@ public class GenerateDoc { ...@@ -59,28 +59,30 @@ public class GenerateDoc {
Class.forName("org.h2.Driver"); Class.forName("org.h2.Driver");
conn = DriverManager.getConnection("jdbc:h2:mem:"); conn = DriverManager.getConnection("jdbc:h2:mem:");
new File(outDir).mkdirs(); new File(outDir).mkdirs();
new RailroadImages().run(outDir + "/images");
bnf = Bnf.getInstance(null); bnf = Bnf.getInstance(null);
bnf.linkStatements();
session.put("version", Constants.getVersion()); session.put("version", Constants.getVersion());
session.put("versionDate", Constants.BUILD_DATE); session.put("versionDate", Constants.BUILD_DATE);
session.put("stableVersion", Constants.getVersionStable()); session.put("stableVersion", Constants.getVersionStable());
session.put("stableVersionDate", Constants.BUILD_DATE_STABLE); session.put("stableVersionDate", Constants.BUILD_DATE_STABLE);
// String help = "SELECT * FROM INFORMATION_SCHEMA.HELP WHERE SECTION"; // String help = "SELECT * FROM INFORMATION_SCHEMA.HELP WHERE SECTION";
String help = "SELECT ROWNUM ID, * FROM CSVREAD('" + inHelp + "') WHERE SECTION "; String help = "SELECT ROWNUM ID, * FROM CSVREAD('" + inHelp + "') WHERE SECTION ";
map("commands", help + "LIKE 'Commands%' ORDER BY ID"); map("commands", help + "LIKE 'Commands%' ORDER BY ID", true);
map("commandsDML", help + "= 'Commands (DML)' ORDER BY ID"); map("commandsDML", help + "= 'Commands (DML)' ORDER BY ID", true);
map("commandsDDL", help + "= 'Commands (DDL)' ORDER BY ID"); map("commandsDDL", help + "= 'Commands (DDL)' ORDER BY ID", true);
map("commandsOther", help + "= 'Commands (Other)' ORDER BY ID"); map("commandsOther", help + "= 'Commands (Other)' ORDER BY ID", true);
map("otherGrammar", help + "= 'Other Grammar' ORDER BY ID"); map("otherGrammar", help + "= 'Other Grammar' ORDER BY ID", true);
map("functionsAggregate", help + "= 'Functions (Aggregate)' ORDER BY ID"); map("functionsAggregate", help + "= 'Functions (Aggregate)' ORDER BY ID", true);
map("functionsNumeric", help + "= 'Functions (Numeric)' ORDER BY ID"); map("functionsNumeric", help + "= 'Functions (Numeric)' ORDER BY ID", true);
map("functionsString", help + "= 'Functions (String)' ORDER BY ID"); map("functionsString", help + "= 'Functions (String)' ORDER BY ID", true);
map("functionsTimeDate", help + "= 'Functions (Time and Date)' ORDER BY ID"); map("functionsTimeDate", help + "= 'Functions (Time and Date)' ORDER BY ID", true);
map("functionsSystem", help + "= 'Functions (System)' ORDER BY ID"); map("functionsSystem", help + "= 'Functions (System)' ORDER BY ID", true);
map("functionsAll", help + "LIKE 'Functions%' ORDER BY SECTION, ID"); map("functionsAll", help + "LIKE 'Functions%' ORDER BY SECTION, ID", true);
map("dataTypes", help + "LIKE 'Data Types%' ORDER BY SECTION, ID"); map("dataTypes", help + "LIKE 'Data Types%' ORDER BY SECTION, ID", true);
map("informationSchema", "SELECT TABLE_NAME TOPIC, GROUP_CONCAT(COLUMN_NAME " map("informationSchema", "SELECT TABLE_NAME TOPIC, GROUP_CONCAT(COLUMN_NAME "
+ "ORDER BY ORDINAL_POSITION SEPARATOR ', ') SYNTAX FROM INFORMATION_SCHEMA.COLUMNS " + "ORDER BY ORDINAL_POSITION SEPARATOR ', ') SYNTAX FROM INFORMATION_SCHEMA.COLUMNS "
+ "WHERE TABLE_SCHEMA='INFORMATION_SCHEMA' GROUP BY TABLE_NAME ORDER BY TABLE_NAME"); + "WHERE TABLE_SCHEMA='INFORMATION_SCHEMA' GROUP BY TABLE_NAME ORDER BY TABLE_NAME", false);
processAll(""); processAll("");
conn.close(); conn.close();
} }
...@@ -115,7 +117,7 @@ public class GenerateDoc { ...@@ -115,7 +117,7 @@ public class GenerateDoc {
out.close(); out.close();
} }
private void map(String key, String sql) throws Exception { private void map(String key, String sql, boolean railroads) throws Exception {
ResultSet rs = null; ResultSet rs = null;
Statement stat = null; Statement stat = null;
try { try {
...@@ -133,9 +135,10 @@ public class GenerateDoc { ...@@ -133,9 +135,10 @@ public class GenerateDoc {
} }
String topic = rs.getString("TOPIC"); String topic = rs.getString("TOPIC");
String syntax = rs.getString("SYNTAX").trim(); String syntax = rs.getString("SYNTAX").trim();
syntax = PageParser.escapeHtml(syntax); if (railroads) {
// if enabled, HTML docs get very wide String railroad = bnf.getRailroadHtml(syntax);
// syntax = StringUtils.replaceAll(syntax, "<br />", " "); map.put("railroad", railroad);
}
syntax = bnf.getSyntaxHtml(syntax); syntax = bnf.getSyntaxHtml(syntax);
map.put("syntax", syntax); map.put("syntax", syntax);
......
...@@ -43,6 +43,7 @@ public class MergeDocs { ...@@ -43,6 +43,7 @@ public class MergeDocs {
for (String page : pages) { for (String page : pages) {
text = StringUtils.replaceAll(text, page + "#", "#"); text = StringUtils.replaceAll(text, page + "#", "#");
} }
text = disableRailroads(text);
text = removeHeaderFooter(fileName, text); text = removeHeaderFooter(fileName, text);
buff.append(text); buff.append(text);
} }
...@@ -59,6 +60,14 @@ public class MergeDocs { ...@@ -59,6 +60,14 @@ public class MergeDocs {
writer.close(); writer.close();
} }
private String disableRailroads(String text) {
text = StringUtils.replaceAll(text, "<!-- railroad-start -->", "<!-- railroad-start ");
text = StringUtils.replaceAll(text, "<!-- railroad-end -->", " railroad-end -->");
text = StringUtils.replaceAll(text, "<!-- syntax-start", "<!-- syntax-start -->");
text = StringUtils.replaceAll(text, "syntax-end -->", "<!-- syntax-end -->");
return text;
}
private String removeHeaderFooter(String fileName, String text) { private String removeHeaderFooter(String fileName, String text) {
// String start = "<body"; // String start = "<body";
// String end = "</body>"; // String end = "</body>";
......
/*
* Copyright 2004-2009 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.build.doc;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* Create the images used in the railroad diagrams.
*/
public class RailroadImages {
private static final int SIZE = 64;
private static final int LINE_REPEAT = 32;
private static final int DIV = 4;
private static final int STROKE = 4;
private String outDir;
/**
* This method is called when executing this application from the command
* line.
*
* @param args the command line parameters
*/
public static void main(String[] args) {
new RailroadImages().run("docs/html/images");
}
/**
* Create the images.
*
* @param outDir the target directory
*/
void run(String outDir) {
this.outDir = outDir;
new File(outDir).mkdirs();
BufferedImage img;
Graphics2D g;
img = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_ARGB);
g = img.createGraphics();
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(STROKE));
g.drawLine(0, SIZE / 2, SIZE, SIZE / 2);
g.dispose();
savePng(img, "div-d.png");
img = new BufferedImage(SIZE, SIZE * LINE_REPEAT, BufferedImage.TYPE_INT_ARGB);
g = img.createGraphics();
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(STROKE));
g.drawLine(0, SIZE / 2, SIZE, SIZE / 2);
g.drawLine(SIZE / 2, SIZE, SIZE / 2, SIZE * LINE_REPEAT);
// g.drawLine(0, SIZE / 2, SIZE / 2, SIZE);
g.drawArc(-SIZE / 2, SIZE / 2, SIZE, SIZE, 0, 90);
g.dispose();
savePng(img, "div-ts.png");
savePng(flipHorizontal(img), "div-te.png");
img = new BufferedImage(SIZE, SIZE * LINE_REPEAT, BufferedImage.TYPE_INT_ARGB);
g = img.createGraphics();
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(STROKE));
g.drawArc(SIZE / 2, -SIZE / 2, SIZE, SIZE, 180, 270);
// g.drawLine(SIZE / 2, 0, SIZE, SIZE / 2);
savePng(img, "div-ls.png");
savePng(flipHorizontal(img), "div-le.png");
g.drawLine(SIZE / 2, 0, SIZE / 2, SIZE * LINE_REPEAT);
g.dispose();
savePng(img, "div-ks.png");
savePng(flipHorizontal(img), "div-ke.png");
}
private void savePng(BufferedImage img, String fileName) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage smaller = new BufferedImage(w / DIV, h / DIV, img.getType());
Graphics2D g = smaller.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, w / DIV, h / DIV, 0, 0, w, h, null);
g.dispose();
try {
ImageIO.write(smaller, "png", new File(outDir + "/" + fileName));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private BufferedImage flipHorizontal(BufferedImage img) {
int w = img.getWidth(), h = img.getHeight();
BufferedImage copy = new BufferedImage(w, h, img.getType());
Graphics2D g = copy.createGraphics();
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null);
g.dispose();
return copy;
}
}
...@@ -124,7 +124,7 @@ public class XMLParser { ...@@ -124,7 +124,7 @@ public class XMLParser {
} }
private void error(String expected) { private void error(String expected) {
throw new RuntimeException("Expected: " + expected + " got: " + xml.substring(index)); throw new RuntimeException("Expected: " + expected + " got: " + xml.substring(index, Math.min(index + 1000, xml.length())));
} }
private void read(String chars) { private void read(String chars) {
......
...@@ -615,4 +615,6 @@ linkage superfluous disallow scoop moebius inputs copilot dmoebius leod jenkov ...@@ -615,4 +615,6 @@ linkage superfluous disallow scoop moebius inputs copilot dmoebius leod jenkov
jakob poker docware peter unstable measurable scramble reissued recreation jakob poker docware peter unstable measurable scramble reissued recreation
scrambling distinguish official unofficial distinguishable overwrites lastval scrambling distinguish official unofficial distinguishable overwrites lastval
notranslate vince bonfanti alphabetically sysdummy sysibm activation notranslate vince bonfanti alphabetically sysdummy sysibm activation
deactivation concatenating reproducing black deactivation concatenating reproducing black railroads railroad radius moz
\ No newline at end of file imageio argb bilinear rendering stroke interpolation flip diagrams draw
delim
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论