| 78 | 78 | ] |
| 79 | 79 | |
| 80 | def javaVersionFull = new File( "java.version" ).text | |
| 81 | def (javaVersion, javaUpdate) = javaVersionFull.tokenize( '+' ) | |
| 82 | ||
| 80 | 83 | java { |
| 81 | sourceCompatibility = 22 | |
| 82 | targetCompatibility = 22 | |
| 84 | sourceCompatibility = javaVersion | |
| 85 | targetCompatibility = javaVersion | |
| 83 | 86 | } |
| 84 | 87 | |
| 85 | 88 | javafx { |
| 86 | version = '21' | |
| 89 | version = javaVersion | |
| 87 | 90 | modules = ['javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.swing'] |
| 88 | 91 | configuration = 'compileOnly' |
| ... | ||
| 265 | 268 | tasks.withType( JavaCompile ).configureEach { |
| 266 | 269 | options.encoding = 'UTF-8' |
| 267 | options.compilerArgs += '--enable-preview' | |
| 268 | 270 | } |
| 269 | 271 | |
| 21 | 21 | readonly OPT_JAVA=$(cat << END_OF_ARGS |
| 22 | 22 | -Dprism.order=sw \ |
| 23 | --enable-preview \ | |
| 24 | 23 | --add-opens=javafx.controls/javafx.scene.control=ALL-UNNAMED \ |
| 25 | 24 | --add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED \ |
| ... | ||
| 36 | 35 | END_OF_ARGS |
| 37 | 36 | ) |
| 37 | ||
| 38 | readonly JAVA_VERSION=$(cat java.version) | |
| 38 | 39 | |
| 39 | 40 | ARG_JAVA_OS="linux" |
| 40 | 41 | ARG_JAVA_ARCH="amd64" |
| 41 | ARG_JAVA_VERSION="21.0.2" | |
| 42 | ARG_JAVA_UPDATE="14" | |
| 42 | ARG_JAVA_VERSION=${JAVA_VERSION%+*} | |
| 43 | ARG_JAVA_UPDATE=${JAVA_VERSION#*+} | |
| 44 | ||
| 43 | 45 | ARG_JAVA_DIR="java" |
| 44 | 46 | |
| 1 | 23+38 | |
| 1 | 2 |
| 504 | 504 | public void newTextEditor() { |
| 505 | 505 | final String key = "file.default.document."; |
| 506 | final String prefix = Constants.get( STR."\{key}prefix" ); | |
| 507 | final String suffix = Constants.get( STR."\{key}suffix" ); | |
| 506 | final String prefix = Constants.get( String.format( "%s%s", key, "prefix" ) ); | |
| 507 | final String suffix = Constants.get( String.format( "%s%s", key, "suffix" ) ); | |
| 508 | 508 | |
| 509 | File file = new File( STR."\{prefix}.\{suffix}" ); | |
| 509 | File file = new File( String.format( "%s.%s", prefix, suffix ) ); | |
| 510 | 510 | int i = 0; |
| 511 | 511 | |
| 512 | 512 | while( file.exists() && i++ < 100 ) { |
| 513 | file = new File( STR."\{prefix}-\{i}.\{suffix}" ); | |
| 513 | file = new File( String.format( "%s-%s.%s", prefix, i, suffix ) ); | |
| 514 | 514 | } |
| 515 | 515 |
| 347 | 347 | |
| 348 | 348 | final var jsonNode = node.getValue(); |
| 349 | final var keyName = STR."\{parent}.\{node.getKey()}"; | |
| 349 | final var keyName = String.format( "%s.%s", parent, node.getKey() ); | |
| 350 | 350 | |
| 351 | 351 | if( jsonNode.isValueNode() ) { |
| 11 | 11 | import java.util.concurrent.ConcurrentHashMap; |
| 12 | 12 | |
| 13 | import static java.lang.String.format; | |
| 13 | 14 | import static java.util.regex.Matcher.quoteReplacement; |
| 14 | 15 | |
| ... | ||
| 96 | 97 | if( mapValue.contains( mOperator.apply( keyName ) ) ) { |
| 97 | 98 | throw new IllegalStateException( |
| 98 | STR."Mapped value '\{mapValue}' may not contain its key name '\{keyName}'" ); | |
| 99 | format( | |
| 100 | "Mapped value '%s' may not contain its key name '%s'", | |
| 101 | mapValue, | |
| 102 | keyName | |
| 103 | ) | |
| 104 | ); | |
| 99 | 105 | } |
| 100 | 106 | |
| 17 | 17 | import static com.keenwrite.events.StatusEvent.clue; |
| 18 | 18 | import static com.keenwrite.util.FileWalker.walk; |
| 19 | import static java.lang.String.format; | |
| 19 | 20 | import static java.lang.System.lineSeparator; |
| 20 | 21 | import static java.nio.charset.StandardCharsets.UTF_8; |
| ... | ||
| 56 | 57 | |
| 57 | 58 | public String call() throws IOException { |
| 58 | final var glob = STR."**/*.\{mExtension}"; | |
| 59 | final var glob = format( "**/*.%s", mExtension ); | |
| 59 | 60 | final var files = new ArrayList<Path>(); |
| 60 | 61 | final var text = new StringBuilder( DOCUMENT_LENGTH ); |
| 271 | 271 | */ |
| 272 | 272 | private static File getFile( final String suffix ) { |
| 273 | return new File( get( STR."file.default.\{suffix}" ) ); | |
| 273 | return new File( get( String.format( "file.default.%s", suffix ) ) ); | |
| 274 | 274 | } |
| 275 | 275 |
| 231 | 231 | private Button createButton( |
| 232 | 232 | final String msgKey, final EventHandler<ActionEvent> eventHandler ) { |
| 233 | final var keyPrefix = STR."\{Constants.ACTION_PREFIX}definition.\{msgKey}"; | |
| 234 | final var button = new Button( get( STR."\{keyPrefix}.text" ) ); | |
| 235 | final var graphic = createGraphic( get( STR."\{keyPrefix}.icon" ) ); | |
| 233 | final var keyPrefix = Constants.ACTION_PREFIX + "definition." + msgKey; | |
| 234 | final var button = new Button( get( keyPrefix + ".text" ) ); | |
| 235 | final var graphic = createGraphic( get( keyPrefix + ".icon" ) ); | |
| 236 | 236 | |
| 237 | 237 | button.setOnAction( eventHandler ); |
| 238 | 238 | button.setGraphic( graphic ); |
| 239 | button.setTooltip( new Tooltip( get( STR."\{keyPrefix}.tooltip" ) ) ); | |
| 239 | button.setTooltip( new Tooltip( get( keyPrefix + ".tooltip" ) ) ); | |
| 240 | 240 | |
| 241 | 241 | return button; |
| ... | ||
| 429 | 429 | final var items = menu.getItems(); |
| 430 | 430 | |
| 431 | addMenuItem( items, STR."\{ACTION_PREFIX}definition.create.text" ) | |
| 431 | addMenuItem( items, ACTION_PREFIX + "definition.create.text" ) | |
| 432 | 432 | .setOnAction( _ -> createDefinition() ); |
| 433 | addMenuItem( items, STR."\{ACTION_PREFIX}definition.rename.text" ) | |
| 433 | addMenuItem( items, ACTION_PREFIX + "definition.rename.text" ) | |
| 434 | 434 | .setOnAction( _ -> renameDefinition() ); |
| 435 | addMenuItem( items, STR."\{ACTION_PREFIX}definition.delete.text" ) | |
| 435 | addMenuItem( items, ACTION_PREFIX + "definition.delete.text" ) | |
| 436 | 436 | .setOnAction( _ -> deleteSelectedItem() ); |
| 437 | addMenuItem( items, STR."\{ACTION_PREFIX}definition.insert.text" ) | |
| 437 | addMenuItem( items, ACTION_PREFIX + "definition.insert.text" ) | |
| 438 | 438 | .setOnAction( _ -> insertSelectedItem() ); |
| 439 | 439 | |
| 374 | 374 | |
| 375 | 375 | private Node label( final Key key, final String... values ) { |
| 376 | return new Label( get( STR."\{key.toString()}.desc", (Object[]) values ) ); | |
| 376 | return new Label( get( String.format( "%s%s", key.toString(), ".desc" ), (Object[]) values ) ); | |
| 377 | 377 | } |
| 378 | 378 | |
| 379 | 379 | private String title( final Key key ) { |
| 380 | return get( STR."\{key.toString()}.title" ); | |
| 380 | return get( String.format( "%s%s", key.toString(), ".title" ) ); | |
| 381 | 381 | } |
| 382 | 382 |
| 33 | 33 | @Override |
| 34 | 34 | public String apply( final String t ) { |
| 35 | return STR."<pre>\{t}</pre>"; | |
| 35 | return String.format( "<pre>%s</pre>", t ); | |
| 36 | 36 | } |
| 37 | 37 | } |
| 14 | 14 | import java.util.regex.Pattern; |
| 15 | 15 | |
| 16 | import static java.lang.String.format; | |
| 16 | 17 | import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS; |
| 17 | 18 | import static java.util.regex.Pattern.compile; |
| ... | ||
| 61 | 62 | // When no regular CSS definition (id or class), use key/value pairs. |
| 62 | 63 | if( cssDef == null ) { |
| 63 | cssAttrKey = STR."data-\{pairMatcher.group( "k" )}"; | |
| 64 | cssAttrKey = format( "data-%s", pairMatcher.group( "k" ) ); | |
| 64 | 65 | cssAttrVal = pairMatcher.group( "v" ); |
| 65 | 66 | } |
| 9 | 9 | import org.jetbrains.annotations.NotNull; |
| 10 | 10 | |
| 11 | import static java.lang.String.format; | |
| 12 | ||
| 11 | 13 | /** |
| 12 | 14 | * Responsible for writing HTML anchor cross-references in the form |
| ... | ||
| 22 | 24 | AnchorXrefNode( final String type, final String id ) { |
| 23 | 25 | mTypeName = type; |
| 24 | mIdName = STR. "#\{ id }" ; | |
| 26 | mIdName = format( "#%s", id ); | |
| 25 | 27 | } |
| 26 | 28 | |
| 9 | 9 | import java.util.regex.Pattern; |
| 10 | 10 | |
| 11 | import static java.lang.String.format; | |
| 12 | ||
| 11 | 13 | class BasedSequenceNameParser extends BasedSequenceParser { |
| 12 | private static final String REGEX = STR. "#\{ REGEX_INNER }" ; | |
| 14 | private static final String REGEX = format( "#%s", REGEX_INNER ); | |
| 13 | 15 | private static final Pattern PATTERN = asPattern( REGEX ); |
| 14 | 16 |
| 11 | 11 | |
| 12 | 12 | import static com.keenwrite.processors.markdown.extensions.common.EmptyNode.EMPTY_NODE; |
| 13 | import static java.lang.String.format; | |
| 13 | 14 | |
| 14 | 15 | class BasedSequenceXrefParser extends BasedSequenceParser { |
| 15 | private static final String REGEX = STR. "\\[@\{ REGEX_INNER }]" ; | |
| 16 | private static final String REGEX = format( "\\[@%s]", REGEX_INNER ); | |
| 16 | 17 | private static final Pattern PATTERN = asPattern( REGEX ); |
| 17 | 18 |
| 7 | 7 | import com.vladsch.flexmark.html.HtmlWriter; |
| 8 | 8 | |
| 9 | import static java.lang.String.format; | |
| 10 | ||
| 9 | 11 | /** |
| 10 | 12 | * Responsible for generating anchor links, either named or cross-referenced. |
| ... | ||
| 27 | 29 | final var attr = getRefAttrName(); |
| 28 | 30 | |
| 29 | final var clazz = STR. "class=\"\{ attr }\"" ; | |
| 30 | final var dataType = STR. "data-type=\"\{ type }\"" ; | |
| 31 | final var refId = STR. "\{ attr }=\"\{ id }\"" ; | |
| 31 | final var clazz = format( "class=\"%s\"", attr ); | |
| 32 | final var dataType = format( "data-type=\"%s\"", type ); | |
| 33 | final var refId = format( "%s=\"%s\"", attr, id ); | |
| 32 | 34 | |
| 33 | html.raw( STR. "<a \{ clazz } \{ dataType } \{ refId } />" ); | |
| 35 | html.raw( format( "<a %s %s %s />", clazz, dataType, refId ) ); | |
| 34 | 36 | } |
| 35 | 37 | } |
| 133 | 133 | |
| 134 | 134 | private static void status( final String s, final long count ) { |
| 135 | clue( STR."Main.status.lexicon.\{s}", count ); | |
| 135 | clue( format( "Main.status.lexicon.%s", s ), count ); | |
| 136 | 136 | } |
| 137 | 137 | } |
| 33 | 33 | |
| 34 | 34 | private static final String TYPESETTER_VERSION = |
| 35 | STR."\{TYPESETTER_EXE} --version > /dev/null"; | |
| 35 | String.format( "%s%s", TYPESETTER_EXE, " --version > /dev/null" ); | |
| 36 | 36 | |
| 37 | 37 | public GuestTypesetter( final Mutator mutator ) { |
| ... | ||
| 100 | 100 | manager.run( |
| 101 | 101 | input -> gobble( input, s -> exitCode.append( s.trim() ) ), |
| 102 | STR."\{TYPESETTER_VERSION}; echo $?" | |
| 102 | String.format( "%s%s", TYPESETTER_VERSION, "; echo $?" ) | |
| 103 | 103 | ); |
| 104 | 104 | |
| 19 | 19 | import static com.keenwrite.events.StatusEvent.clue; |
| 20 | 20 | import static com.keenwrite.util.Time.toElapsedTime; |
| 21 | import static java.lang.String.*; | |
| 21 | 22 | import static java.lang.String.format; |
| 22 | 23 | import static java.lang.System.currentTimeMillis; |
| ... | ||
| 165 | 166 | final var prefix = "Main.status.typeset."; |
| 166 | 167 | |
| 167 | clue( STR."\{prefix}began", outputPath ); | |
| 168 | clue( format( "%s%s", prefix, "began" ), outputPath ); | |
| 168 | 169 | |
| 169 | 170 | final var time = currentTimeMillis(); |
| 170 | 171 | final var success = typesetter.call(); |
| 171 | 172 | final var suffix = success ? "success" : "failure"; |
| 172 | 173 | |
| 173 | clue( STR."\{prefix}ended.\{suffix}", outputPath, since( time ) ); | |
| 174 | clue( format( "%sended.%s", prefix, suffix ), outputPath, since( time ) ); | |
| 174 | 175 | } |
| 175 | 176 | |
| ... | ||
| 188 | 189 | |
| 189 | 190 | args.add( |
| 190 | format( "--arguments=themesdir=%s,imagesdir=%s,cachesdir=%s", | |
| 191 | themesPath, imagesPath, cachesPath ) | |
| 191 | format( | |
| 192 | "--arguments=themesdir=%s,imagesdir=%s,cachesdir=%s", | |
| 193 | themesPath, imagesPath, cachesPath | |
| 194 | ) | |
| 192 | 195 | ); |
| 193 | 196 | args.add( format( "--path='%s'", themesPath ) ); |
| 22 | 22 | import static com.keenwrite.io.downloads.DownloadManager.downloadAsync; |
| 23 | 23 | import static com.keenwrite.io.downloads.DownloadManager.toFilename; |
| 24 | import static java.lang.String.*; | |
| 24 | 25 | |
| 25 | 26 | /** |
| ... | ||
| 35 | 36 | |
| 36 | 37 | public AbstractDownloadPane() { |
| 37 | mUri = getUri( STR."\{getPrefix()}.download.link.url" ); | |
| 38 | mUri = getUri( format( "%s%s", getPrefix(), ".download.link.url" ) ); | |
| 38 | 39 | mFilename = toFilename( mUri ); |
| 39 | 40 | final var directory = USER_DATA_DIR; |
| 40 | 41 | mTarget = toFile( directory.resolve( mFilename ) ); |
| 41 | final var source = labelf( STR."\{getPrefix()}.paths", mFilename, directory ); | |
| 42 | mStatus = labelf( STR."\{getPrefix()}\{STATUS}.progress", 0, 0 ); | |
| 42 | final var source = labelf( | |
| 43 | format( "%s%s", getPrefix(), ".paths" ), mFilename, directory | |
| 44 | ); | |
| 45 | mStatus = labelf( format( "%s%s.progress", getPrefix(), STATUS ), 0, 0 ); | |
| 43 | 46 | |
| 44 | 47 | final var border = new BorderPane(); |
| ... | ||
| 73 | 76 | final var suffix = checksumOk ? ".ok" : ".no"; |
| 74 | 77 | |
| 75 | updateStatus( STR."\{STATUS}.checksum\{suffix}", mFilename ); | |
| 78 | updateStatus( format( "%s.checksum%s", STATUS, suffix ), mFilename ); | |
| 76 | 79 | disableNext( !checksumOk ); |
| 77 | 80 | } |
| ... | ||
| 99 | 102 | @Override |
| 100 | 103 | protected String getHeaderKey() { |
| 101 | return STR."\{getPrefix()}.header"; | |
| 104 | return format( "%s%s", getPrefix(), ".header" ); | |
| 102 | 105 | } |
| 103 | 106 | |
| ... | ||
| 112 | 115 | protected void onDownloadSucceeded( |
| 113 | 116 | final String threadName, final ObservableMap<Object, Object> properties ) { |
| 114 | updateStatus( STR."\{STATUS}.success" ); | |
| 117 | updateStatus( format( "%s%s", STATUS, ".success" ) ); | |
| 115 | 118 | properties.remove( threadName ); |
| 116 | 119 | disableNext( false ); |
| 117 | 120 | } |
| 118 | 121 | |
| 119 | 122 | protected void onDownloadFailed( |
| 120 | 123 | final String threadName, final ObservableMap<Object, Object> properties ) { |
| 121 | updateStatus( STR."\{STATUS}.failure" ); | |
| 124 | updateStatus( format( "%s%s", STATUS, ".failure" ) ); | |
| 122 | 125 | properties.remove( threadName ); |
| 123 | 126 | } |
| 216 | 216 | |
| 217 | 217 | static Hyperlink hyperlink( final String prefix ) { |
| 218 | final var label = get( STR."\{prefix}.lbl" ); | |
| 219 | final var url = get( STR."\{prefix}.url" ); | |
| 218 | final var label = get( String.format( "%s%s", prefix, ".lbl" ) ); | |
| 219 | final var url = get( String.format( "%s%s", prefix, ".url" ) ); | |
| 220 | 220 | final var link = new Hyperlink( label ); |
| 221 | 221 |
| 87 | 87 | final var node = super.createButtonBar(); |
| 88 | 88 | final var layout = new BorderPane(); |
| 89 | final var copyButton = button( STR."\{PREFIX}.copy.began" ); | |
| 89 | final var copyButton = button( format( "%s%s", PREFIX, ".copy.began" ) ); | |
| 90 | 90 | |
| 91 | 91 | // Change the label to indicate clipboard is updated. |
| 92 | 92 | copyButton.setOnAction( _ -> { |
| 93 | 93 | SystemClipboard.write( mCommands.getText() ); |
| 94 | copyButton.setText( get( STR."\{PREFIX}.copy.ended" ) ); | |
| 94 | copyButton.setText( get( format( "%s%s", PREFIX, ".copy.ended" ) ) ); | |
| 95 | 95 | } ); |
| 96 | 96 | |
| ... | ||
| 108 | 108 | @Override |
| 109 | 109 | protected String getHeaderKey() { |
| 110 | return STR."\{PREFIX}.header"; | |
| 110 | return format( "%s%s", PREFIX, ".header" ); | |
| 111 | 111 | } |
| 112 | 112 | |
| ... | ||
| 134 | 134 | final var comboBox = new ComboBox<UnixOsCommand>(); |
| 135 | 135 | final var items = comboBox.getItems(); |
| 136 | final var prefix = STR."\{PREFIX}.command"; | |
| 137 | final var distros = getInt( STR."\{prefix}.distros", 14 ); | |
| 136 | final var prefix = format( "%s%s", PREFIX, ".command" ); | |
| 137 | final var distros = getInt( format( "%s%s", prefix, ".distros" ), 14 ); | |
| 138 | 138 | |
| 139 | 139 | for( int i = 1; i <= distros; i++ ) { |
| 140 | 140 | final var suffix = format( ".%02d", i ); |
| 141 | final var name = get( STR."\{prefix}.os.name\{suffix}" ); | |
| 142 | final var command = get( STR."\{prefix}.os.text\{suffix}" ); | |
| 141 | final var name = get( format( "%s.os.name%s", prefix, suffix ) ); | |
| 142 | final var command = get( format( "%s.os.text%s", prefix, suffix ) ); | |
| 143 | 143 | |
| 144 | 144 | items.add( new UnixOsCommand( name, command ) ); |
| 41 | 41 | |
| 42 | 42 | final var titledPane = titledPane( "Output", mCommands ); |
| 43 | append( mCommands, get( STR."\{PREFIX}.status.running" ) ); | |
| 43 | append( mCommands, get( String.format( "%s%s", PREFIX, ".status.running" ) ) ); | |
| 44 | 44 | |
| 45 | 45 | final var stepsPane = new VBox(); |
| 46 | 46 | final var steps = stepsPane.getChildren(); |
| 47 | steps.add( label( STR."\{PREFIX}.step.0" ) ); | |
| 47 | steps.add( label( String.format( "%s%s", PREFIX, ".step.0" ) ) ); | |
| 48 | 48 | steps.add( spacer() ); |
| 49 | steps.add( label( STR."\{PREFIX}.step.1" ) ); | |
| 50 | steps.add( label( STR."\{PREFIX}.step.2" ) ); | |
| 51 | steps.add( label( STR."\{PREFIX}.step.3" ) ); | |
| 49 | steps.add( label( String.format( "%s%s", PREFIX, ".step.1" ) ) ); | |
| 50 | steps.add( label( String.format( "%s%s", PREFIX, ".step.2" ) ) ); | |
| 51 | steps.add( label( String.format( "%s%s", PREFIX, ".step.3" ) ) ); | |
| 52 | 52 | steps.add( spacer() ); |
| 53 | 53 | steps.add( titledPane ); |
| ... | ||
| 72 | 72 | |
| 73 | 73 | final var binary = properties.get( WIN_BIN ); |
| 74 | final var key = STR."\{PREFIX}.status"; | |
| 74 | final var key = String.format( "%s%s", PREFIX, ".status" ); | |
| 75 | 75 | |
| 76 | 76 | if( binary instanceof File exe ) { |
| 77 | 77 | final var task = createTask( () -> { |
| 78 | 78 | final var exit = mContainer.install( exe ); |
| 79 | 79 | |
| 80 | 80 | // Remove the installer after installation is finished. |
| 81 | 81 | properties.remove( thread ); |
| 82 | 82 | |
| 83 | 83 | final var msg = exit == 0 |
| 84 | ? get( STR."\{key}.success" ) | |
| 85 | : get( STR."\{key}.failure", exit ); | |
| 84 | ? get( String.format( "%s%s", key, ".success" ) ) | |
| 85 | : get( String.format( "%s%s", key, ".failure" ), exit ); | |
| 86 | 86 | |
| 87 | 87 | append( mCommands, msg ); |
| ... | ||
| 96 | 96 | } |
| 97 | 97 | else { |
| 98 | append( mCommands, get( STR."\{PREFIX}.unknown", binary ) ); | |
| 98 | append( mCommands, get( String.format( "%s%s", PREFIX, ".unknown" ), binary ) ); | |
| 99 | 99 | } |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | @Override |
| 103 | 103 | public String getHeaderKey() { |
| 104 | return STR."\{PREFIX}.header"; | |
| 104 | return String.format( "%s%s", PREFIX, ".header" ); | |
| 105 | 105 | } |
| 106 | 106 | } |
| 48 | 48 | */ |
| 49 | 49 | public Builder setId( final String id ) { |
| 50 | final var prefix = STR."\{ACTION_PREFIX}\{id}."; | |
| 51 | final var text = STR."\{prefix}text"; | |
| 52 | final var icon = STR."\{prefix}icon"; | |
| 53 | final var accelerator = STR."\{prefix}accelerator"; | |
| 50 | final var prefix = String.format( "%s%s.", ACTION_PREFIX, id ); | |
| 51 | final var text = String.format( "%s%s", prefix, "text" ); | |
| 52 | final var icon = String.format( "%s%s", prefix, "icon" ); | |
| 53 | final var accelerator = String.format( "%s%s", prefix, "accelerator" ); | |
| 54 | 54 | final var builder = setText( text ).setIcon( icon ); |
| 55 | 55 | |
| ... | ||
| 172 | 172 | |
| 173 | 173 | if( mAccelerator != null ) { |
| 174 | tooltip += STR." (\{mAccelerator.getDisplayText()}\{')'}"; | |
| 174 | tooltip += String.format( " (%s)", mAccelerator.getDisplayText() ); | |
| 175 | 175 | } |
| 176 | 176 | |
| 604 | 604 | final var alert = new Alert( INFORMATION ); |
| 605 | 605 | final var prefix = "Dialog.about."; |
| 606 | alert.setTitle( get( STR."\{prefix}title", APP_TITLE ) ); | |
| 607 | alert.setHeaderText( get( STR."\{prefix}header", APP_TITLE ) ); | |
| 608 | alert.setContentText( get( STR."\{prefix}content", | |
| 606 | alert.setTitle( get( String.format( "%s%s", prefix, "title" ), APP_TITLE ) ); | |
| 607 | alert.setHeaderText( get( String.format( "%s%s", prefix, "header" ), APP_TITLE ) ); | |
| 608 | alert.setContentText( get( String.format( "%s%s", prefix, "content" ), | |
| 609 | 609 | APP_YEAR, |
| 610 | 610 | APP_VERSION ) ); |
| 326 | 326 | |
| 327 | 327 | private Label createLabel( final String key ) { |
| 328 | final var label = new Label( STR."\{get( key )}:" ); | |
| 328 | final var label = new Label( String.format( "%s%s", get( key ), ":" ) ); | |
| 329 | 329 | final var font = label.getFont(); |
| 330 | 330 | final var upscale = new Font( font.getName(), 14 ); |
| 26 | 26 | */ |
| 27 | 27 | public HyperlinkDialog( final Window owner, final HyperlinkModel model ) { |
| 28 | super( owner, STR."\{PREFIX}title" ); | |
| 28 | super( owner, String.format( "%s%s", PREFIX, "title" ) ); | |
| 29 | 29 | |
| 30 | 30 | mModel = model; |
| ... | ||
| 37 | 37 | addInputField( |
| 38 | 38 | "text", |
| 39 | STR."\{PREFIX}label.text", STR."\{PREFIX}prompt.text", | |
| 39 | String.format( "%s%s", PREFIX, "label.text" ), String.format( "%s%s", PREFIX, "prompt.text" ), | |
| 40 | 40 | mModel.getText(), |
| 41 | 41 | ( _, _, n ) -> mModel.setText( n ) |
| 42 | 42 | ); |
| 43 | 43 | addInputField( |
| 44 | 44 | "url", |
| 45 | STR."\{PREFIX}label.url", STR."\{PREFIX}prompt.url", | |
| 45 | String.format( "%s%s", PREFIX, "label.url" ), String.format( "%s%s", PREFIX, "prompt.url" ), | |
| 46 | 46 | mModel.getUrl(), |
| 47 | 47 | ( _, _, n ) -> mModel.setUrl( n ) |
| 48 | 48 | ); |
| 49 | 49 | addInputField( |
| 50 | 50 | "title", |
| 51 | STR."\{PREFIX}label.title", STR."\{PREFIX}prompt.title", | |
| 51 | String.format( "%s%s", PREFIX, "label.title" ), String.format( "%s%s", PREFIX, "prompt.title" ), | |
| 52 | 52 | mModel.getTitle(), |
| 53 | 53 | ( _, _, n ) -> mModel.setTitle( n ) |
| 17 | 17 | |
| 18 | 18 | public ImageDialog( final Window owner, final ImageModel model ) { |
| 19 | super( owner, STR."\{PREFIX}title" ); | |
| 19 | super( owner, String.format( "%s%s", PREFIX, "title" ) ); | |
| 20 | 20 | |
| 21 | 21 | mModel = model; |
| ... | ||
| 28 | 28 | addInputField( |
| 29 | 29 | "url", |
| 30 | STR."\{PREFIX}label.url", STR."\{PREFIX}prompt.url", | |
| 30 | String.format( "%s%s", PREFIX, "label.url" ), | |
| 31 | String.format( "%s%s", PREFIX, "prompt.url" ), | |
| 31 | 32 | mModel.getUrl(), |
| 32 | 33 | ( _, _, n ) -> mModel.setUrl( n ) |
| 33 | 34 | ); |
| 34 | 35 | addInputField( |
| 35 | 36 | "text", |
| 36 | STR."\{PREFIX}label.text", STR."\{PREFIX}prompt.text", | |
| 37 | String.format( "%s%s", PREFIX, "label.text" ), | |
| 38 | String.format( "%s%s", PREFIX, "prompt.text" ), | |
| 37 | 39 | mModel.getText(), |
| 38 | 40 | ( _, _, n ) -> mModel.setText( n ) |
| 39 | 41 | ); |
| 40 | 42 | addInputField( |
| 41 | 43 | "title", |
| 42 | STR."\{PREFIX}label.title", STR."\{PREFIX}prompt.title", | |
| 44 | String.format( "%s%s", PREFIX, "label.title" ), | |
| 45 | String.format( "%s%s", PREFIX, "prompt.title" ), | |
| 43 | 46 | mModel.getTitle(), |
| 44 | 47 | ( _, _, n ) -> mModel.setTitle( n ) |
| 22 | 22 | private static final String PREFIX = "Dialog.open_url."; |
| 23 | 23 | private static final String DOWNLOAD = "Main.status.url.request."; |
| 24 | private static final String STATUS = STR."\{DOWNLOAD}status."; | |
| 24 | private static final String STATUS = String.format( | |
| 25 | "%s%s", DOWNLOAD, "status." | |
| 26 | ); | |
| 25 | 27 | |
| 26 | 28 | private final Path mParent; |
| ... | ||
| 34 | 36 | */ |
| 35 | 37 | public OpenUrlDialog( final Window owner, final Path parent ) { |
| 36 | super( owner, STR."\{PREFIX}title" ); | |
| 38 | super( owner, String.format( "%s%s", PREFIX, "title" ) ); | |
| 37 | 39 | |
| 38 | 40 | mParent = parent; |
| ... | ||
| 45 | 47 | addInputField( |
| 46 | 48 | "url", |
| 47 | STR."\{PREFIX}label.url", STR."\{PREFIX}prompt.url", | |
| 49 | String.format( "%s%s", PREFIX, "label.url" ), | |
| 50 | String.format( "%s%s", PREFIX, "prompt.url" ), | |
| 48 | 51 | mUrl, |
| 49 | 52 | ( _, _, n ) -> mUrl = sanitize( n ) |
| ... | ||
| 58 | 61 | private File download( final String reference ) { |
| 59 | 62 | try { |
| 60 | clue( STR."\{DOWNLOAD}fetch", reference ); | |
| 63 | clue( String.format( "%s%s", DOWNLOAD, "fetch" ), reference ); | |
| 61 | 64 | |
| 62 | 65 | final var uri = new URI( reference ); |
| 63 | 66 | final var path = toFile( uri ); |
| 64 | 67 | final var basedir = path.getName(); |
| 65 | 68 | final var file = mParent.resolve( basedir ).toFile(); |
| 66 | 69 | |
| 67 | 70 | if( file.exists() ) { |
| 68 | clue( STR."\{DOWNLOAD}exists", file ); | |
| 71 | clue( String.format( "%s%s", DOWNLOAD, "exists" ), file ); | |
| 69 | 72 | } |
| 70 | 73 | else { |
| 71 | 74 | final var task = downloadAsync( uri, file, ( progress, bytes ) -> { |
| 72 | 75 | final var suffix = progress < 0 ? "bytes" : "progress"; |
| 73 | 76 | |
| 74 | clue( STR."\{STATUS}\{suffix}", progress, bytes ); | |
| 77 | clue( String.format( "%s%s", STATUS, suffix ), progress, bytes ); | |
| 75 | 78 | } ); |
| 76 | 79 | |
| 77 | 80 | task.setOnSucceeded( _ -> { |
| 78 | clue( STR."\{DOWNLOAD}success", file ); | |
| 81 | clue( String.format( "%s%s", DOWNLOAD, "success" ), file ); | |
| 79 | 82 | |
| 80 | 83 | // Only after the download succeeds can we open the file. |
| 81 | 84 | FileOpenEvent.fire( file.toURI() ); |
| 82 | 85 | } ); |
| 83 | task.setOnFailed( _ -> clue( STR."\{DOWNLOAD}failure", uri ) ); | |
| 86 | task.setOnFailed( _ -> clue( | |
| 87 | String.format( "%s%s", DOWNLOAD, "failure" ), uri ) | |
| 88 | ); | |
| 84 | 89 | } |
| 85 | 90 | |
| 6 | 6 | |
| 7 | 7 | import com.vladsch.flexmark.ast.Link; |
| 8 | import org.renjin.gnur.format; | |
| 8 | 9 | |
| 9 | 10 | /** |
| ... | ||
| 55 | 56 | public String toString() { |
| 56 | 57 | final String format = hasText() |
| 57 | ? STR."[%s]\{hasTitle() ? "(%s \"%s\")" : "(%s%s)"}" | |
| 58 | ? "[%s]" + (hasTitle() ? "(%s \"%s\")" : "(%s%s)") | |
| 58 | 59 | : "%s%s%s"; |
| 59 | 60 | |
| 5 | 5 | package com.keenwrite.ui.models; |
| 6 | 6 | |
| 7 | import org.renjin.gnur.format; | |
| 8 | ||
| 7 | 9 | /** |
| 8 | 10 | * Represents the model for an image: text, url, and title. |
| ... | ||
| 28 | 30 | public String toString() { |
| 29 | 31 | final String format = hasText() |
| 30 | ? STR."![%s]\{hasTitle() ? "(%s \"%s\")" : "(%s%s)"}" | |
| 32 | ? "![%s]" + (hasTitle() ? "(%s \"%s\")" : "(%s%s)") | |
| 31 | 33 | : "%s"; |
| 32 | 34 | |
| 7 | 7 | import java.util.function.Consumer; |
| 8 | 8 | |
| 9 | import static java.lang.String.format; | |
| 9 | 10 | import static java.nio.file.FileSystems.getDefault; |
| 10 | 11 | |
| ... | ||
| 29 | 30 | final Path path, final String glob, final Consumer<Path> c ) |
| 30 | 31 | throws IOException { |
| 31 | final var matcher = getDefault().getPathMatcher( STR."glob:\{glob}" ); | |
| 32 | final var pattern = format( "glob:%s", glob ); | |
| 33 | final var matcher = getDefault().getPathMatcher( pattern ); | |
| 32 | 34 | |
| 33 | 35 | try( final var walk = Files.walk( path, 10 ) ) { |
| 21 | 21 | final var dir = pkgName.replace( '.', '/' ); |
| 22 | 22 | |
| 23 | final var urls = clazz.getClassLoader().getResources( STR."\{dir}/images" ); | |
| 23 | final var urls = clazz.getClassLoader().getResources( String.format( "%s%s", dir, "/images" ) ); | |
| 24 | 24 | assertTrue( urls.hasMoreElements() ); |
| 25 | 25 | |
| ... | ||
| 34 | 34 | final var actualExtension = valueFrom( media ).getExtension(); |
| 35 | 35 | final var expectedExtension = getExtension( image.toString() ); |
| 36 | System.out.println( STR."\{image} -> \{media}" ); | |
| 36 | System.out.println( String.format( "%s%s", image, " -> \{media}" ) ); | |
| 37 | 37 | |
| 38 | 38 | assertEquals( expectedExtension, actualExtension ); |
| 32 | 32 | private static final String URI_FILE = "kitten"; |
| 33 | 33 | private static final String URI_PATH = UIR_DIR + '/' + URI_FILE; |
| 34 | private static final String PATH_KITTEN_PNG = STR."\{URI_PATH}.png"; | |
| 35 | private static final String PATH_KITTEN_JPG = STR."\{URI_PATH}.jpg"; | |
| 34 | private static final String PATH_KITTEN_PNG = String.format( | |
| 35 | "%s%s", URI_PATH, ".png" ); | |
| 36 | private static final String PATH_KITTEN_JPG = String.format( | |
| 37 | "%s%s", URI_PATH, ".jpg" ); | |
| 36 | 38 | |
| 37 | /** Web server that doles out images. */ | |
| 39 | /** | |
| 40 | * Web server that doles out images. | |
| 41 | */ | |
| 38 | 42 | private static final String PLACEHOLDER = "loremflickr.com"; |
| 39 | 43 | |
| 40 | 44 | private static final Map<String, String> IMAGES = new LinkedHashMap<>(); |
| 41 | 45 | |
| 42 | 46 | static { |
| 43 | 47 | add( PATH_KITTEN_PNG, URI_PATH ); |
| 44 | 48 | add( PATH_KITTEN_PNG, URI_FILE ); |
| 45 | 49 | add( PATH_KITTEN_PNG, PATH_KITTEN_PNG ); |
| 46 | 50 | add( PATH_KITTEN_JPG, PATH_KITTEN_JPG ); |
| 47 | add( STR."//\{PLACEHOLDER}/200/200", STR."//\{PLACEHOLDER}/200/200" ); | |
| 48 | add( STR."ftp://\{PLACEHOLDER}/200/200", STR."ftp://\{PLACEHOLDER}/200/200" ); | |
| 49 | add( STR."http://\{PLACEHOLDER}/200/200", STR."http://\{PLACEHOLDER}/200/200" ); | |
| 50 | add( STR."https://\{PLACEHOLDER}/200/200", STR."https://\{PLACEHOLDER}/200/200" ); | |
| 51 | add( format( "//%s/200/200", PLACEHOLDER ), | |
| 52 | format( "//%s/200/200", PLACEHOLDER ) ); | |
| 53 | add( format( "ftp://%s/200/200", PLACEHOLDER ), | |
| 54 | format( "ftp://%s/200/200", PLACEHOLDER ) ); | |
| 55 | add( format( "http://%s/200/200", PLACEHOLDER ), | |
| 56 | format( "http://%s/200/200", PLACEHOLDER ) ); | |
| 57 | add( format( "https://%s/200/200", PLACEHOLDER ), | |
| 58 | format( "https://%s/200/200", PLACEHOLDER ) ); | |
| 51 | 59 | } |
| 52 | 60 |