From 0d9e99886b13a5619b5e4f214731e934702c4e87 Mon Sep 17 00:00:00 2001 From: serso Date: Sun, 23 Oct 2011 15:10:25 +0400 Subject: [PATCH] group separator in editor --- .../android/calculator/TextHighlighter.java | 6 ++ .../android/calculator/math/MathType.java | 82 ++++++++++---- .../model/FromJsclSimplifyTextProcessor.java | 101 ++---------------- .../calculator/model/NumberBuilder.java | 83 ++++++++++++++ .../calculator/model/ToJsclTextProcessor.java | 2 +- .../calculator/TextHighlighterTest.java | 1 + 6 files changed, 161 insertions(+), 114 deletions(-) create mode 100644 src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java diff --git a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java index 79e22d05..127c991f 100644 --- a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java +++ b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java @@ -8,6 +8,7 @@ package org.solovyev.android.calculator; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.math.MathType; +import org.solovyev.android.calculator.model.NumberBuilder; import org.solovyev.android.calculator.model.ParseException; import org.solovyev.android.calculator.model.TextProcessor; @@ -43,9 +44,12 @@ public class TextHighlighter implements TextProcessor { final StringBuilder text1 = new StringBuilder(); + final NumberBuilder numberBuilder = new NumberBuilder(); for (int i = 0; i < text.length(); i++) { final MathType.Result mathType = MathType.getType(text, i); + numberBuilder.process(text1, mathType); + switch (mathType.getMathType()) { case open_group_symbol: numberOfOpenGroupSymbols++; @@ -67,6 +71,8 @@ public class TextHighlighter implements TextProcessor { } } + numberBuilder.process(text1); + if (maxNumberOfOpenGroupSymbols > 0) { final StringBuilder text2 = new StringBuilder(); diff --git a/src/main/java/org/solovyev/android/calculator/math/MathType.java b/src/main/java/org/solovyev/android/calculator/math/MathType.java index d3832d6c..9f44cd4e 100644 --- a/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -29,7 +29,7 @@ public enum MathType { } }, - dot(200, true, true, "."){ + dot(200, true, true, ".") { @Override public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) { return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit; @@ -38,17 +38,17 @@ public enum MathType { power_10(300, true, false, "E") { @Override - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteToJscl(@NotNull String match) { return POWER_10_JSCL; } }, postfix_function(400, true, false, Functions.allPostfix) { @Override - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteToJscl(@NotNull String match) { final String result; - if ( match.equals(Functions.DEGREE)) { + if (match.equals(Functions.DEGREE)) { result = PI + "/180"; } else { result = null; @@ -60,8 +60,8 @@ public enum MathType { unary_operation(500, false, false, "-", "=", "!"), binary_operation(600, false, false, "-", "+", "*", "×", "∙", "/", "^") { @Override - protected String getSubstitute(@NotNull String match) { - if ( match.equals("×") || match.equals("∙") ) { + protected String getSubstituteToJscl(@NotNull String match) { + if (match.equals("×") || match.equals("∙")) { return "*"; } else { return null; @@ -76,7 +76,7 @@ public enum MathType { } @Override - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteToJscl(@NotNull String match) { return "("; } }, @@ -88,14 +88,14 @@ public enum MathType { } @Override - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteToJscl(@NotNull String match) { return ")"; } }, function(1000, true, true, Functions.allPrefix) { @Override - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteToJscl(@NotNull String match) { final String result; if (match.equals(Functions.LN)) { @@ -103,7 +103,22 @@ public enum MathType { } else if (match.equals(Functions.SQRT)) { result = Functions.SQRT_JSCL; } else { - result = match; + result = null; + } + + return result; + } + + @Override + protected String getSubstituteFromJscl(@NotNull String match) { + final String result; + + if (match.equals(Functions.LN_JSCL)) { + result = Functions.LN; + } else if (match.equals(Functions.SQRT_JSCL)) { + result = Functions.SQRT; + } else { + result = null; } return result; @@ -118,7 +133,23 @@ public enum MathType { } }, - text(1200, false, false); + text(1200, false, false) { + @Override + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + + @Override + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + if (match.length() > 0) { + result.append(match.charAt(0)); + } + return i; + } + }; @NotNull private final List tokens; @@ -164,14 +195,25 @@ public enum MathType { return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter(); } - public int process(@NotNull StringBuilder result, int i, @NotNull String match) { - final String substitute = getSubstitute(match); + public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + final String substitute = getSubstituteToJscl(match); + result.append(substitute == null ? match : substitute); + return i + match.length() - 1; + } + + public int processFromJscl(@NotNull StringBuilder result, int i, @NotNull String match) { + final String substitute = getSubstituteFromJscl(match); result.append(substitute == null ? match : substitute); return i + match.length() - 1; } @Nullable - protected String getSubstitute(@NotNull String match) { + protected String getSubstituteFromJscl(@NotNull String match) { + return null; + } + + @Nullable + protected String getSubstituteToJscl(@NotNull String match) { return null; } @@ -213,7 +255,7 @@ public enum MathType { for (MathType mathType : getMathTypesByPriority()) { final String s = get(mathType.getTokens(), startsWithFinder); - if ( s != null ) { + if (s != null) { return new Result(mathType, s); } } @@ -226,7 +268,7 @@ public enum MathType { @NotNull private static List getMathTypesByPriority() { - if ( mathTypesByPriority == null ) { + if (mathTypesByPriority == null) { final List result = CollectionsUtils.asList(MathType.values()); Collections.sort(result, new Comparator() { @@ -256,8 +298,12 @@ public enum MathType { this.match = match; } - public int process(@NotNull StringBuilder result, int i) { - return mathType.process(result, i, match); + public int processToJscl(@NotNull StringBuilder result, int i) { + return mathType.processToJscl(result, i, match); + } + + public int processFromJscl(@NotNull StringBuilder result, int i) { + return mathType.processFromJscl(result, i, match); } @NotNull diff --git a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java index 14f78c75..4d7c4b3d 100644 --- a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -2,10 +2,7 @@ package org.solovyev.android.calculator.model; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.solovyev.android.calculator.math.Functions; import org.solovyev.android.calculator.math.MathType; -import org.solovyev.common.utils.CollectionsUtils; -import org.solovyev.common.utils.Finder; import java.util.Arrays; import java.util.List; @@ -17,91 +14,31 @@ import java.util.List; */ public class FromJsclSimplifyTextProcessor implements TextProcessor { + @NotNull @Override public String process(@NotNull String s) throws ParseException { final StringBuilder sb = new StringBuilder(); - MathType.Result mathTypeResult = null; - StringBuilder numberBuilder = null; - String number = null; + final NumberBuilder numberBuilder = new NumberBuilder(); for (int i = 0; i < s.length(); i++) { char ch = s.charAt(i); if ( Character.isWhitespace(ch) ) { continue; } - mathTypeResult = MathType.getType(s, i); + final MathType.Result mathTypeResult = MathType.getType(s, i); - final MathType mathType = mathTypeResult.getMathType(); + numberBuilder.process(sb, mathTypeResult); - number = null; - if (mathType == MathType.digit || mathType == MathType.dot || mathType == MathType.power_10) { - if (numberBuilder == null) { - numberBuilder = new StringBuilder(); - } - numberBuilder.append(mathTypeResult.getMatch()); - } else { - if (numberBuilder != null) { - try { - number = numberBuilder.toString(); - Double.valueOf(number); - } catch (NumberFormatException e) { - number = null; - } - - numberBuilder = null; - } else { - number = null; - } - } - - replaceSystemVars(sb, number); - - if (mathType == MathType.constant){ - sb.append(mathTypeResult.getMatch()); - i += mathTypeResult.getMatch().length() - 1; - } else if ( mathType == MathType.function) { - sb.append(fromJsclFunction(mathTypeResult.getMatch())); - i += mathTypeResult.getMatch().length() - 1; - } else { - sb.append(ch); - } + i = mathTypeResult.processFromJscl(sb, i); } - if (numberBuilder != null) { - try { - number = numberBuilder.toString(); - Double.valueOf(number); - } catch (NumberFormatException e) { - number = null; - } - - numberBuilder = null; - } else { - number = null; - } - - replaceSystemVars(sb, number); + numberBuilder.process(sb); return removeMultiplicationSigns(sb.toString()); } - @NotNull - private static String fromJsclFunction(@NotNull String function) { - final String result; - - if (function.equals(Functions.LN_JSCL)) { - result = Functions.LN; - } else if (function.equals(Functions.SQRT_JSCL)) { - result = Functions.SQRT; - } else { - result = function; - } - - return result; - } - @NotNull private String removeMultiplicationSigns(String s) { final StringBuilder sb = new StringBuilder(); @@ -161,30 +98,4 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor { return true; } - @Nullable - private MathType replaceSystemVars(StringBuilder sb, String number) { - MathType result = null; - - if (number != null) { - final String finalNumber = number; - final Var var = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getSystemVars(), new Finder() { - @Override - public boolean isFound(@Nullable Var var) { - return var != null && finalNumber.equals(var.getValue()); - } - }); - - if (var != null) { - sb.delete(sb.length() - number.length(), sb.length()); - sb.append(var.getName()); - result = MathType.constant; - } else { - sb.delete(sb.length() - number.length(), sb.length()); - sb.append(CalculatorEngine.instance.format(Double.valueOf(number))); - } - } - - return result; - } - } diff --git a/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java new file mode 100644 index 00000000..04bdc81a --- /dev/null +++ b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2009-2011. Created by serso aka se.solovyev. + * For more information, please, contact se.solovyev@gmail.com + * or visit http://se.solovyev.org + */ + +package org.solovyev.android.calculator.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.solovyev.android.calculator.math.MathType; +import org.solovyev.common.utils.CollectionsUtils; +import org.solovyev.common.utils.Finder; + +/** +* User: serso +* Date: 10/23/11 +* Time: 2:57 PM +*/ +public class NumberBuilder { + + @Nullable + private StringBuilder numberBuilder = null; + @Nullable + private String number = null; + + public void process(@NotNull StringBuilder sb, @NotNull MathType.Result mathTypeResult) { + number = null; + if (mathTypeResult.getMathType() == MathType.digit || mathTypeResult.getMathType() == MathType.dot || mathTypeResult.getMathType() == MathType.power_10) { + if (numberBuilder == null) { + numberBuilder = new StringBuilder(); + } + numberBuilder.append(mathTypeResult.getMatch()); + + replaceSystemVars(sb, number); + } else { + process(sb); + } + } + + public void process(@NotNull StringBuilder sb) { + if (numberBuilder != null) { + try { + number = numberBuilder.toString(); + Double.valueOf(number); + } catch (NumberFormatException e) { + number = null; + } + + numberBuilder = null; + } else { + number = null; + } + + replaceSystemVars(sb, number); + } + + @Nullable + private MathType replaceSystemVars(StringBuilder sb, String number) { + MathType result = null; + + if (number != null) { + final String finalNumber = number; + final Var var = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getSystemVars(), new Finder() { + @Override + public boolean isFound(@Nullable Var var) { + return var != null && finalNumber.equals(var.getValue()); + } + }); + + if (var != null) { + sb.delete(sb.length() - number.length(), sb.length()); + sb.append(var.getName()); + result = MathType.constant; + } else { + sb.delete(sb.length() - number.length(), sb.length()); + sb.append(CalculatorEngine.instance.format(Double.valueOf(number))); + } + } + + return result; + } +} diff --git a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java index bc339503..1dda86d1 100644 --- a/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/ToJsclTextProcessor.java @@ -54,7 +54,7 @@ class ToJsclTextProcessor implements TextProcessor { throw new ParseException("Empty function: " + mathTypeResult.getMatch()); } - i = mathTypeResult.process(result, i); + i = mathTypeResult.processToJscl(result, i); } return replaceVariables(result.toString()); diff --git a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java index 029d15aa..d5bdd31c 100644 --- a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java +++ b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java @@ -41,5 +41,6 @@ public class TextHighlighterTest { Assert.assertEquals(")(((())())", textHighlighter.process(")(((())())")); Assert.assertEquals(")", textHighlighter.process(")")); Assert.assertEquals(")()(", textHighlighter.process(")()(")); + Assert.assertEquals("1 000 000", textHighlighter.process("1000000")); } }