BrightSide Workbench Full Report + Source Code
WikiElement.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2015 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.zkoss.text;
20 
21 import java.io.File;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import org.turro.string.Strings;
25 import org.turro.elephant.context.ElephantContext;
26 import org.zkoss.zul.impl.InputElement;
27 
32 public class WikiElement {
33 
34  public static final String[]
35  NON_BLOCK_ELEMENTS = { "img" };
36 
37  private int startElement, endElement, selectionStart, selectionEnd;
38  private String text, tag, content, avoid[];
39  private InputElement input;
40  private boolean creating;
41  private HashMap<String, String> attributes = new HashMap<>();
42 
43  public WikiElement(int selectionStart, InputElement input, String tag) {
44  this.selectionStart = selectionStart;
45  this.selectionEnd = selectionStart;
46  this.input = input;
47  this.avoid = null;
48  this.text = input.getText();
49  initializeTag(tag);
50  }
51 
52  public WikiElement(int selectionStart, int selectionEnd, InputElement input) {
53  this(selectionStart, selectionEnd, input, null);
54  }
55 
56  public WikiElement(int selectionStart, int selectionEnd, InputElement input, String avoid[]) {
57  this.selectionStart = selectionStart;
58  this.selectionEnd = selectionEnd;
59  this.input = input;
60  this.avoid = avoid;
61  this.text = input.getText();
62  initialize();
63  }
64 
65  public void forgetAndCreate(String newTag) {
66  this.tag = newTag;
67  attributes.clear();
68  creating = true;
69  }
70 
71  public void setContent(String content) {
72  this.content = content;
73  }
74 
75  public boolean inside() {
76  return !Strings.isBlank(tag);
77  }
78 
79  public boolean isTag(String tag) {
80  return this.tag == null ? false : this.tag.equals(tag);
81  }
82 
83  public boolean isCreating() {
84  return creating;
85  }
86 
87  public HashMap<String, String> getAttributes() {
88  return attributes;
89  }
90 
91  public void addNoValuedAttribute(String value) {
92  attributes.put(value, "no-value");
93  }
94 
95  public String getFistNoneValued() {
96  for(String s : attributes.keySet()) {
97  if(attributes.get(s).equals("no-value")) {
98  return s;
99  }
100  }
101  return "";
102  }
103 
104  public void addClass(String sclass) {
105  String classes = attributes.get("&class");
106  if(classes != null) {
107  if(!classes.contains(sclass)) {
108  classes += " " + sclass;
109  }
110  } else {
111  classes = sclass;
112  }
113  attributes.put("&class", classes);
114  }
115 
116  public void removeValuedAttributes() {
117  Iterator<String> it = attributes.keySet().iterator();
118  while(it.hasNext()) {
119  String v = attributes.get(it.next());
120  if(!"no-value".equals(v)) {
121  it.remove();
122  }
123  }
124  }
125 
126  private void initialize() {
127  startElement = avoided();
128  if(startElement > -1 && text.charAt(startElement + 1) != '/') {
129  endElement = text.substring(startElement).indexOf("]") + startElement;
130  int p = text.substring(startElement, endElement).indexOf("(");
131  tag = Strings.extract(text.substring(startElement + 1), "([a-z0-9]+)");
132  if(p > -1) {
133  tag = text.substring(startElement + 1, startElement + p);
134  String attr = text.substring(startElement + p + 1, endElement - 1);
135  if(attr != null) {
136  for(String s : attr.split(",")) {
137  int pa = s.indexOf(":");
138  if(pa > 1) {
139  if(s.charAt(pa - 1) == '\\') {
140  int pa2 = s.indexOf(":", pa + 1);
141  if(pa2 > -1) {
142  pa += pa2;
143  } else {
144  pa = -1;
145  }
146  }
147  }
148  if(pa == -1) {
149  attributes.put(s, "no-value");
150  } else {
151  attributes.put(s.substring(0, pa), s.substring(pa + 1).replaceAll("\\:", "\\\\\\:"));
152  }
153  }
154  }
155  }
156  }
157  }
158 
159  private void initializeTag(String tag) {
160  startElement = text.substring(0, selectionStart).lastIndexOf("[" + tag);
161  endElement = text.indexOf("]", startElement);
162  this.tag = tag;
163  if(startElement > -1 && startElement < selectionStart && selectionStart < endElement) {
164 
165  } else {
166  forgetAndCreate(tag);
167  }
168  }
169 
170  public boolean render() {
171  int pointer = creating ? selectionStart : startElement;
172  if(!Strings.isBlank(tag)) {
173  if(!creating) {
174  input.setSelectedText(pointer, endElement + 1, "", false);
175  }
176  String tagString = elementString();
177  input.setSelectedText(pointer, pointer, tagString, false);
178  if(creating) {
179  if(!Strings.isBlank(content)) {
180  pointer += tagString.length();
181  input.setSelectedText(pointer, pointer, content, false);
182  pointer += content.length();
183  }
184  input.setSelectedText(pointer, pointer, "[/" + tag + "]", false);
185  }
186  return true;
187  }
188  return false;
189  }
190 
191  private String elementString() {
192  StringBuilder sb = new StringBuilder();
193  sb.append("[").append(tag);
194  boolean firstDone = false;
195  if(!attributes.isEmpty()) {
196  sb.append("(");
197  // start with no-value
198  for(String k : attributes.keySet()) {
199  String v = attributes.get(k);
200  if("no-value".equals(v)) {
201  if(firstDone) {
202  sb.append(",");
203  }
204  sb.append(k);
205  firstDone = true;
206  }
207  }
208  for(String k : attributes.keySet()) {
209  String v = attributes.get(k);
210  if(!"no-value".equals(v)) {
211  if(firstDone) {
212  sb.append(",");
213  }
214  sb.append(k);
215  sb.append(":").append(v.replaceAll("\\:", "\\\\\\:"));
216  firstDone = true;
217  }
218  }
219  sb.append(")");
220  }
221  sb.append("]");
222  return sb.toString();
223  }
224 
225  public boolean renderImage(File image) {
226  if(image != null) {
227  int pointer = creating ? selectionStart : startElement;
228  if(!Strings.isBlank(tag)) {
229  if(!creating) {
230  input.setSelectedText(pointer, endElement + 1, "", false);
231  }
232  String tagString = imageString(image);
233  input.setSelectedText(pointer, pointer, tagString, false);
234  }
235  return true;
236  }
237  return false;
238  }
239 
240  private String imageString(File image) {
241  StringBuilder sb = new StringBuilder();
242  sb.append("[").append(tag).append(" ")
243  .append(ElephantContext.getRootWebPath() + ElephantContext.getRelativePath(image.getAbsolutePath()))
244  .append("]");
245  return sb.toString();
246  }
247 
248  private int avoided() {
249  int start = text.substring(0, selectionStart).lastIndexOf("[");
250  if(avoid != null) {
251  while(start > -1) {
252  boolean accept = true;
253  for(String s : avoid) {
254  if(text.substring(start + 1).startsWith(s)) {
255  accept = false;
256  break;
257  }
258  }
259  if(accept || start == 0) {
260  break;
261  } else {
262  start = text.substring(0, start - 1).lastIndexOf("[");
263  }
264  }
265  }
266  return start;
267  }
268 
269 }
void addNoValuedAttribute(String value)
boolean renderImage(File image)
void forgetAndCreate(String newTag)
HashMap< String, String > getAttributes()
WikiElement(int selectionStart, InputElement input, String tag)
WikiElement(int selectionStart, int selectionEnd, InputElement input, String avoid[])
void setContent(String content)
static final String[] NON_BLOCK_ELEMENTS
WikiElement(int selectionStart, int selectionEnd, InputElement input)