summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/ioutils/format/directives
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java/bjc/utils/ioutils/format/directives')
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java64
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java37
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java120
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java38
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java46
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java28
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java47
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/GotoDirective.java40
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java132
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java35
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java37
-rw-r--r--base/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java47
12 files changed, 671 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
new file mode 100644
index 0000000..cbba104
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/AestheticDirective.java
@@ -0,0 +1,64 @@
+package bjc.utils.ioutils.format.directives;
+
+import java.util.regex.Matcher;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+public class AestheticDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ CLFormatter.checkItem(item, 'A');
+
+ int mincol = 0, colinc = 1, minpad = 0;
+ char padchar = ' ';
+
+ if(params.length() > 1) {
+ mincol = params.getIntDefault(0, "minimum column count", 'A', 0);
+ }
+
+ if(params.length() < 4) {
+ throw new IllegalArgumentException(
+ "Must provide either zero, one or four arguments to A directive");
+ }
+
+ colinc = params.getIntDefault(1, "padding increment", 'A', 1);
+ minpad = params.getIntDefault(2, "minimum amount of padding", 'A', 0);
+ padchar = params.getCharDefault(3, "padding character", 'A', ' ');
+
+ StringBuilder work = new StringBuilder();
+
+ if(mods.atMod) {
+ for(int i = 0; i < minpad; i++) {
+ work.append(padchar);
+ }
+
+ for(int i = work.length(); i < mincol; i++) {
+ for(int k = 0; k < colinc; k++) {
+ work.append(padchar);
+ }
+ }
+ }
+
+ work.append(item.toString());
+
+ if(!mods.atMod) {
+ for(int i = 0; i < minpad; i++) {
+ work.append(padchar);
+ }
+
+ for(int i = work.length(); i < mincol; i++) {
+ for(int k = 0; k < colinc; k++) {
+ work.append(padchar);
+ }
+ }
+ }
+
+ tParams.right();
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java
new file mode 100644
index 0000000..8041cf4
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/CharacterDirective.java
@@ -0,0 +1,37 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.IllegalFormatConversionException;
+import java.util.regex.Matcher;
+
+public class CharacterDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer buff, Object parm, CLModifiers mods, CLParameters arrParams,
+ Tape<Object> tParams, Matcher dirMatcher, CLFormatter fmt) {
+ CLFormatter.checkItem(parm, 'C');
+
+ if(!(parm instanceof Character)) {
+ throw new IllegalFormatConversionException('C', parm.getClass());
+ }
+
+ char ch = (Character) parm;
+ int codepoint = ch;
+
+ if(mods.colonMod) {
+ /*
+ * Colon mod means print Unicode character name.
+ */
+ buff.append(Character.getName(codepoint));
+ } else {
+ buff.append(ch);
+ }
+
+ tParams.right();
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java
new file mode 100644
index 0000000..98c62cb
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/ConditionalDirective.java
@@ -0,0 +1,120 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.ArrayList;
+import java.util.IllegalFormatConversionException;
+import java.util.List;
+import java.util.regex.Matcher;
+
+public class ConditionalDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters arrParams,
+ Tape<Object> formatParams, Matcher dirMatcher, CLFormatter fmt) {
+ StringBuffer condBody = new StringBuffer();
+
+ List<String> clauses = new ArrayList<>();
+ String defClause = null;
+ boolean isDefault = false;
+
+ while(dirMatcher.find()) {
+ /* Process a list of clauses. */
+ String dirName = dirMatcher.group("name");
+ String dirMods = dirMatcher.group("modifiers");
+
+ if(dirName != null) {
+ /* Append everything up to this directive. */
+ dirMatcher.appendReplacement(condBody, "");
+
+ if(dirName.equals("]")) {
+ /* End the conditional. */
+ String clause = condBody.toString();
+ if(isDefault) {
+ defClause = clause;
+ } else {
+ clauses.add(clause);
+ }
+
+ break;
+ } else if(dirName.equals(";")) {
+ /* End the clause. */
+ String clause = condBody.toString();
+ if(isDefault) {
+ defClause = clause;
+ } else {
+ clauses.add(clause);
+ }
+
+ /*
+ * Mark the next clause as the default.
+ */
+ if(dirMods.contains(":")) {
+ isDefault = true;
+ }
+ } else {
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
+ }
+ }
+ }
+
+ Object par = formatParams.item();
+ if(mods.colonMod) {
+ formatParams.right();
+
+ if(par == null) {
+ throw new IllegalArgumentException("No parameter provided for [ directive.");
+ } else if(!(par instanceof Boolean)) {
+ throw new IllegalFormatConversionException('[', par.getClass());
+ }
+ boolean res = (Boolean) par;
+
+ String frmt;
+ if(res)
+ frmt = clauses.get(1);
+ else
+ frmt = clauses.get(0);
+
+ fmt.doFormatString(frmt, sb, formatParams);
+ } else if(mods.atMod) {
+ if(par == null) {
+ throw new IllegalArgumentException("No parameter provided for [ directive.");
+ } else if(!(par instanceof Boolean)) {
+ throw new IllegalFormatConversionException('[', par.getClass());
+ }
+ boolean res = (Boolean) par;
+
+ if(res) {
+ fmt.doFormatString(clauses.get(0), sb, formatParams);
+ } else {
+ formatParams.right();
+ }
+ } else {
+ int res;
+ if(arrParams.length() > 1) {
+ res = arrParams.getInt(0, "conditional choice", '[');
+ } else {
+ if(par == null) {
+ throw new IllegalArgumentException("No parameter provided for [ directive.");
+ } else if(!(par instanceof Number)) {
+ throw new IllegalFormatConversionException('[', par.getClass());
+ }
+ res = ((Number) par).intValue();
+
+ formatParams.right();
+ }
+
+ if(res < 0 || res > clauses.size()) {
+ if(defClause != null) fmt.doFormatString(defClause, sb, formatParams);
+ } else {
+ fmt.doFormatString(clauses.get(res), sb, formatParams);
+ }
+ }
+ return;
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java b/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java
new file mode 100644
index 0000000..6d558fc
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/Directive.java
@@ -0,0 +1,38 @@
+package bjc.utils.ioutils.format.directives;
+
+import java.util.regex.Matcher;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+/**
+ * A CL format directive.
+ *
+ * @author EVE
+ *
+ */
+@FunctionalInterface
+public interface Directive {
+ /**
+ * Execute this format directive.
+ *
+ * @param sb
+ * The buffer the string is being output to.
+ * @param item
+ * The current parameter being passed
+ * @param mods
+ * The directive modifiers
+ * @param arrParams
+ * The prefix parameters to the directive
+ * @param tParams
+ * All of the provided format parameters
+ * @param dirMatcher
+ * The matcher for format directives
+ * @param fmt
+ * The formatter itself.
+ */
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters arrParams, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt);
+} \ No newline at end of file
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
new file mode 100644
index 0000000..ba1acf5
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/EscapeDirective.java
@@ -0,0 +1,46 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+import bjc.utils.ioutils.format.EscapeException;
+
+import java.util.regex.Matcher;
+
+public class EscapeDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters params,
+ Tape<Object> formatParams, Matcher dirMatcher, CLFormatter fmt) {
+ boolean shouldExit;
+
+ switch(params.length()) {
+ case 0:
+ shouldExit = formatParams.size() == 0;
+ break;
+ case 1:
+ int num = params.getInt(0, "condition count", '^');
+ shouldExit = num == 0;
+ break;
+ case 2:
+ int left = params.getInt(0, "left-hand condition", '^');
+ int right = params.getInt(1, "right-hand condition", '^');
+ shouldExit = left == right;
+ break;
+ case 3:
+ default:
+ int low = params.getInt(0, "lower-bound condition", '^');
+ int mid = params.getInt(1, "interval condition", '^');
+ int high = params.getInt(2, "upper-bound condition", '^');
+ shouldExit = (low <= mid) && (mid <= high);
+ break;
+ }
+
+ /* At negates it. */
+ if(mods.atMod) shouldExit = !shouldExit;
+
+ if(shouldExit) throw new EscapeException(mods.colonMod);
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java
new file mode 100644
index 0000000..e394a8d
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/FreshlineDirective.java
@@ -0,0 +1,28 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.regex.Matcher;
+
+public class FreshlineDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer buff, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ int nTimes = 1;
+
+ if(params.length() > 1) {
+ nTimes = params.getInt(0, "occurance count", '&');
+ }
+
+ if(buff.charAt(buff.length() - 1) == '\n') nTimes -= 1;
+
+ for(int i = 0; i < nTimes; i++) {
+ buff.append("\n");
+ }
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java
new file mode 100644
index 0000000..34abcab
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/GeneralNumberDirective.java
@@ -0,0 +1,47 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+import bjc.utils.math.NumberUtils;
+
+public abstract class GeneralNumberDirective implements Directive {
+ protected static void handleNumberDirective(StringBuffer buff, CLModifiers mods, CLParameters params,
+ int argidx, long val, int radix) {
+ /*
+ * Initialize the two padding related parameters, and then fill
+ * them in from the directive parameters if they are present.
+ */
+ int mincol = 0;
+ char padchar = ' ';
+ if(params.length() > (argidx + 2)) {
+ mincol = params.getIntDefault(argidx + 1, "minimum column count", 'R', 0);
+ }
+ if(params.length() > (argidx + 3)) {
+ padchar = params.getCharDefault(argidx + 2, "padding character", 'R', ' ');
+ }
+
+ String res;
+
+ if(mods.colonMod) {
+ /*
+ * We're doing commas, so check if the two comma-related
+ * parameters were supplied.
+ */
+ int commaInterval = 0;
+ char commaChar = ',';
+ if(params.length() > (argidx + 3)) {
+ commaChar = params.getCharDefault((argidx + 3), "comma character", 'R', ' ');
+ }
+ if(params.length() > (argidx + 4)) {
+ commaInterval = params.getIntDefault((argidx + 4), "comma interval", 'R', 0);
+ }
+
+ res = NumberUtils.toCommaString(val, mincol, padchar, commaInterval, commaChar, mods.atMod,
+ radix);
+ } else {
+ res = NumberUtils.toNormalString(val, mincol, padchar, mods.atMod, radix);
+ }
+
+ buff.append(res);
+ }
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/GotoDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/GotoDirective.java
new file mode 100644
index 0000000..f3da9bb
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/GotoDirective.java
@@ -0,0 +1,40 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.regex.Matcher;
+
+public class GotoDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters params,
+ Tape<Object> formatParams, Matcher dirMatcher, CLFormatter fmt) {
+ if(mods.colonMod) {
+ int num = 1;
+ if(params.length() > 1) {
+ num = params.getIntDefault(0, "number of arguments backward", '*', 1);
+ }
+
+ formatParams.left(num);
+ } else if(mods.atMod) {
+ int num = 0;
+ if(params.length() > 1) {
+ num = params.getIntDefault(0, "argument index", '*', 0);
+ }
+
+ formatParams.first();
+ formatParams.right(num);
+ } else {
+ int num = 1;
+ if(params.length() > 1) {
+ num = params.getIntDefault(0, "number of arguments forward", '*', 1);
+ }
+
+ formatParams.right(num);
+ }
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
new file mode 100644
index 0000000..52b2e40
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/IterationDirective.java
@@ -0,0 +1,132 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.SingleTape;
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.IllegalFormatConversionException;
+import java.util.regex.Matcher;
+
+public class IterationDirective implements Directive {
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters arrParams, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ CLFormatter.checkItem(item, '{');
+
+ StringBuffer condBody = new StringBuffer();
+
+ while(dirMatcher.find()) {
+ /* Process a list of clauses. */
+ String dirName = dirMatcher.group("name");
+
+ if(dirName != null) {
+ /* Append everything up to this directive. */
+ dirMatcher.appendReplacement(condBody, "");
+
+ if(dirName.equals("}")) {
+ /* End the iteration. */
+ break;
+ }
+
+ /* Not a special directive. */
+ condBody.append(dirMatcher.group());
+ }
+ }
+
+ String frmt = condBody.toString();
+ Object iter = item;
+
+ if(frmt.equals("")) {
+ /* Grab an argument. */
+ if(!(item instanceof String)) {
+ throw new IllegalFormatConversionException('{', String.class);
+ }
+
+ frmt = (String) item;
+
+ if(!tParams.right()) {
+ throw new IllegalArgumentException("Not enough parameters to '{' directive");
+ }
+
+ iter = tParams.item();
+ }
+
+ int maxItr = Integer.MAX_VALUE;
+
+ if(arrParams.length() > 0) {
+ maxItr = arrParams.getInt(0, "maximum iterations", '{');
+ }
+
+ int numItr = 0;
+
+ if(mods.atMod && mods.colonMod) {
+ do {
+ if(numItr > maxItr) break;
+ numItr += 1;
+
+ if(!(iter instanceof Iterable<?>)) {
+ throw new IllegalFormatConversionException('{', iter.getClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable<Object> nitr = (Iterable<Object>) iter;
+ Tape<Object> nParams = new SingleTape<>(nitr);
+
+ fmt.doFormatString(frmt, sb, nParams);
+
+ iter = tParams.right();
+ } while(tParams.position() < tParams.size());
+ } else if(mods.atMod) {
+ while(tParams.position() < tParams.size()) {
+ if(numItr > maxItr) break;
+ numItr += 1;
+
+ fmt.doFormatString(frmt, sb, tParams);
+ }
+ } else if(mods.colonMod) {
+ if(!(item instanceof Iterable<?>)) {
+ throw new IllegalFormatConversionException('{', item.getClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable<Object> itr = (Iterable<Object>) item;
+
+ for(Object obj : itr) {
+ if(numItr > maxItr) break;
+ numItr += 1;
+
+ if(!(obj instanceof Iterable<?>)) {
+ throw new IllegalFormatConversionException('{', obj.getClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable<Object> nitr = (Iterable<Object>) obj;
+ Tape<Object> nParams = new SingleTape<>(nitr);
+
+ fmt.doFormatString(frmt, sb, nParams);
+ }
+ } else {
+ if(!(item instanceof Iterable<?>)) {
+ throw new IllegalFormatConversionException('{', item.getClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ Iterable<Object> itr = (Iterable<Object>) item;
+
+ Tape<Object> nParams = new SingleTape<>(itr);
+
+ while(nParams.position() < nParams.size()) {
+ if(numItr > maxItr) break;
+ numItr += 1;
+
+ fmt.doFormatString(frmt, sb, nParams);
+ }
+ }
+
+ tParams.right();
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java
new file mode 100644
index 0000000..ba00520
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/LiteralDirective.java
@@ -0,0 +1,35 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+import java.util.regex.Matcher;
+
+public class LiteralDirective implements Directive {
+
+ private char directive;
+ private String lit;
+
+ public LiteralDirective(String lit, char directive) {
+ this.directive = directive;
+ this.lit = lit;
+ }
+
+ @Override
+ public void format(StringBuffer buff, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ int nTimes = 1;
+
+ if(params.length() > 1) {
+ nTimes = params.getInt(0, "occurance count", directive);
+ }
+
+ for(int i = 0; i < nTimes; i++) {
+ buff.append(lit);
+ }
+
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java
new file mode 100644
index 0000000..98d6c16
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/NumberDirective.java
@@ -0,0 +1,37 @@
+package bjc.utils.ioutils.format.directives;
+
+import java.util.IllegalFormatConversionException;
+import java.util.regex.Matcher;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+
+public class NumberDirective extends GeneralNumberDirective {
+
+ public NumberDirective(int argidx, int radix) {
+ this.argidx = argidx;
+ this.radix = radix;
+ }
+
+ private int argidx;
+ private int radix;
+
+ @Override
+ public void format(StringBuffer sb, Object item, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ CLFormatter.checkItem(item, 'B');
+
+ if(!(item instanceof Number)) {
+ throw new IllegalFormatConversionException('B', item.getClass());
+ }
+
+ long val = ((Number) item).longValue();
+
+ handleNumberDirective(sb, mods, params, argidx, val, radix);
+
+ tParams.right();
+ }
+
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java b/base/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java
new file mode 100644
index 0000000..428c613
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/format/directives/RadixDirective.java
@@ -0,0 +1,47 @@
+package bjc.utils.ioutils.format.directives;
+
+import bjc.utils.esodata.Tape;
+import bjc.utils.ioutils.format.CLFormatter;
+import bjc.utils.ioutils.format.CLModifiers;
+import bjc.utils.ioutils.format.CLParameters;
+import bjc.utils.math.NumberUtils;
+
+import java.util.IllegalFormatConversionException;
+import java.util.regex.Matcher;
+
+public class RadixDirective extends GeneralNumberDirective {
+
+ @Override
+ public void format(StringBuffer buff, Object arg, CLModifiers mods, CLParameters params, Tape<Object> tParams,
+ Matcher dirMatcher, CLFormatter fmt) {
+ CLFormatter.checkItem(arg, 'R');
+
+ if(!(arg instanceof Number)) {
+ throw new IllegalFormatConversionException('R', arg.getClass());
+ }
+
+ /*
+ * @TODO see if this is the way we want to do this.
+ */
+ long val = ((Number) arg).longValue();
+
+ if(params.length() == 0) {
+ if(mods.atMod) {
+ buff.append(NumberUtils.toRoman(val, mods.colonMod));
+ } else if(mods.colonMod) {
+ buff.append(NumberUtils.toOrdinal(val));
+ } else {
+ buff.append(NumberUtils.toCardinal(val));
+ }
+ } else {
+ if(params.length() < 1) throw new IllegalArgumentException(
+ "R directive requires at least one parameter, the radix");
+
+ int radix = params.getInt(0, "radix", 'R');
+
+ handleNumberDirective(buff, mods, params, 0, val, radix);
+ }
+
+ tParams.right();
+ }
+}