diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb63d1240..10eea33a7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ - See [Discussions](https://github.com/gsantner/markor/discussions), [Issues](https://github.com/gsantner/markor/issues) and [Project news](https://github.com/gsantner/markor/blob/master/NEWS.md) to see what is going on. - New Updates also visible here: +### v2.13 series +- [2.13.0](https://github.com/gsantner/markor/compare/v2.12.6...v2.13.0) + ### v2.12 series - [2.12.0](https://github.com/gsantner/markor/compare/v2.11.1...v2.12.0) - [2.12.1](https://github.com/gsantner/markor/compare/v2.12.0...v2.12.1) @@ -11,6 +14,60 @@ - [2.12.5](https://github.com/gsantner/markor/compare/v2.12.4...v2.12.5) - [2.12.6](https://github.com/gsantner/markor/compare/v2.12.5...v2.12.6) +- Override .org file extension to use text mimetype (*/* unrecognized on older devices) PR#2455 +- android-35 Disable window size overlap, closes #2448 #2387 #2451 +- orgmode: add more text styling syntax and textactions (PR #2450) +- orgmode: fix action buttons not being loaded correctly (PR #2449) +- Rework /storage mapped folders (PR #2445 by @gsantner) +- FileManager: Remove top submenu to open special folders, load storage overview in filemanager instead (PR #2440 by @gsantner) +- Register chess extension (.fen) for plaintext - https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation closes #2241 (#2439) +- Open .lrc extension as plaintext by default, closes #2322 (#2438) +- TextAction: Add text case changing functionality (closes #2390, PR #2426) +- Bugfix: showAndFlash must be called on UI thread, closes #2427 (#2428) +- Improvements for HeadlineDialog scroll restoration and copy code block button (PR #2406) +- Improvements for the action buttons (closes #2386, PR #2388) +- Create launcher widget for todo (closes #1997, PR #2379) +- Disable multi-window settings option by default (PR #2420) +- Fixed checking for indices (#2421) +- Fix how multiple windows are launched (PR #2419) +- Add Em Space special key for paragraph indent (#2400) +- GitHub Actions CI configuration - upgrade upload step, fixes CI build error (PR #2416 by @gsantner) +- Updated README with dark/light todo.txt format images (PR #2411) +- Navigation and highlighting improvements (PR #2377 closes #2409 closes #2410) +- Filebrowser: Fix file modification time not reloaded, closes #2196 (PR #2385) +- Minor doc improvements +- Fix inject-head js option not applying, closes #2365, closes #2380 (PR #2383) +- Add usual yyyy-MM-dd newfile default option +- DocumentEditAndViewFragment: Fix all warnings, especially related to null pointers +- Zim: Fix link/attachment format (PR #2147 by @mehw) +- Add history scroll restoration for scroll views (#2366) +- Various bugfixes (anchor/toc jumping #2364, snippets folder #2369, wikitext newfile #2362, virtual directory browser #2350) (PR #2370 by @hardhard1) +- New Color picker, bump Android minSdk from 16 to 18, closes #1428 (PR #2203 by @halfdane) +- Latest Android SDK/Gradle fixes, by @gsantner #2360 +- Add links to changelog +- SearchReplace dialog: Use full width, closes #2367, by @gsantner +- ShareInto: Fix crash when editor is null +- Appearance improvements (PR #2359 closes #2358) +- Fix notebook directory not being created, fix NewFileDialog when no last used type, by @gsantner closes #2360 +- Project configuration: upgrade to Android SDK 35, Gradle 8.7, AGP 8.5, Build tools 35, by @gsantner, (closes #2346, closes #2305 PR #2355) +- Add ACTION_CREATE_NOTE intent filter, closes #2320, by @gsantner +- Highlight file when going back to filebrowser (PR #2351) +- View-Mode: Prism codeblock copy to clipboard button, update Mermaid and dark mode, closes #2336 closes #2335 (#2345) +- File browser: Make Folder and file icons visually better distinct (outlined icon for file), (PR by @wshoy #2331 fixes #2186) +- Jump to correct heading via id, other tweaks, bugfixes (PR #2307 by @harshad1, fixes #2312 #2313) +- FileBrowser: Disable file change options in virtual directories (closes #2287, by @gsantner) +- Format detection fixes, headline dialog improvements (PR #2300 closes #2303 closes #2296 closes #2297) +- Disallow treating openxml (msword) files as textfiles, closes #2285 +- ShareInto: Move link checkbox down +- ShareInto: Fix missing text at shared links (PR #2282 closes #2294) +- CI/CD: Update GitHub Actions versions, fixes outdated warnings, force Java from Eclipse +- Fix crash for unknown filetypes, fix EmbedBinary not detected, related to PR #2277 +- FileBrowser: Fix file copy file (nullpointer in currentfolder), by @gsantner +- Update year in texts +- Reformat code of PR #2277, closes #2225, closes #2217, closes #2199, closes #2153 +- Improvements to newfile dialog, open links, other fixes (PR #2277) + + ### v2.11 ([Details](https://github.com/gsantner/markor/blob/master/NEWS.md#markor-v211---asciidoc-csv-and-org-mode-todotxt-advanced-search-line-numbers)) - Reworked attachments (PR #2106 by @harshad1) - Editor/viewer: Side margin improvements 2, closes #2111 (PR #2119 by @guanglinn) diff --git a/app/build.gradle b/app/build.gradle index 64f4bc03f0..3d4e30e6a5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,8 +25,8 @@ android { defaultConfig { resValue "string", "manifest_package_id", "net.gsantner.markor" applicationId "net.gsantner.markor" - versionName "2.12.5" - versionCode 154 + versionName "2.13.0" + versionCode 155 multiDexEnabled true minSdkVersion rootProject.ext.version_minSdk diff --git a/app/src/main/java/net/gsantner/markor/activity/ActionButtonSettingsActivity.java b/app/src/main/java/net/gsantner/markor/activity/ActionButtonSettingsActivity.java index 16d49fdab4..a8d3e28e91 100644 --- a/app/src/main/java/net/gsantner/markor/activity/ActionButtonSettingsActivity.java +++ b/app/src/main/java/net/gsantner/markor/activity/ActionButtonSettingsActivity.java @@ -35,6 +35,7 @@ import net.gsantner.markor.format.plaintext.PlaintextActionButtons; import net.gsantner.markor.format.todotxt.TodoTxtActionButtons; import net.gsantner.markor.format.wikitext.WikitextActionButtons; +import net.gsantner.markor.format.orgmode.OrgmodeActionButtons; import net.gsantner.opoc.util.GsCollectionUtils; import java.util.ArrayList; @@ -133,6 +134,8 @@ private void extractActionData() { _textActions = new WikitextActionButtons(this, null); } else if (documentType == R.string.pref_key__asciidoc__reorder_actions) { _textActions = new AsciidocActionButtons(this, null); + } else if (documentType == R.string.pref_key__orgmode__reorder_actions) { + _textActions = new OrgmodeActionButtons(this, null); } else { // Default to Plaintext _textActions = new PlaintextActionButtons(this, null); } diff --git a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java index bb2f7b9cce..a69b4d14ba 100644 --- a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java +++ b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeActionButtons.java @@ -30,7 +30,12 @@ public List getFormatActionList() { new ActionItem(R.string.abid_common_deindent, R.drawable.ic_format_indent_decrease_black_24dp, R.string.deindent), new ActionItem(R.string.abid_common_insert_link, R.drawable.ic_link_black_24dp, R.string.insert_link), new ActionItem(R.string.abid_common_insert_image, R.drawable.ic_image_black_24dp, R.string.insert_image), - new ActionItem(R.string.abid_common_insert_audio, R.drawable.ic_keyboard_voice_black_24dp, R.string.audio) + new ActionItem(R.string.abid_common_insert_audio, R.drawable.ic_keyboard_voice_black_24dp, R.string.audio), + new ActionItem(R.string.abid_orgmode_bold, R.drawable.ic_format_bold_black_24dp, R.string.bold), + new ActionItem(R.string.abid_orgmode_italic, R.drawable.ic_format_italic_black_24dp, R.string.italic), + new ActionItem(R.string.abid_orgmode_strikeout, R.drawable.ic_format_strikethrough_black_24dp, R.string.strikeout), + new ActionItem(R.string.abid_orgmode_underline, R.drawable.ic_format_underlined_black_24dp, R.string.underline), + new ActionItem(R.string.abid_orgmode_code_inline, R.drawable.ic_code_black_24dp, R.string.inline_code) ); } @@ -45,4 +50,33 @@ protected void renumberOrderedList() { // Use markdown format for orgmode too AutoTextFormatter.renumberOrderedList(_hlEditor.getText(), MarkdownReplacePatternGenerator.formatPatterns); } + + @Override + public boolean onActionClick(final @StringRes int action) { + switch (action) { + case R.string.abid_orgmode_bold: { + runSurroundAction("*"); + return true; + } + case R.string.abid_orgmode_italic: { + runSurroundAction("/"); + return true; + } + case R.string.abid_orgmode_strikeout: { + runSurroundAction("+"); + return true; + } + case R.string.abid_orgmode_underline: { + runSurroundAction("_"); + return true; + } + case R.string.abid_orgmode_code_inline: { + runSurroundAction("="); + return true; + } + default: { + return runCommonAction(action); + } + } + } } diff --git a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeSyntaxHighlighter.java b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeSyntaxHighlighter.java index 02eaf15da4..22586b4de8 100644 --- a/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeSyntaxHighlighter.java +++ b/app/src/main/java/net/gsantner/markor/format/orgmode/OrgmodeSyntaxHighlighter.java @@ -1,6 +1,8 @@ package net.gsantner.markor.format.orgmode; +import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Typeface; import net.gsantner.markor.frontend.textview.SyntaxHighlighterBase; import net.gsantner.markor.model.AppSettings; @@ -8,7 +10,12 @@ import java.util.regex.Pattern; public class OrgmodeSyntaxHighlighter extends SyntaxHighlighterBase { - + public final static String COMMON_EMPHASIS_PATTERN = "(?<=(\\n|^|\\s|\\{|\\())([%s])(?=\\S)(.*?)\\S\\2(?=(\\n|$|\\s|\\.|,|:|;|-|\\}|\\)))"; + public final static Pattern BOLD = Pattern.compile(String.format(COMMON_EMPHASIS_PATTERN, "*")); + public final static Pattern ITALICS = Pattern.compile(String.format(COMMON_EMPHASIS_PATTERN, "/")); + public final static Pattern STRIKETHROUGH = Pattern.compile(String.format(COMMON_EMPHASIS_PATTERN, "+")); + public final static Pattern UNDERLINE = Pattern.compile(String.format(COMMON_EMPHASIS_PATTERN, "_")); + public final static Pattern CODE_INLINE = Pattern.compile(String.format(COMMON_EMPHASIS_PATTERN, "=~")); public final static Pattern HEADING = Pattern.compile("(?m)^(\\*+)\\s(.*?)(?=\\n|$)"); public final static Pattern BLOCK = Pattern.compile("(?m)(?<=#\\+BEGIN_.{1,15}$\\s)[\\s\\S]*?(?=#\\+END)"); public final static Pattern PREAMBLE = Pattern.compile("(?m)^(#\\+)(.*?)(?=\\n|$)"); @@ -44,6 +51,12 @@ protected void generateSpans() { createColorSpanForMatches(PREAMBLE, ORG_COLOR_DIM); createColorSpanForMatches(COMMENT, ORG_COLOR_DIM); createColorBackgroundSpan(BLOCK, ORG_COLOR_BLOCK); + + createStyleSpanForMatches(BOLD, Typeface.BOLD); + createStyleSpanForMatches(ITALICS, Typeface.ITALIC); + createStrikeThroughSpanForMatches(STRIKETHROUGH); + createColoredUnderlineSpanForMatches(UNDERLINE, Color.BLACK); + createMonospaceSpanForMatches(CODE_INLINE); } } diff --git a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java index 0804105255..039b4fddba 100644 --- a/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java +++ b/app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserListAdapter.java @@ -70,7 +70,7 @@ public class GsFileBrowserListAdapter extends RecyclerView.Adapter getVirtualFolders() { } for (final File file : ContextCompat.getExternalFilesDirs(_context, null)) { - final File remap = new File(VIRTUAL_STORAGE_ROOT, "appdata-public (" + file.getName() + ")"); + //noinspection DataFlowIssue + final File remap = new File(VIRTUAL_STORAGE_ROOT, "AppData (" + file.getParentFile().toString().replace("/", "-").substring(1) + ")"); map.put(remap, file); } - for (final Pair p : cu.getAppDataPublicDirs(_context, false, true, false)) { - final File remap = new File(VIRTUAL_STORAGE_ROOT, "sdcard (" + p.second + ")"); - map.put(remap, p.first); - } - map.put(VIRTUAL_STORAGE_RECENTS, VIRTUAL_STORAGE_RECENTS); map.put(VIRTUAL_STORAGE_POPULAR, VIRTUAL_STORAGE_POPULAR); map.put(VIRTUAL_STORAGE_FAVOURITE, VIRTUAL_STORAGE_FAVOURITE); - map.put(VIRTUAL_STORAGE_EMULATED, VIRTUAL_STORAGE_EMULATED); return map; } @@ -211,7 +206,7 @@ public void onBindViewHolder(@NonNull FilesystemViewerViewHolder holder, int pos if (isCurrentFolderVirtual() && "index.html".equals(filename)) { titleText += " [" + currentFolderName + "]"; } - if (currentFolderName.equals("storage") && _dopt.storageMaps.containsValue(displayFile)){ + if (currentFolderName.equals("storage") && _dopt.storageMaps.containsValue(displayFile)) { titleText = GsCollectionUtils.reverse(_dopt.storageMaps).get(displayFile).getName(); } @@ -695,11 +690,28 @@ private void loadFolder(final File folder, final File show) { // This function is not called on the main thread, so post to the UI thread private synchronized void _loadFolder(final @NonNull File folder, final @Nullable File toShow) { - final boolean folderChanged = !folder.equals(_currentFolder); - final List newData = new ArrayList<>(); + // Make sure /storage/emulated/0 is browsable, even though filesystem says it's not accessible + if (folder.equals(new File("/"))) { + newData.add(VIRTUAL_STORAGE_ROOT); + } else if (folder.equals(VIRTUAL_STORAGE_ROOT)) { + newData.add(VIRTUAL_STORAGE_EMULATED); + + // SD Card and other external storage directories that are also not listable + for (final Pair p : GsContextUtils.instance.getAppDataPublicDirs(_context, false, true, false)) { + File f = p.first; + while (f.getParentFile() != null && !f.getParentFile().getName().equals("storage")) { + f = f.getParentFile(); + } + newData.add(f); + } + } else if (folder.equals(VIRTUAL_STORAGE_EMULATED)) { + newData.add(new File(folder, "0")); + } + + if (folder.equals(VIRTUAL_STORAGE_RECENTS)) { newData.addAll(_dopt.recentFiles); } else if (folder.equals(VIRTUAL_STORAGE_POPULAR)) { @@ -715,17 +727,6 @@ private synchronized void _loadFolder(final @NonNull File folder, final @Nullabl newData.addAll(_virtualMapping.keySet()); } - // Add all emulated folders under /storage/emulated - if (VIRTUAL_STORAGE_EMULATED.equals(folder)) { - newData.add(new File(folder, "0")); - for (int i = 1; i < 10; i++) { - final File f = new File(folder, String.valueOf(i)); - if (GsFileUtils.canCreate(f)) { - newData.add(f); - } - } - } - if (folder.getAbsolutePath().equals("/")) { newData.add(new File(folder, VIRTUAL_STORAGE_ROOT.getName())); } diff --git a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java index 30ee5aa22a..87a9ebf9ab 100644 --- a/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java +++ b/app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java @@ -461,6 +461,8 @@ private static String gatherMimeType(final File file) { return "text/markdown"; } else if (ext.matches("(te?xt)|(taskpaper)")) { return "text/plain"; + } else if (ext.matches("org")) { + return "text/org"; } else if (ext.matches("webp")) { return "image/webp"; } else if (ext.matches("jpe?g")) { diff --git a/app/src/main/res/values/string-not_translatable.xml b/app/src/main/res/values/string-not_translatable.xml index 2128b6a4aa..a790a20abb 100644 --- a/app/src/main/res/values/string-not_translatable.xml +++ b/app/src/main/res/values/string-not_translatable.xml @@ -348,6 +348,13 @@ work. If not, see . abid_todotxt_due_date abid_todotxt_sort_todo + + abid_orgmode_bold + abid_orgmode_italic + abid_orgmode_strikeout + abid_orgmode_underline + abid_orgmode_code_inline + Jekyll Post Wikitext / Zim diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2de2590ac6..b544c6280d 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -41,6 +41,9 @@ @dimen/dialog_corner_radius + + + true