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.amic.util.string.Strings;
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 }
static final String [] NON_BLOCK_ELEMENTS
HashMap< String, String > getAttributes()
WikiElement(int selectionStart, int selectionEnd, InputElement input)
void addNoValuedAttribute(String value)
boolean renderImage(File image)
void forgetAndCreate(String newTag)
WikiElement(int selectionStart, InputElement input, String tag)
void setContent(String content)
static String getRelativePath(String path)
WikiElement(int selectionStart, int selectionEnd, InputElement input, String avoid[])