ruby_wordcram 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.mvn/extensions.xml +8 -0
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  5. data/Rakefile +28 -5
  6. data/docs/_posts/2017-03-07-getting_started.md +3 -2
  7. data/docs/_posts/2017-03-07-under_the_hood.md +33 -0
  8. data/lib/WordCram.jar +0 -0
  9. data/lib/jsoup-1.10.2.jar +0 -0
  10. data/lib/ruby_wordcram/version.rb +1 -1
  11. data/lib/ruby_wordcram.rb +1 -2
  12. data/pom.rb +53 -0
  13. data/pom.xml +87 -0
  14. data/ruby_wordcram.gemspec +1 -2
  15. data/src/cue/lang/Counter.java +141 -0
  16. data/src/cue/lang/IterableText.java +10 -0
  17. data/src/cue/lang/NGramIterator.java +151 -0
  18. data/src/cue/lang/SentenceIterator.java +86 -0
  19. data/src/cue/lang/WordIterator.java +60 -0
  20. data/src/cue/lang/stop/StopWords.java +114 -0
  21. data/src/cue/lang/stop/arabic +351 -0
  22. data/src/cue/lang/stop/armenian +45 -0
  23. data/src/cue/lang/stop/catalan +219 -0
  24. data/src/cue/lang/stop/croatian +2024 -0
  25. data/src/cue/lang/stop/czech +256 -0
  26. data/src/cue/lang/stop/danish +94 -0
  27. data/src/cue/lang/stop/dutch +107 -0
  28. data/src/cue/lang/stop/english +183 -0
  29. data/src/cue/lang/stop/esperanto +180 -0
  30. data/src/cue/lang/stop/farsi +966 -0
  31. data/src/cue/lang/stop/finnish +235 -0
  32. data/src/cue/lang/stop/french +543 -0
  33. data/src/cue/lang/stop/german +231 -0
  34. data/src/cue/lang/stop/greek +637 -0
  35. data/src/cue/lang/stop/hebrew +220 -0
  36. data/src/cue/lang/stop/hindi +97 -0
  37. data/src/cue/lang/stop/hungarian +202 -0
  38. data/src/cue/lang/stop/italian +279 -0
  39. data/src/cue/lang/stop/latin +1 -0
  40. data/src/cue/lang/stop/norwegian +176 -0
  41. data/src/cue/lang/stop/polish +138 -0
  42. data/src/cue/lang/stop/portuguese +204 -0
  43. data/src/cue/lang/stop/romanian +284 -0
  44. data/src/cue/lang/stop/russian +652 -0
  45. data/src/cue/lang/stop/slovak +110 -0
  46. data/src/cue/lang/stop/slovenian +448 -0
  47. data/src/cue/lang/stop/spanish +308 -0
  48. data/src/cue/lang/stop/swedish +114 -0
  49. data/src/cue/lang/stop/turkish +117 -0
  50. data/src/cue/lang/unicode/BlockUtil.java +103 -0
  51. data/src/cue/lang/unicode/Normalizer.java +55 -0
  52. data/src/cue/lang/unicode/Normalizer6.java +32 -0
  53. data/src/license.txt +201 -0
  54. data/src/wordcram/Anglers.java +137 -0
  55. data/src/wordcram/BBTree.java +133 -0
  56. data/src/wordcram/BBTreeBuilder.java +61 -0
  57. data/src/wordcram/Colorers.java +52 -0
  58. data/src/wordcram/EngineWord.java +73 -0
  59. data/src/wordcram/Fonters.java +17 -0
  60. data/src/wordcram/HsbWordColorer.java +28 -0
  61. data/src/wordcram/ImageShaper.java +91 -0
  62. data/src/wordcram/Observer.java +9 -0
  63. data/src/wordcram/PlacerHeatMap.java +134 -0
  64. data/src/wordcram/Placers.java +74 -0
  65. data/src/wordcram/PlottingWordNudger.java +38 -0
  66. data/src/wordcram/PlottingWordPlacer.java +36 -0
  67. data/src/wordcram/ProcessingWordRenderer.java +42 -0
  68. data/src/wordcram/RandomWordNudger.java +44 -0
  69. data/src/wordcram/RenderOptions.java +10 -0
  70. data/src/wordcram/ShapeBasedPlacer.java +66 -0
  71. data/src/wordcram/Sizers.java +54 -0
  72. data/src/wordcram/SketchCallbackObserver.java +70 -0
  73. data/src/wordcram/SpiralWordNudger.java +31 -0
  74. data/src/wordcram/SvgWordRenderer.java +110 -0
  75. data/src/wordcram/SwirlWordPlacer.java +25 -0
  76. data/src/wordcram/UpperLeftWordPlacer.java +27 -0
  77. data/src/wordcram/WaveWordPlacer.java +25 -0
  78. data/src/wordcram/Word.java +357 -0
  79. data/src/wordcram/WordAngler.java +20 -0
  80. data/src/wordcram/WordArray.java +18 -0
  81. data/src/wordcram/WordBag.java +31 -0
  82. data/src/wordcram/WordColorer.java +25 -0
  83. data/src/wordcram/WordCounter.java +96 -0
  84. data/src/wordcram/WordCram.java +920 -0
  85. data/src/wordcram/WordCramEngine.java +196 -0
  86. data/src/wordcram/WordFonter.java +24 -0
  87. data/src/wordcram/WordNudger.java +44 -0
  88. data/src/wordcram/WordPlacer.java +44 -0
  89. data/src/wordcram/WordRenderer.java +10 -0
  90. data/src/wordcram/WordShaper.java +78 -0
  91. data/src/wordcram/WordSizer.java +46 -0
  92. data/src/wordcram/WordSkipReason.java +42 -0
  93. data/src/wordcram/WordSorterAndScaler.java +31 -0
  94. data/src/wordcram/WordSource.java +5 -0
  95. data/src/wordcram/text/Html.java +15 -0
  96. data/src/wordcram/text/Html2Text.java +17 -0
  97. data/src/wordcram/text/Text.java +15 -0
  98. data/src/wordcram/text/TextFile.java +23 -0
  99. data/src/wordcram/text/TextSource.java +5 -0
  100. data/src/wordcram/text/WebPage.java +23 -0
  101. metadata +94 -5
  102. data/lib/cue.language.jar +0 -0
  103. data/lib/jsoup-1.7.2.jar +0 -0
  104. data/vendors/Rakefile +0 -51
@@ -0,0 +1,9 @@
1
+ package wordcram;
2
+
3
+ public interface Observer {
4
+ public void wordsCounted(Word[] words);
5
+ public void beginDraw();
6
+ public void wordDrawn(Word word);
7
+ public void wordSkipped(Word word);
8
+ public void endDraw();
9
+ }
@@ -0,0 +1,134 @@
1
+ package wordcram;
2
+
3
+ import java.awt.Shape; // awt: word->shape->rect
4
+ import java.awt.geom.Rectangle2D; // awt: intersects(box), x-y-w-h, bounds
5
+ import java.util.ArrayList;
6
+ import java.util.HashMap;
7
+
8
+ import processing.core.PApplet;
9
+ import processing.core.PFont;
10
+ import processing.core.PVector;
11
+
12
+ public class PlacerHeatMap {
13
+
14
+ private final Word[] words;
15
+ private final WordFonter fonter;
16
+ private final WordSizer sizer;
17
+ private final WordAngler angler;
18
+ private final WordPlacer placer;
19
+ private final WordNudger nudger;
20
+ private final WordShaper shaper;
21
+
22
+ PlacerHeatMap(Word[] words, WordFonter fonter, WordSizer sizer, WordAngler angler, WordPlacer placer, WordNudger nudger, WordShaper shaper) {
23
+
24
+ this.fonter = fonter;
25
+ this.sizer = sizer;
26
+ this.angler = angler;
27
+ this.placer = placer;
28
+ this.nudger = nudger;
29
+ this.shaper = shaper;
30
+ this.words = words;
31
+ }
32
+
33
+ class RectStack {
34
+ ArrayList<Rectangle2D> rects = new ArrayList<>();
35
+
36
+ void add(int x, int y, int w, int h) {
37
+ rects.add(new Rectangle2D.Float(x, y, w, h));
38
+ }
39
+
40
+ int howManyIntersect(int x, int y, int w, int h) {
41
+ int sum = 0;
42
+
43
+ sum = rects.stream().filter((r) -> (r.intersects(x, y, w, h))).map((_item) -> 1).reduce(sum, Integer::sum);
44
+
45
+ return sum;
46
+ }
47
+ }
48
+
49
+ class RectGrid {
50
+ RectStack stack;
51
+ HashMap<Rectangle2D, Integer> levels = new HashMap<>();
52
+
53
+ RectGrid(RectStack stack) {
54
+ this.stack = stack;
55
+ }
56
+
57
+ void measure(int x, int y, int w, int h) {
58
+ Rectangle2D plot = new Rectangle2D.Float(x, y, w, h);
59
+ int level = stack.howManyIntersect(x, y, w, h);
60
+ levels.put(plot, level);
61
+ }
62
+
63
+ int maxLevel() {
64
+ int maxLevel = 0;
65
+ for (Integer level : levels.values()) {
66
+ if (level > maxLevel) {
67
+ maxLevel = level;
68
+ }
69
+ }
70
+ return maxLevel;
71
+ }
72
+
73
+ void draw(PApplet sketch) {
74
+ int rowHeight = 10;
75
+ int colWidth = 10;
76
+ int rows = (int)(sketch.height / (float)rowHeight);
77
+ int cols = (int)(sketch.width / (float)colWidth);
78
+
79
+ for (int i = 0; i < rows; i++) {
80
+ int y = i * rowHeight;
81
+ for (int j = 0; j < cols; j++) {
82
+ int x = j * colWidth;
83
+
84
+ measure(x, y, colWidth, rowHeight);
85
+ }
86
+ }
87
+
88
+ sketch.colorMode(PApplet.HSB);
89
+
90
+ int max = maxLevel();
91
+ levels.keySet().forEach((rect) -> {
92
+ Integer level = levels.get(rect);
93
+
94
+ int c = sketch.color(0);
95
+ if (level > 0) {
96
+ float scaled = (float)level / 8;
97
+ int hue = (int)PApplet.map(scaled, 0, 1, 85, 0); // 85 = pure green
98
+ c = sketch.color(hue, 255, 255);
99
+ }
100
+
101
+ sketch.fill(c);
102
+ sketch.rect((float)rect.getX(), (float)rect.getY(), (float)rect.getWidth(), (float)rect.getHeight());
103
+ });
104
+ }
105
+ }
106
+
107
+ public void draw(PApplet sketch) {
108
+ RectStack rectStack = new RectStack();
109
+
110
+ for (int i = 0; i < words.length; i++) {
111
+ Word word = words[i];
112
+ PFont wordFont = word.getFont(fonter);
113
+ float wordSize = word.getSize(sizer, i, words.length);
114
+ float wordAngle = word.getAngle(angler);
115
+
116
+ Shape shape = shaper.getShapeFor(word.word, wordFont, wordSize, wordAngle);
117
+ Rectangle2D rect = shape.getBounds2D();
118
+ //return r.getHeight() < minShapeSize || r.getWidth() < minShapeSize;
119
+
120
+ int wordImageWidth = (int)rect.getWidth();
121
+ int wordImageHeight = (int)rect.getHeight();
122
+
123
+ PVector desiredLocation = word.getTargetPlace(placer, i, words.length,
124
+ wordImageWidth, wordImageHeight, sketch.width, sketch.height);
125
+
126
+ //sketch.rect(desiredLocation.x, desiredLocation.y, wordImageWidth, wordImageHeight);
127
+ rectStack.add((int)desiredLocation.x, (int)desiredLocation.y,
128
+ wordImageWidth, wordImageHeight);
129
+ }
130
+
131
+ RectGrid grid = new RectGrid(rectStack);
132
+ grid.draw(sketch);
133
+ }
134
+ }
@@ -0,0 +1,74 @@
1
+ package wordcram;
2
+
3
+ import java.util.Random;
4
+
5
+ import processing.core.PApplet;
6
+ import processing.core.PVector;
7
+
8
+ public class Placers {
9
+
10
+ public static WordPlacer horizLine() {
11
+ final Random r = new Random();
12
+
13
+ return (Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) -> {
14
+ int centerHorizLine = (int) ((fieldHeight - wordImageHeight) * 0.5);
15
+ int centerVertLine = (int) ((fieldWidth - wordImageWidth) * 0.5);
16
+
17
+ float xOff = (float) r.nextGaussian() * ((fieldWidth - wordImageWidth) * 0.2f);
18
+ float yOff = (float) r.nextGaussian() * 50;
19
+
20
+ return new PVector(centerVertLine + xOff, centerHorizLine + yOff);
21
+ /*
22
+ int adjFieldWidth = fieldWidth - wordImageWidth;
23
+ int adjFieldHeight = fieldHeight - wordImageHeight;
24
+
25
+ float xOff = (float) r.nextGaussian();// * 0.2f;
26
+ float yOff = (float) r.nextGaussian();// * 0.5f;
27
+ yOff = (float)Math.pow(yOff, 3) * 1.5f;
28
+
29
+ return new PVector(PApplet.map(xOff, -2, 2, 0, adjFieldWidth),
30
+ PApplet.map(yOff, -2, 2, 0, adjFieldHeight));
31
+ */ };
32
+ }
33
+
34
+ public static WordPlacer centerClump() {
35
+ final Random r = new Random();
36
+ final float stdev = 0.4f;
37
+
38
+ return new WordPlacer() {
39
+
40
+ @Override
41
+ public PVector place(Word word, int wordIndex, int wordsCount,
42
+ int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) {
43
+ return new PVector(getOneUnder(fieldWidth - wordImageWidth),
44
+ getOneUnder(fieldHeight - wordImageHeight));
45
+ }
46
+
47
+ private int getOneUnder(float upperLimit) {
48
+ return PApplet.round(PApplet.map((float) r.nextGaussian()
49
+ * stdev, -2, 2, 0, upperLimit));
50
+ }
51
+ };
52
+ }
53
+
54
+ public static WordPlacer horizBandAnchoredLeft() {
55
+ final Random r = new Random();
56
+ return (Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) -> {
57
+ float x = (1 - word.weight) * fieldWidth * r.nextFloat(); // big=left, small=right
58
+ float y = ((float) fieldHeight) * 0.5f;
59
+ return new PVector(x, y);
60
+ };
61
+ }
62
+
63
+ public static WordPlacer swirl() {
64
+ return new SwirlWordPlacer();
65
+ }
66
+
67
+ public static WordPlacer upperLeft() {
68
+ return new UpperLeftWordPlacer();
69
+ }
70
+
71
+ public static WordPlacer wave() {
72
+ return new WaveWordPlacer();
73
+ }
74
+ }
@@ -0,0 +1,38 @@
1
+ package wordcram;
2
+
3
+ import processing.core.PApplet;
4
+ import processing.core.PVector;
5
+
6
+ /**
7
+ * If you're using a custom WordNudger, and having difficulty seeing
8
+ * how well it works, try wrapping it in a PlottingWordNudger. As your
9
+ * WordCram is drawn, it'll render tiny dots at each location it
10
+ * nudges your words to, so you can see how well it's working.
11
+ */
12
+ public class PlottingWordNudger implements WordNudger {
13
+
14
+ private final PApplet parent;
15
+ private final WordNudger wrappedNudger;
16
+
17
+ public PlottingWordNudger(PApplet _parent, WordNudger _wrappedNudger) {
18
+ parent = _parent;
19
+ wrappedNudger = _wrappedNudger;
20
+ }
21
+
22
+ @Override
23
+ public PVector nudgeFor(Word word, int attempt) {
24
+ PVector v = wrappedNudger.nudgeFor(word, attempt);
25
+ parent.pushStyle();
26
+ parent.noStroke();
27
+
28
+ float alpha = attempt/700f;
29
+ //alpha = (float) Math.pow(alpha, 3);
30
+ parent.fill(40, 255, 255); //, alpha * 255);
31
+
32
+ PVector wordLoc = PVector.add(v, word.getTargetPlace());
33
+ parent.ellipse(wordLoc.x, wordLoc.y, 3, 3);
34
+ parent.popStyle();
35
+ return v;
36
+ }
37
+
38
+ }
@@ -0,0 +1,36 @@
1
+ package wordcram;
2
+
3
+ import processing.core.PApplet;
4
+ import processing.core.PVector;
5
+
6
+ /**
7
+ * If you're using a custom WordPlacer, and having difficulty seeing
8
+ * how well it works, try wrapping it in a PlottingWordPlacer. As your
9
+ * WordCram is drawn, it'll render tiny dots at each word's target
10
+ * location, so you can sort-of see how far off they are when they're
11
+ * finally rendered.
12
+ */
13
+ public class PlottingWordPlacer implements WordPlacer {
14
+
15
+ private final PApplet parent;
16
+ private final WordPlacer wrappedPlacer;
17
+
18
+ public PlottingWordPlacer(PApplet _parent, WordPlacer _wrappedPlacer) {
19
+ parent = _parent;
20
+ wrappedPlacer = _wrappedPlacer;
21
+ }
22
+
23
+ @Override
24
+ public PVector place(Word word, int wordIndex, int wordsCount, int wordImageWidth, int wordImageHeight, int fieldWidth, int fieldHeight) {
25
+ PVector v = wrappedPlacer.place(word, wordIndex, wordsCount, wordImageWidth, wordImageHeight, fieldWidth, fieldHeight);
26
+ parent.pushStyle();
27
+ parent.noFill();
28
+
29
+ parent.stroke(15, 255, 255, 200);
30
+
31
+ parent.ellipse(v.x, v.y, 10, 10);
32
+ parent.popStyle();
33
+ return v;
34
+ }
35
+
36
+ }
@@ -0,0 +1,42 @@
1
+ package wordcram;
2
+
3
+ import java.awt.Color; // awt: for fill color
4
+ import java.awt.Graphics2D; // awt: draws the word to the screen
5
+ import java.awt.RenderingHints; // awt: for constants while rendering a word
6
+ import java.awt.geom.GeneralPath; // awt: Shape -> Path, fill(path)
7
+
8
+ import processing.core.PGraphics;
9
+ import processing.awt.PGraphicsJava2D;
10
+
11
+ class ProcessingWordRenderer implements WordRenderer {
12
+ PGraphics destination;
13
+
14
+ ProcessingWordRenderer(PGraphics destination) {
15
+ this.destination = destination;
16
+ }
17
+
18
+ @Override
19
+ public int getWidth() {
20
+ return destination.width;
21
+ }
22
+
23
+ @Override
24
+ public int getHeight() {
25
+ return destination.height;
26
+ }
27
+
28
+ @Override
29
+ public void drawWord(EngineWord word, Color color) {
30
+ GeneralPath path2d = new GeneralPath(word.getShape());
31
+
32
+ // Graphics2D g2 = (Graphics2D)destination.image.getGraphics();
33
+ Graphics2D g2 = ((PGraphicsJava2D)destination).g2;
34
+
35
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
36
+ g2.setPaint(color);
37
+ g2.fill(path2d);
38
+ }
39
+
40
+ @Override
41
+ public void finish() {}
42
+ }
@@ -0,0 +1,44 @@
1
+ package wordcram;
2
+
3
+ import java.util.Random;
4
+
5
+ import processing.core.PVector;
6
+
7
+ /**
8
+ * A RandomWordNudger, where each attempt's PVector has X & Y coords
9
+ * distributed randomly around the desired point, multiplied by a standard deviation,
10
+ * and multiplied by the attempt number (so it gets farther, as it gets more
11
+ * desperate).
12
+ *
13
+ * @author Dan Bernier
14
+ */
15
+ public class RandomWordNudger implements WordNudger {
16
+
17
+ private final Random r = new Random();
18
+ private float stdDev;
19
+
20
+ /**
21
+ * Create a RandomWordNudger with a standard deviation of 0.6.
22
+ */
23
+ public RandomWordNudger() {
24
+ this(0.6f);
25
+ }
26
+
27
+ /**
28
+ * Create a RandomWordNudger with your own standard deviation.
29
+ * @param stdDev
30
+ */
31
+ public RandomWordNudger(float stdDev) {
32
+ this.stdDev = stdDev;
33
+ }
34
+
35
+ @Override
36
+ public PVector nudgeFor(Word w, int attempt) {
37
+ return new PVector(next(attempt), next(attempt));
38
+ }
39
+
40
+ private float next(int attempt) {
41
+ return (float)r.nextGaussian() * attempt * stdDev;
42
+ }
43
+
44
+ }
@@ -0,0 +1,10 @@
1
+ package wordcram;
2
+
3
+ class RenderOptions {
4
+ int maxAttemptsToPlaceWord = -1; // default: based on Word weight
5
+ int maxNumberOfWordsToDraw = -1; // default: unlimited
6
+ int minShapeSize = 7;
7
+ int wordPadding = 1;
8
+
9
+ boolean rightToLeft = false;
10
+ }
@@ -0,0 +1,66 @@
1
+ package wordcram;
2
+
3
+ import java.awt.Shape; // awt: passed as arg, turned into Area
4
+ import java.awt.geom.Area; // awt: from Shape, getBounds2D(), contains(box)
5
+ import java.awt.geom.Rectangle2D; // awt: from Area, getMinX() and Y(), getMaxX() and Y()
6
+ import java.util.Random;
7
+ import processing.core.PVector;
8
+
9
+ public class ShapeBasedPlacer implements WordPlacer, WordNudger {
10
+
11
+ Area area;
12
+ float minX;
13
+ float minY;
14
+ float maxX;
15
+ float maxY;
16
+ Random random;
17
+
18
+ public ShapeBasedPlacer(Shape shape) {
19
+ this.area = new Area(shape);
20
+ random = new Random();
21
+ Rectangle2D areaBounds = area.getBounds2D();
22
+ this.minX = (float) areaBounds.getMinX();
23
+ this.minY = (float) areaBounds.getMinY();
24
+ this.maxX = (float) areaBounds.getMaxX();
25
+ this.maxY = (float) areaBounds.getMaxY();
26
+ }
27
+
28
+ @Override
29
+ public PVector place(Word w, int rank, int count, int ww, int wh, int fw,
30
+ int fh) {
31
+
32
+ for (int i = 0; i < 1000; i++) {
33
+ float newX = randomBetween(minX, maxX);
34
+ float newY = randomBetween(minY, maxY);
35
+ if (area.contains(newX, newY, ww, wh)) {
36
+ return new PVector(newX, newY);
37
+ }
38
+ }
39
+
40
+ return new PVector(-1, -1);
41
+ }
42
+
43
+ @Override
44
+ public PVector nudgeFor(Word word, int attempt) {
45
+ PVector target = word.getTargetPlace();
46
+ float wx = target.x;
47
+ float wy = target.y;
48
+ float ww = word.getRenderedWidth();
49
+ float wh = word.getRenderedHeight();
50
+
51
+ for (int i = 0; i < 1000; i++) {
52
+ float newX = randomBetween(minX, maxX);
53
+ float newY = randomBetween(minY, maxY);
54
+
55
+ if (area.contains(newX, newY, ww, wh)) {
56
+ return new PVector(newX - wx, newY - wy);
57
+ }
58
+ }
59
+
60
+ return new PVector(-1, -1);
61
+ }
62
+
63
+ float randomBetween(float a, float b) {
64
+ return a + random.nextFloat() * (b - a);
65
+ }
66
+ }