From 6149689f27e74830cf2638c8ceffbe0dca9b82f0 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 19 Mar 2018 19:05:34 +0100 Subject: [PATCH 01/16] Fix small bug in Downloader --- src/be/nikiroo/utils/Downloader.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/be/nikiroo/utils/Downloader.java b/src/be/nikiroo/utils/Downloader.java index 1b82755..2919ff0 100644 --- a/src/be/nikiroo/utils/Downloader.java +++ b/src/be/nikiroo/utils/Downloader.java @@ -202,11 +202,19 @@ public class Downloader { conn.connect(); // Check if redirect - if (conn instanceof HttpURLConnection - && ((HttpURLConnection) conn).getResponseCode() / 100 == 3) { - String newUrl = conn.getHeaderField("Location"); - return open(new URL(newUrl), originalUrl, currentReferer, - cookiesValues, postParams, getParams, oauth); + if (conn instanceof HttpURLConnection) { + int repCode = 0; + try { + // Can fail in some circumstances + repCode = ((HttpURLConnection) conn).getResponseCode(); + } catch (IOException e) { + } + + if (repCode / 100 == 3) { + String newUrl = conn.getHeaderField("Location"); + return open(new URL(newUrl), originalUrl, currentReferer, + cookiesValues, postParams, getParams, oauth); + } } InputStream in = conn.getInputStream(); -- 2.27.0 From e772626b9593bc1a8c8ec1ca9cfbd4386a51f2ba Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 19 Mar 2018 19:06:04 +0100 Subject: [PATCH 02/16] Version 4.2.1: fix small bug in Downloader --- VERSION | 2 +- changelog.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 6aba2b2..fae6e3d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.2.0 +4.2.1 diff --git a/changelog.md b/changelog.md index 0584827..7b44b8b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # nikiroo-utils +## Version 4.2.1 + +- Fix small bug in Downloader + ## Version 4.2.0 - New getLanguage() in TransBundle -- 2.27.0 From 4110f63bcffb5112677fad45a6952314bde713df Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Fri, 23 Mar 2018 14:49:03 +0100 Subject: [PATCH 03/16] New: IOUtils.unzip() --- changelog.md | 4 +++ src/be/nikiroo/utils/IOUtils.java | 53 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/changelog.md b/changelog.md index 7b44b8b..8892800 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # nikiroo-utils +## Version 4.3.0 + +- New: IOUtils.Unzip() + ## Version 4.2.1 - Fix small bug in Downloader diff --git a/src/be/nikiroo/utils/IOUtils.java b/src/be/nikiroo/utils/IOUtils.java index d833114..3e2f6e7 100644 --- a/src/be/nikiroo/utils/IOUtils.java +++ b/src/be/nikiroo/utils/IOUtils.java @@ -13,6 +13,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; /** @@ -141,6 +142,58 @@ public class IOUtils { } } + /** + * Unzip the given ZIP file into the target directory. + * + * @param zipFile + * the ZIP file + * @param targetDirectory + * the target directory + * + * @return the number of extracted files (not directories) + * + * @throws IOException + * in case of I/O errors + */ + public static long unzip(File zipFile, File targetDirectory) + throws IOException { + long count = 0; + + if (targetDirectory.exists() && targetDirectory.isFile()) { + throw new IOException("Cannot unzip " + zipFile + " into " + + targetDirectory + ": it is not a directory"); + } + + targetDirectory.mkdir(); + if (!targetDirectory.exists()) { + throw new IOException("Cannot create target directory " + + targetDirectory); + } + + FileInputStream in = new FileInputStream(zipFile); + try { + ZipInputStream zipStream = new ZipInputStream(in); + try { + for (ZipEntry entry = zipStream.getNextEntry(); entry != null; entry = zipStream + .getNextEntry()) { + File file = new File(targetDirectory, entry.getName()); + if (entry.isDirectory()) { + file.mkdirs(); + } else { + IOUtils.write(zipStream, file); + count++; + } + } + } finally { + zipStream.close(); + } + } finally { + in.close(); + } + + return count; + } + /** * Write the {@link String} content to {@link File}. * -- 2.27.0 From 534332fff48954b4d26c6394a79d7a7aff605f67 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 25 Mar 2018 11:40:12 +0200 Subject: [PATCH 04/16] TestCase: improve error messages for comparisons --- src/be/nikiroo/utils/test/TestCase.java | 54 ++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/be/nikiroo/utils/test/TestCase.java b/src/be/nikiroo/utils/test/TestCase.java index 5cff363..4e7d380 100644 --- a/src/be/nikiroo/utils/test/TestCase.java +++ b/src/be/nikiroo/utils/test/TestCase.java @@ -44,7 +44,6 @@ abstract public class TestCase { * @throws Exception * in case of error */ - @SuppressWarnings("unused") public void setUp() throws Exception { } @@ -54,7 +53,6 @@ abstract public class TestCase { * @throws Exception * in case of error */ - @SuppressWarnings("unused") public void tearDown() throws Exception { } @@ -259,14 +257,37 @@ abstract public class TestCase { */ public void assertEquals(List expected, List actual) throws AssertException { + assertEquals("Assertion failed", expected, actual); + } + + /** + * Check that 2 {@link List}s are equals. + * + * @param errorMessage + * the error message to display if they differ + * @param expected + * the expected value + * @param actual + * the actual value + * @param errorMessage + * the error message to display if they differ + * + * @throws AssertException + * in case they differ + */ + public void assertEquals(String errorMessage, List expected, + List actual) throws AssertException { - assertEquals("The 2 lists don't contain the same number of items", - expected.size(), actual.size()); + if (expected.size() != actual.size()) { + assertEquals(errorMessage + ": not same number of items", + list(expected), list(actual)); + } int size = expected.size(); for (int i = 0; i < size; i++) { - assertEquals("Line " + i + " (0-based) is not correct", - expected.get(i), actual.get(i)); + assertEquals(errorMessage + ": item " + i + + " (0-based) is not correct", expected.get(i), + actual.get(i)); } } @@ -314,4 +335,25 @@ abstract public class TestCase { + "Expected value: [%s]%n" // + "Actual value: [%s]", expected, actual); } + + private static String list(List items) { + StringBuilder builder = new StringBuilder(); + for (Object item : items) { + if (builder.length() == 0) { + builder.append(items.size() + " item(s): "); + } else { + builder.append(", "); + } + + builder.append("" + item); + + if (builder.length() > 60) { + builder.setLength(57); + builder.append("..."); + break; + } + } + + return builder.toString(); + } } -- 2.27.0 From f6d228ae45e9467ac523a35721f667e4facc3cab Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 25 Mar 2018 11:40:40 +0200 Subject: [PATCH 05/16] Version 4.3.0: unzip, better list comparison mess. --- VERSION | 2 +- changelog.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index fae6e3d..8089590 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.2.1 +4.3.0 diff --git a/changelog.md b/changelog.md index 8892800..d1a53ca 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ ## Version 4.3.0 - New: IOUtils.Unzip() +- TestCase: better message for lists comparisons ## Version 4.2.1 -- 2.27.0 From ce060f5a4fcbea33cbecf2e8696fde7db183bff0 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Fri, 6 Apr 2018 16:46:19 +0200 Subject: [PATCH 06/16] New Utils main classes + ImageUtils fixes --- ImageUtils.sh | 3 + changelog.md | 5 + src/be/nikiroo/utils/IOUtils.java | 18 ++- .../nikiroo/utils/main/StartImageUtils.java | 131 ++++++++++++++++++ .../nikiroo/utils/main/StartStringUtils.java | 5 + src/be/nikiroo/utils/test/Test.java | 6 + src/be/nikiroo/utils/ui/ImageTextAwt.java | 46 ++++-- 7 files changed, 199 insertions(+), 15 deletions(-) create mode 100755 ImageUtils.sh create mode 100644 src/be/nikiroo/utils/main/StartImageUtils.java create mode 100644 src/be/nikiroo/utils/main/StartStringUtils.java diff --git a/ImageUtils.sh b/ImageUtils.sh new file mode 100755 index 0000000..8e12b66 --- /dev/null +++ b/ImageUtils.sh @@ -0,0 +1,3 @@ +#!/bin/sh +exec java -cp nikiroo-utils.jar be.nikiroo.utils.main.StartImageUtils "$@" + diff --git a/changelog.md b/changelog.md index d1a53ca..5a2ecd0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,10 @@ # nikiroo-utils +## Version WIP + +- New: Utils now have a main class +- Image to text converion fixes + ## Version 4.3.0 - New: IOUtils.Unzip() diff --git a/src/be/nikiroo/utils/IOUtils.java b/src/be/nikiroo/utils/IOUtils.java index 3e2f6e7..0d9bc37 100644 --- a/src/be/nikiroo/utils/IOUtils.java +++ b/src/be/nikiroo/utils/IOUtils.java @@ -213,7 +213,23 @@ public class IOUtils { dir.mkdirs(); } - FileWriter writerVersion = new FileWriter(new File(dir, filename)); + writeSmallFile(new File(dir, filename), content); + } + + /** + * Write the {@link String} content to {@link File}. + * + * @param file + * the {@link File} to write + * @param content + * the content + * + * @throws IOException + * in case of I/O error + */ + public static void writeSmallFile(File file, String content) + throws IOException { + FileWriter writerVersion = new FileWriter(file); try { writerVersion.write(content); } finally { diff --git a/src/be/nikiroo/utils/main/StartImageUtils.java b/src/be/nikiroo/utils/main/StartImageUtils.java new file mode 100644 index 0000000..99f753c --- /dev/null +++ b/src/be/nikiroo/utils/main/StartImageUtils.java @@ -0,0 +1,131 @@ +package be.nikiroo.utils.main; + +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import be.nikiroo.utils.IOUtils; +import be.nikiroo.utils.Image; +import be.nikiroo.utils.ui.ImageTextAwt; +import be.nikiroo.utils.ui.ImageTextAwt.Mode; +import be.nikiroo.utils.ui.ImageUtilsAwt; + +public class StartImageUtils { + /** + * ImageUtils main entry point. + *

+ * Syntax: see --help + * + * @param args + */ + public static void main(String[] args) { + Dimension size = null; + Mode mode = null; + boolean invert = false; + List inputs = new ArrayList(); + File output = null; + + String lastArg = ""; + try { + int height = -1; + int width = -1; + + for (String arg : args) { + lastArg = arg; + + if (arg.startsWith("--mode=")) { + mode = Mode.valueOf(arg.substring("--mode=".length())); + } else if (arg.startsWith("--width=")) { + width = Integer + .parseInt(arg.substring("--width=".length())); + } else if (arg.startsWith("--height=")) { + height = Integer.parseInt(arg.substring("--height=" + .length())); + } else if (arg.startsWith("--size=")) { + String content = arg.substring("--size=".length()) + .replace("X", "x"); + width = Integer.parseInt(content.split("x")[0]); + height = Integer.parseInt(content.split("x")[1]); + } else if (arg.startsWith("--ouput=")) { + if (!arg.equals("--output=-")) { + output = new File(arg.substring("--output=".length())); + } + } else if (arg.equals("--invert")) { + invert = true; + } else if (arg.equals("--help")) { + System.out + .println("Syntax: (--mode=MODE) (--width=WIDTH) (--height=HEIGHT) (--size=SIZE) (--output=OUTPUT) (--invert) (--help)"); + System.out.println("\t --help: will show this screen"); + System.out + .println("\t --invert: will invert the 'colours'"); + System.out + .println("\t --mode: will select the rendering mode (default: ASCII):"); + System.out + .println("\t\t ASCII: ASCI output mode, that is, characters \" .-+=o8#\""); + System.out + .println("\t\t DITHERING: Use 5 different \"colours\" which are actually" + + "\n\t\t Unicode characters \" ░▒▓█\""); + System.out + .println("\t\t DOUBLE_RESOLUTION: Use \"block\" Unicode characters up to quarter" + + "\n\t\t blocks, thus in effect doubling the resolution both in vertical" + + "\n\t\t and horizontal space." + + "\n\t\t Note that since 2 characters next to each other are square," + + "\n\t\t 4 blocks per 2 blocks for w/h resolution."); + System.out + .println("\t\t DOUBLE_DITHERING: Use characters from both DOUBLE_RESOLUTION" + + "\n\t\t and DITHERING"); + return; + } else { + inputs.add(arg); + } + } + + size = new Dimension(width, height); + if (inputs.size() == 0) { + inputs.add("-"); // by default, stdin + } + } catch (Exception e) { + System.err.println("Syntax error: \"" + lastArg + "\" is invalid"); + System.exit(1); + } + + try { + if (mode == null) { + mode = Mode.ASCII; + } + + for (String input : inputs) { + InputStream in = null; + + try { + if (input.equals("-")) { + in = System.in; + } else { + in = new FileInputStream(input); + } + BufferedImage image = ImageUtilsAwt + .fromImage(new Image(in)); + ImageTextAwt img = new ImageTextAwt(image, size, mode, + invert); + if (output == null) { + System.out.println(img.getText()); + } else { + IOUtils.writeSmallFile(output, img.getText()); + } + } finally { + if (!input.equals("-")) { + in.close(); + } + } + } + } catch (IOException e) { + e.printStackTrace(); + System.exit(2); + } + } +} diff --git a/src/be/nikiroo/utils/main/StartStringUtils.java b/src/be/nikiroo/utils/main/StartStringUtils.java new file mode 100644 index 0000000..ba5ccc6 --- /dev/null +++ b/src/be/nikiroo/utils/main/StartStringUtils.java @@ -0,0 +1,5 @@ +package be.nikiroo.utils.main; + +public class StartStringUtils { + +} diff --git a/src/be/nikiroo/utils/test/Test.java b/src/be/nikiroo/utils/test/Test.java index dd6bf61..7fe9bbc 100644 --- a/src/be/nikiroo/utils/test/Test.java +++ b/src/be/nikiroo/utils/test/Test.java @@ -2,6 +2,8 @@ package be.nikiroo.utils.test; import be.nikiroo.utils.Cache; import be.nikiroo.utils.Downloader; +import be.nikiroo.utils.main.StartImageUtils; +import be.nikiroo.utils.main.StartStringUtils; /** * Tests for nikiroo-utils. @@ -31,6 +33,10 @@ public class Test extends TestLauncher { // TODO: test cache and downloader Cache cache = null; Downloader downloader = null; + + // To include the sources: + StartImageUtils siu; + StartStringUtils ssu; } /** diff --git a/src/be/nikiroo/utils/ui/ImageTextAwt.java b/src/be/nikiroo/utils/ui/ImageTextAwt.java index ee4f58c..8fdaa86 100644 --- a/src/be/nikiroo/utils/ui/ImageTextAwt.java +++ b/src/be/nikiroo/utils/ui/ImageTextAwt.java @@ -165,30 +165,48 @@ public class ImageTextAwt { mult = 2; } + Dimension srcSize = getSize(image); + srcSize = new Dimension(srcSize.width * 2, srcSize.height); + int x = 0; + int y = 0; + int w = size.width * mult; int h = size.height * mult; + // Default = original ratio or original size if none + if (w < 0 || h < 0) { + if (w < 0 && h < 0) { + w = srcSize.width * mult; + h = srcSize.height * mult; + } else { + double ratioSrc = (double) srcSize.width + / (double) srcSize.height; + if (w < 0) { + w = (int) Math.round(h * ratioSrc); + } else { + h = (int) Math.round(w / ratioSrc); + } + } + } + + // Fail safe: we consider this to be too much + if (w > 1000 || h > 1000) { + return "[IMAGE TOO BIG]"; + } + BufferedImage buff = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics gfx = buff.getGraphics(); - Dimension srcSize = getSize(image); - srcSize = new Dimension(srcSize.width * 2, srcSize.height); - int x = 0; - int y = 0; - + double ratioAsked = (double) (w) / (double) (h); + double ratioSrc = (double) srcSize.height / (double) srcSize.width; + double ratio = ratioAsked * ratioSrc; if (srcSize.width < srcSize.height) { - double ratio = (double) size.width / (double) size.height; - ratio *= (double) srcSize.height / (double) srcSize.width; - h = (int) Math.round(ratio * h); y = (buff.getHeight() - h) / 2; } else { - double ratio = (double) size.height / (double) size.width; - ratio *= (double) srcSize.width / (double) srcSize.height; - - w = (int) Math.round(ratio * w); + w = (int) Math.round(w / ratio); x = (buff.getWidth() - w) / 2; } @@ -214,12 +232,12 @@ public class ImageTextAwt { StringBuilder builder = new StringBuilder(); - for (int row = 0; row < buff.getHeight(); row += mult) { + for (int row = 0; row + (mult - 1) < buff.getHeight(); row += mult) { if (row > 0) { builder.append('\n'); } - for (int col = 0; col < buff.getWidth(); col += mult) { + for (int col = 0; col + (mult - 1) < buff.getWidth(); col += mult) { if (mult == 1) { char car = ' '; float brightness = getBrightness(buff.getRGB(col, row)); -- 2.27.0 From 9e50696ec75e70b4eb592a9a1b6fceacf169977f Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 10 Apr 2018 08:54:16 +0200 Subject: [PATCH 07/16] new 'justify' tool + rename ImageUtils -> img2aa --- ImageUtils.sh | 3 - img2aa | 3 + .../nikiroo/utils/main/StartStringUtils.java | 5 - .../{StartImageUtils.java => img2aa.java} | 16 +++- src/be/nikiroo/utils/main/justify.java | 95 +++++++++++++++++++ src/be/nikiroo/utils/test/Test.java | 8 +- 6 files changed, 113 insertions(+), 17 deletions(-) delete mode 100755 ImageUtils.sh create mode 100755 img2aa delete mode 100644 src/be/nikiroo/utils/main/StartStringUtils.java rename src/be/nikiroo/utils/main/{StartImageUtils.java => img2aa.java} (92%) create mode 100644 src/be/nikiroo/utils/main/justify.java diff --git a/ImageUtils.sh b/ImageUtils.sh deleted file mode 100755 index 8e12b66..0000000 --- a/ImageUtils.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -exec java -cp nikiroo-utils.jar be.nikiroo.utils.main.StartImageUtils "$@" - diff --git a/img2aa b/img2aa new file mode 100755 index 0000000..e689894 --- /dev/null +++ b/img2aa @@ -0,0 +1,3 @@ +#!/bin/sh +exec nikiroo-utils be.nikiroo.utils.main.img2aa "$@" + diff --git a/src/be/nikiroo/utils/main/StartStringUtils.java b/src/be/nikiroo/utils/main/StartStringUtils.java deleted file mode 100644 index ba5ccc6..0000000 --- a/src/be/nikiroo/utils/main/StartStringUtils.java +++ /dev/null @@ -1,5 +0,0 @@ -package be.nikiroo.utils.main; - -public class StartStringUtils { - -} diff --git a/src/be/nikiroo/utils/main/StartImageUtils.java b/src/be/nikiroo/utils/main/img2aa.java similarity index 92% rename from src/be/nikiroo/utils/main/StartImageUtils.java rename to src/be/nikiroo/utils/main/img2aa.java index 99f753c..9cc6f0c 100644 --- a/src/be/nikiroo/utils/main/StartImageUtils.java +++ b/src/be/nikiroo/utils/main/img2aa.java @@ -15,11 +15,17 @@ import be.nikiroo.utils.ui.ImageTextAwt; import be.nikiroo.utils.ui.ImageTextAwt.Mode; import be.nikiroo.utils.ui.ImageUtilsAwt; -public class StartImageUtils { +/** + * Image to ASCII conversion. + * + * @author niki + */ +public class img2aa { /** - * ImageUtils main entry point. + * Syntax: (--mode=MODE) (--width=WIDTH) (--height=HEIGHT) (--size=SIZE) + * (--output=OUTPUT) (--invert) (--help) *

- * Syntax: see --help + * See "--help". * * @param args */ @@ -47,8 +53,8 @@ public class StartImageUtils { height = Integer.parseInt(arg.substring("--height=" .length())); } else if (arg.startsWith("--size=")) { - String content = arg.substring("--size=".length()) - .replace("X", "x"); + String content = arg.substring("--size=".length()).replace( + "X", "x"); width = Integer.parseInt(content.split("x")[0]); height = Integer.parseInt(content.split("x")[1]); } else if (arg.startsWith("--ouput=")) { diff --git a/src/be/nikiroo/utils/main/justify.java b/src/be/nikiroo/utils/main/justify.java new file mode 100644 index 0000000..cf58905 --- /dev/null +++ b/src/be/nikiroo/utils/main/justify.java @@ -0,0 +1,95 @@ +package be.nikiroo.utils.main; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import be.nikiroo.utils.StringUtils; +import be.nikiroo.utils.StringUtils.Alignment; + +/** + * Text justification (left, right, center, justify). + * + * @author niki + */ +public class justify { + /** + * Syntax: $0 ([left|right|center|justify]) (max width) + *

+ *

    + *
  • mode: left, right, center or full justification (defaults to left)
  • + *
  • max width: the maximum width of a line, or "" for "no maximum" + * (defaults to "no maximum")
  • + *
+ * + * @param args + */ + public static void main(String[] args) { + int width = -1; + StringUtils.Alignment align = Alignment.LEFT; + + if (args.length >= 1) { + align = Alignment.valueOf(args[0].toUpperCase()); + } + if (args.length >= 2) { + width = Integer.parseInt(args[1]); + } + + // TODO: move to utils? + List lines = new ArrayList(); + Scanner scan = new Scanner(System.in); + scan.useDelimiter("[\r\n]"); + try { + StringBuilder previous = null; + StringBuilder tmp = new StringBuilder(); + while (scan.hasNext()) { + String current = scan.next(); + tmp.setLength(0); + for (String word : current.split(" ")) { + if (word.isEmpty()) { + continue; + } + + if (tmp.length() > 0) { + tmp.append(' '); + } + tmp.append(word.trim()); + } + current = tmp.toString(); + + if (previous == null) { + previous = new StringBuilder(); + } else { + if (current.isEmpty() || isFullLine(previous)) { + lines.add(previous.toString()); + previous.setLength(0); + } else { + previous.append(' '); + } + } + + previous.append(current); + } + + if (previous != null) { + lines.add(previous.toString()); + } + } finally { + scan.close(); + } + + // TODO: supports bullet lines "- xxx" and sub levels + for (String line : lines) { + for (String subline : StringUtils.justifyText(line, width, align)) { + System.out.println(subline); + } + } + } + + static private boolean isFullLine(StringBuilder line) { + return line.length() == 0 // + || line.charAt(line.length() - 1) == '.' + || line.charAt(line.length() - 1) == '"' + || line.charAt(line.length() - 1) == '»'; + } +} diff --git a/src/be/nikiroo/utils/test/Test.java b/src/be/nikiroo/utils/test/Test.java index 7fe9bbc..e0dfa0f 100644 --- a/src/be/nikiroo/utils/test/Test.java +++ b/src/be/nikiroo/utils/test/Test.java @@ -2,8 +2,8 @@ package be.nikiroo.utils.test; import be.nikiroo.utils.Cache; import be.nikiroo.utils.Downloader; -import be.nikiroo.utils.main.StartImageUtils; -import be.nikiroo.utils.main.StartStringUtils; +import be.nikiroo.utils.main.img2aa; +import be.nikiroo.utils.main.justify; /** * Tests for nikiroo-utils. @@ -35,8 +35,8 @@ public class Test extends TestLauncher { Downloader downloader = null; // To include the sources: - StartImageUtils siu; - StartStringUtils ssu; + img2aa siu; + justify ssu; } /** -- 2.27.0 From 3cde28f95e0a0a31722ce457c7ffb6a71e21f2ee Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 10 Apr 2018 09:13:56 +0200 Subject: [PATCH 08/16] Fix img2aa, add justify wrappers --- img2aa | 18 +++++++++++++++++- justify | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 justify diff --git a/img2aa b/img2aa index e689894..8e5db09 100755 --- a/img2aa +++ b/img2aa @@ -1,3 +1,19 @@ #!/bin/sh -exec nikiroo-utils be.nikiroo.utils.main.img2aa "$@" +NAME=nikiroo-utils.jar + +jar="$NAME" +if [ ! -e "$jar" ]; then + jar="`dirname "$0"`/$NAME" +fi + +if [ ! -e "$jar" ]; then + jar="`whereis "$NAME" | sed 's: :\n:g' | grep "$NAME" | head -n1`" +fi + +if [ ! -e "$jar" ]; then + echo "$NAME not found." >&2 + exit 1 +fi + +exec java -cp "$jar" be.nikiroo.utils.main.img2aa "$@" diff --git a/justify b/justify new file mode 100755 index 0000000..8d94a60 --- /dev/null +++ b/justify @@ -0,0 +1,19 @@ +#!/bin/sh +NAME=nikiroo-utils.jar + +jar="$NAME" +if [ ! -e "$jar" ]; then + jar="`dirname "$0"`/$NAME" +fi + +if [ ! -e "$jar" ]; then + jar="`whereis "$NAME" | sed 's: :\n:g' | grep "$NAME" | head -n1`" +fi + +if [ ! -e "$jar" ]; then + echo "$NAME not found." >&2 + exit 1 +fi + +exec java -cp "$jar" be.nikiroo.utils.main.justify "$@" + -- 2.27.0 From 67e9a06e496d2c11432e4356c71e0af5a9204b16 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Tue, 10 Apr 2018 10:08:34 +0200 Subject: [PATCH 09/16] justify tool: accepts \r\n text --- src/be/nikiroo/utils/main/justify.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/be/nikiroo/utils/main/justify.java b/src/be/nikiroo/utils/main/justify.java index cf58905..32cfb10 100644 --- a/src/be/nikiroo/utils/main/justify.java +++ b/src/be/nikiroo/utils/main/justify.java @@ -38,7 +38,7 @@ public class justify { // TODO: move to utils? List lines = new ArrayList(); Scanner scan = new Scanner(System.in); - scan.useDelimiter("[\r\n]"); + scan.useDelimiter("\r\n|[\r\n]"); try { StringBuilder previous = null; StringBuilder tmp = new StringBuilder(); @@ -90,6 +90,7 @@ public class justify { return line.length() == 0 // || line.charAt(line.length() - 1) == '.' || line.charAt(line.length() - 1) == '"' - || line.charAt(line.length() - 1) == '»'; + || line.charAt(line.length() - 1) == '»' + ; } } -- 2.27.0 From a5d976cda8048c53a4b4fdeee458eab05959bec5 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 08:47:24 +0200 Subject: [PATCH 10/16] justify: supports bullet lists --- src/be/nikiroo/utils/main/justify.java | 101 ++++++++++++++++++++----- 1 file changed, 82 insertions(+), 19 deletions(-) diff --git a/src/be/nikiroo/utils/main/justify.java b/src/be/nikiroo/utils/main/justify.java index 32cfb10..68f5358 100644 --- a/src/be/nikiroo/utils/main/justify.java +++ b/src/be/nikiroo/utils/main/justify.java @@ -1,7 +1,9 @@ package be.nikiroo.utils.main; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; import java.util.Scanner; import be.nikiroo.utils.StringUtils; @@ -36,52 +38,98 @@ public class justify { } // TODO: move to utils? - List lines = new ArrayList(); + // Content <-> Bullet spacing (null = no spacing) + List> lines = new ArrayList>(); Scanner scan = new Scanner(System.in); scan.useDelimiter("\r\n|[\r\n]"); try { StringBuilder previous = null; StringBuilder tmp = new StringBuilder(); + String previousItemBulletSpacing = null; + String itemBulletSpacing = null; while (scan.hasNext()) { - String current = scan.next(); - tmp.setLength(0); - for (String word : current.split(" ")) { - if (word.isEmpty()) { - continue; + boolean previousLineComplete = true; + + String current = scan.next().replace("\t", " "); + itemBulletSpacing = getItemSpacing(current); + boolean bullet = isItemLine(current); + if ((previousItemBulletSpacing == null || itemBulletSpacing + .length() <= previousItemBulletSpacing.length()) + && !bullet) { + itemBulletSpacing = null; + } + + if (itemBulletSpacing != null) { + current = current.trim(); + if (!current.isEmpty() && bullet) { + current = current.substring(1); } + current = current.trim(); + previousLineComplete = bullet; + } else { + tmp.setLength(0); + for (String word : current.split(" ")) { + if (word.isEmpty()) { + continue; + } - if (tmp.length() > 0) { - tmp.append(' '); + if (tmp.length() > 0) { + tmp.append(' '); + } + tmp.append(word.trim()); } - tmp.append(word.trim()); + current = tmp.toString(); + + previousLineComplete = current.isEmpty() + || previousItemBulletSpacing != null + || (previous != null && isFullLine(previous)); } - current = tmp.toString(); if (previous == null) { previous = new StringBuilder(); } else { - if (current.isEmpty() || isFullLine(previous)) { - lines.add(previous.toString()); + if (previousLineComplete) { + lines.add(new AbstractMap.SimpleEntry( + previous.toString(), previousItemBulletSpacing)); previous.setLength(0); + previousItemBulletSpacing = itemBulletSpacing; } else { previous.append(' '); } } previous.append(current); + } if (previous != null) { - lines.add(previous.toString()); + lines.add(new AbstractMap.SimpleEntry(previous + .toString(), previousItemBulletSpacing)); } } finally { scan.close(); } - // TODO: supports bullet lines "- xxx" and sub levels - for (String line : lines) { - for (String subline : StringUtils.justifyText(line, width, align)) { - System.out.println(subline); + for (Entry line : lines) { + String content = line.getKey(); + String spacing = line.getValue(); + + String bullet = "- "; + if (spacing == null) { + bullet = ""; + spacing = ""; + } + + if (spacing.length() > width + 3) { + spacing = ""; + } + + for (String subline : StringUtils.justifyText(content, width + - (spacing.length() + bullet.length()), align)) { + System.out.println(spacing + bullet + subline); + if (!bullet.isEmpty()) { + bullet = " "; + } } } } @@ -90,7 +138,22 @@ public class justify { return line.length() == 0 // || line.charAt(line.length() - 1) == '.' || line.charAt(line.length() - 1) == '"' - || line.charAt(line.length() - 1) == '»' - ; + || line.charAt(line.length() - 1) == '»'; + } + + static private boolean isItemLine(String line) { + String spacing = getItemSpacing(line); + return spacing != null && line.charAt(spacing.length()) == '-'; + } + + static private String getItemSpacing(String line) { + int i; + for (i = 0; i < line.length(); i++) { + if (line.charAt(i) != ' ') { + return line.substring(0, i); + } + } + + return ""; } } -- 2.27.0 From dc22eb95c9b74c41e229f48e021a8a0c85992f35 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 08:57:23 +0200 Subject: [PATCH 11/16] Move justify List into StringUtils (tests needed) --- src/be/nikiroo/utils/StringUtils.java | 150 +++++++++++++++++++++++++ src/be/nikiroo/utils/main/justify.java | 114 +------------------ 2 files changed, 154 insertions(+), 110 deletions(-) diff --git a/src/be/nikiroo/utils/StringUtils.java b/src/be/nikiroo/utils/StringUtils.java index 9e5d654..b8468a1 100644 --- a/src/be/nikiroo/utils/StringUtils.java +++ b/src/be/nikiroo/utils/StringUtils.java @@ -9,8 +9,11 @@ import java.text.Normalizer; import java.text.Normalizer.Form; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.AbstractMap; +import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map.Entry; import java.util.Scanner; import java.util.regex.Pattern; @@ -193,6 +196,128 @@ public class StringUtils { } } + /** + * Justify a text into width-sized (at the maximum) lines. + * + * @param text + * the {@link String} to justify + * @param width + * the maximum size of the resulting lines + * + * @return a list of justified text lines + */ + static public List justifyText(List text, int width) { + return justifyText(text, width, null); + } + + /** + * Justify a text into width-sized (at the maximum) lines. + * + * @param text + * the {@link String} to justify + * @param width + * the maximum size of the resulting lines + * @param align + * align the lines in this position (default is + * Alignment.Beginning) + * + * @return a list of justified text lines + */ + static public List justifyText(List text, int width, + Alignment align) { + List result = new ArrayList(); + + // Content <-> Bullet spacing (null = no spacing) + List> lines = new ArrayList>(); + StringBuilder previous = null; + StringBuilder tmp = new StringBuilder(); + String previousItemBulletSpacing = null; + String itemBulletSpacing = null; + for (String inputLine : text) { + boolean previousLineComplete = true; + + String current = inputLine.replace("\t", " "); + itemBulletSpacing = getItemSpacing(current); + boolean bullet = isItemLine(current); + if ((previousItemBulletSpacing == null || itemBulletSpacing + .length() <= previousItemBulletSpacing.length()) && !bullet) { + itemBulletSpacing = null; + } + + if (itemBulletSpacing != null) { + current = current.trim(); + if (!current.isEmpty() && bullet) { + current = current.substring(1); + } + current = current.trim(); + previousLineComplete = bullet; + } else { + tmp.setLength(0); + for (String word : current.split(" ")) { + if (word.isEmpty()) { + continue; + } + + if (tmp.length() > 0) { + tmp.append(' '); + } + tmp.append(word.trim()); + } + current = tmp.toString(); + + previousLineComplete = current.isEmpty() + || previousItemBulletSpacing != null + || (previous != null && isFullLine(previous)); + } + + if (previous == null) { + previous = new StringBuilder(); + } else { + if (previousLineComplete) { + lines.add(new AbstractMap.SimpleEntry( + previous.toString(), previousItemBulletSpacing)); + previous.setLength(0); + previousItemBulletSpacing = itemBulletSpacing; + } else { + previous.append(' '); + } + } + + previous.append(current); + + } + + if (previous != null) { + lines.add(new AbstractMap.SimpleEntry(previous + .toString(), previousItemBulletSpacing)); + } + + for (Entry line : lines) { + String content = line.getKey(); + String spacing = line.getValue(); + + String bullet = "- "; + if (spacing == null) { + bullet = ""; + spacing = ""; + } + + if (spacing.length() > width + 3) { + spacing = ""; + } + + for (String subline : StringUtils.justifyText(content, width + - (spacing.length() + bullet.length()), align)) { + result.add(spacing + bullet + subline); + if (!bullet.isEmpty()) { + bullet = " "; + } + } + } + + return result; + } + /** * Sanitise the given input to make it more Terminal-friendly by removing * combining characters. @@ -438,4 +563,29 @@ public class StringUtils { return null; } } + + // justify List related: + + static private boolean isFullLine(StringBuilder line) { + return line.length() == 0 // + || line.charAt(line.length() - 1) == '.' + || line.charAt(line.length() - 1) == '"' + || line.charAt(line.length() - 1) == '»'; + } + + static private boolean isItemLine(String line) { + String spacing = getItemSpacing(line); + return spacing != null && line.charAt(spacing.length()) == '-'; + } + + static private String getItemSpacing(String line) { + int i; + for (i = 0; i < line.length(); i++) { + if (line.charAt(i) != ' ') { + return line.substring(0, i); + } + } + + return ""; + } } diff --git a/src/be/nikiroo/utils/main/justify.java b/src/be/nikiroo/utils/main/justify.java index 68f5358..2a83389 100644 --- a/src/be/nikiroo/utils/main/justify.java +++ b/src/be/nikiroo/utils/main/justify.java @@ -1,9 +1,7 @@ package be.nikiroo.utils.main; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.List; -import java.util.Map.Entry; import java.util.Scanner; import be.nikiroo.utils.StringUtils; @@ -37,123 +35,19 @@ public class justify { width = Integer.parseInt(args[1]); } - // TODO: move to utils? - // Content <-> Bullet spacing (null = no spacing) - List> lines = new ArrayList>(); Scanner scan = new Scanner(System.in); scan.useDelimiter("\r\n|[\r\n]"); try { - StringBuilder previous = null; - StringBuilder tmp = new StringBuilder(); - String previousItemBulletSpacing = null; - String itemBulletSpacing = null; + List lines = new ArrayList(); while (scan.hasNext()) { - boolean previousLineComplete = true; - - String current = scan.next().replace("\t", " "); - itemBulletSpacing = getItemSpacing(current); - boolean bullet = isItemLine(current); - if ((previousItemBulletSpacing == null || itemBulletSpacing - .length() <= previousItemBulletSpacing.length()) - && !bullet) { - itemBulletSpacing = null; - } - - if (itemBulletSpacing != null) { - current = current.trim(); - if (!current.isEmpty() && bullet) { - current = current.substring(1); - } - current = current.trim(); - previousLineComplete = bullet; - } else { - tmp.setLength(0); - for (String word : current.split(" ")) { - if (word.isEmpty()) { - continue; - } - - if (tmp.length() > 0) { - tmp.append(' '); - } - tmp.append(word.trim()); - } - current = tmp.toString(); - - previousLineComplete = current.isEmpty() - || previousItemBulletSpacing != null - || (previous != null && isFullLine(previous)); - } - - if (previous == null) { - previous = new StringBuilder(); - } else { - if (previousLineComplete) { - lines.add(new AbstractMap.SimpleEntry( - previous.toString(), previousItemBulletSpacing)); - previous.setLength(0); - previousItemBulletSpacing = itemBulletSpacing; - } else { - previous.append(' '); - } - } - - previous.append(current); - + lines.add(scan.next()); } - if (previous != null) { - lines.add(new AbstractMap.SimpleEntry(previous - .toString(), previousItemBulletSpacing)); + for (String line : StringUtils.justifyText(lines, width, align)) { + System.out.println(line); } } finally { scan.close(); } - - for (Entry line : lines) { - String content = line.getKey(); - String spacing = line.getValue(); - - String bullet = "- "; - if (spacing == null) { - bullet = ""; - spacing = ""; - } - - if (spacing.length() > width + 3) { - spacing = ""; - } - - for (String subline : StringUtils.justifyText(content, width - - (spacing.length() + bullet.length()), align)) { - System.out.println(spacing + bullet + subline); - if (!bullet.isEmpty()) { - bullet = " "; - } - } - } - } - - static private boolean isFullLine(StringBuilder line) { - return line.length() == 0 // - || line.charAt(line.length() - 1) == '.' - || line.charAt(line.length() - 1) == '"' - || line.charAt(line.length() - 1) == '»'; - } - - static private boolean isItemLine(String line) { - String spacing = getItemSpacing(line); - return spacing != null && line.charAt(spacing.length()) == '-'; - } - - static private String getItemSpacing(String line) { - int i; - for (i = 0; i < line.length(); i++) { - if (line.charAt(i) != ' ') { - return line.substring(0, i); - } - } - - return ""; } } -- 2.27.0 From ef34f6f76b3446c7310b2c2057e01bfe725e7aa4 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 09:00:31 +0200 Subject: [PATCH 12/16] StringUtils: add a new (failed) test --- src/be/nikiroo/utils/test/StringUtilsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/be/nikiroo/utils/test/StringUtilsTest.java b/src/be/nikiroo/utils/test/StringUtilsTest.java index 6ebf43e..29f5bf3 100644 --- a/src/be/nikiroo/utils/test/StringUtilsTest.java +++ b/src/be/nikiroo/utils/test/StringUtilsTest.java @@ -174,6 +174,8 @@ class StringUtilsTest extends TestLauncher { "Un petit texte qui se mettra sur plusieurs lignes", 14, "Un petit", "texte qui se", "mettra sur", "plusieurs lig-", "nes"); + addValue(source, Alignment.JUSTIFY, "le dash-test", 9, + "le dash-", "test"); for (String data : source.keySet()) { for (int size : source.get(data).keySet()) { -- 2.27.0 From 6917b9b9682946639aea043c0b5c13656cdd0962 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 13:05:22 +0200 Subject: [PATCH 13/16] Fix StringJustifier error with dashes (-) --- src/be/nikiroo/utils/StringJustifier.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/be/nikiroo/utils/StringJustifier.java b/src/be/nikiroo/utils/StringJustifier.java index 9ea0b72..ed20291 100644 --- a/src/be/nikiroo/utils/StringJustifier.java +++ b/src/be/nikiroo/utils/StringJustifier.java @@ -26,6 +26,9 @@ * * @author Kevin Lamonte [kevin.lamonte@gmail.com] * @version 1 + * + * I added some changes to integrate it here. + * @author Niki */ package be.nikiroo.utils; @@ -220,8 +223,14 @@ class StringJustifier { if ((i + 1) < line.length()) { char car = line.charAt(i); char nextCar = line.charAt(i + 1); - if (nextCar == ' ' || car == '-' || nextCar == '-') { + if (car == ' ' || car == '-' || nextCar == ' ') { needDash = false; + } else if (i > 0) { + char prevCar = line.charAt(i - 1); + if (prevCar == ' ' || prevCar == '-') { + needDash = false; + i--; + } } } @@ -238,8 +247,8 @@ class StringJustifier { // no dash before parenthesis (but cannot add one more // after) if ((i + 1) < line.length()) { - char car = line.charAt(i + 1); - if (car == '(' || car == ')') { + char nextCar = line.charAt(i + 1); + if (nextCar == '(' || nextCar == ')') { needDash = false; } } -- 2.27.0 From c0c091af3d5ecd11fd46f517e6a1493f1454ceb0 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 13:31:59 +0200 Subject: [PATCH 14/16] StringUtils: justify: fix crash, supports HR lines --- src/be/nikiroo/utils/StringUtils.java | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/be/nikiroo/utils/StringUtils.java b/src/be/nikiroo/utils/StringUtils.java index b8468a1..2c90d29 100644 --- a/src/be/nikiroo/utils/StringUtils.java +++ b/src/be/nikiroo/utils/StringUtils.java @@ -267,7 +267,8 @@ public class StringUtils { previousLineComplete = current.isEmpty() || previousItemBulletSpacing != null - || (previous != null && isFullLine(previous)); + || (previous != null && isFullLine(previous)) + || isHrLine(current) || isHrLine(previous); } if (previous == null) { @@ -575,7 +576,8 @@ public class StringUtils { static private boolean isItemLine(String line) { String spacing = getItemSpacing(line); - return spacing != null && line.charAt(spacing.length()) == '-'; + return spacing != null && !spacing.isEmpty() + && line.charAt(spacing.length()) == '-'; } static private String getItemSpacing(String line) { @@ -588,4 +590,22 @@ public class StringUtils { return ""; } + + static private boolean isHrLine(CharSequence line) { + int count = 0; + if (line != null) { + for (int i = 0; i < line.length(); i++) { + char car = line.charAt(i); + if (car == ' ' || car == '\t' || car == '*' || car == '-' + || car == '_' || car == '~' || car == '=' || car == '/' + || car == '\\') { + count++; + } else { + return false; + } + } + } + + return count > 2; + } } -- 2.27.0 From 9db215c6238d776d39dae5b7c8d805cb6f4e9bd1 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Thu, 12 Apr 2018 19:20:41 +0200 Subject: [PATCH 15/16] image to text: improve DOUBLE_DITHERING --- src/be/nikiroo/utils/ui/ImageTextAwt.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/be/nikiroo/utils/ui/ImageTextAwt.java b/src/be/nikiroo/utils/ui/ImageTextAwt.java index 8fdaa86..4c0c824 100644 --- a/src/be/nikiroo/utils/ui/ImageTextAwt.java +++ b/src/be/nikiroo/utils/ui/ImageTextAwt.java @@ -389,7 +389,13 @@ public class ImageTextAwt { avg += getBrightness(lowerright); avg /= 4; - return getDitheringChar(avg, " ░▒▓█"); + // Since all the quarters are > 0.5, avg is between 0.5 and 1.0 + // So, expand the range of the value + avg = (avg - 0.5f) * 2; + + // Do not use the " " char, as it would make a + // "all quarters > 0.5" pixel go black + return getDitheringChar(avg, "░▒▓█"); } return '█'; -- 2.27.0 From b6af2a6f8ec1f1963f6d33db0f8708b3a9cf3341 Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Mon, 18 Jun 2018 08:54:14 +0200 Subject: [PATCH 16/16] Makefile: Fix jar/${JAR} --- Makefile.base | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.base b/Makefile.base index aeebcbd..70d6c01 100644 --- a/Makefile.base +++ b/Makefile.base @@ -3,6 +3,7 @@ # Version: # - 1.0.0: add a version comment # - 1.1.0: add help, sjar +# - 1.1.1: fix "jar" instead of ${JAR} # Required parameters (the commented out ones are supposed to change per project): @@ -76,10 +77,10 @@ clean: @for lib in libs/*-sources.jar libs/*-sources.patch.jar; do \ if [ "$$lib" != 'libs/*-sources.jar' -a "$$lib" != 'libs/*-sources.patch.jar' ]; then \ basename "$$lib"; \ - jar tf "$$lib" | while read -r ln; do \ + ${JAR} tf "$$lib" | while read -r ln; do \ [ -f "src/$$ln" ] && rm "src/$$ln"; \ done; \ - jar tf "$$lib" | tac | while read -r ln; do \ + ${JAR} tf "$$lib" | tac | while read -r ln; do \ [ -d "src/$$ln" ] && rmdir "src/$$ln" 2>/dev/null || true; \ done; \ fi \ @@ -122,7 +123,7 @@ libs: bin @[ -e bin/libs -o ! -d libs ] || (cd src && for lib in ../libs/*-sources.jar ../libs/*-sources.patch.jar; do \ if [ "$$lib" != '../libs/*-sources.jar' -a "$$lib" != '../libs/*-sources.patch.jar' ]; then \ basename "$$lib"; \ - jar xf "$$lib"; \ + ${JAR} xf "$$lib"; \ fi \ done ) @[ ! -d libs ] || touch bin/libs -- 2.27.0