Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jump to correct heading via id, other tweaks, bugfixes #2307

Merged
merged 39 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
db2581e
Jump to correct heading via id
harshad1 May 25, 2024
0e1c90e
No need to track lines
harshad1 May 25, 2024
dc23d15
Clanups
harshad1 May 26, 2024
bc2d84c
As link checkbox to top bar
harshad1 May 26, 2024
ed067ff
Simplify heading, checkbox to title, task filter literal
harshad1 May 26, 2024
7f35212
Cleanups
harshad1 May 26, 2024
58df0fa
Unified and cleaned up link formatting
harshad1 May 30, 2024
4900732
new file dialog fixes, no folder in select qn / todo
harshad1 Jun 1, 2024
5c7b194
launch in new activity
harshad1 Jun 3, 2024
0188154
Improvement to launching activities
harshad1 Jun 3, 2024
e947739
Added comment on preview states
harshad1 Jun 3, 2024
ddfdbb2
Fixed + improved isFileOutOfThisFormat
harshad1 Jun 4, 2024
f0506b4
Switching from blink to ripple
harshad1 Jun 5, 2024
ec4de19
Logic to save and restore file browser position
harshad1 Jun 7, 2024
fb65503
Cleanups to code
harshad1 Jun 8, 2024
984f992
cleanups
harshad1 Jun 9, 2024
7862ce1
Small features and fixes
harshad1 Jun 14, 2024
b95d2c2
Can scroll action bar on repeat items
harshad1 Jun 16, 2024
9c6ed68
Handle unknown formats better
harshad1 Jun 19, 2024
b4857cd
Handle virtual folders better
harshad1 Jun 19, 2024
7cf1c04
Rounded dialogs, fixes for launching files
harshad1 Jun 24, 2024
f27d0ea
Changes per android studio
harshad1 Jun 25, 2024
b22a046
Improved show and flash
harshad1 Jun 30, 2024
ac9eaae
Fixes for remember ext
harshad1 Jul 2, 2024
16dc5f0
imports
harshad1 Jul 2, 2024
3650cf8
Improved keyboard showing
harshad1 Jul 2, 2024
66d6bef
Improved how we test for compatible files
harshad1 Jul 3, 2024
a9f39cc
Cleaner way to do dialog radius
harshad1 Jul 3, 2024
d0c494a
xml
harshad1 Jul 3, 2024
3c04b36
Better showing of folders
harshad1 Jul 4, 2024
64aa257
Rounded corners for all dialogs, cleaner structure
harshad1 Jul 5, 2024
3aadca4
Better text file detection
harshad1 Jul 6, 2024
d1f9313
Better text file detection
harshad1 Jul 6, 2024
cebf97f
Cleaner style system
harshad1 Jul 7, 2024
3a7f816
Matching colour
harshad1 Jul 13, 2024
bce6cb2
Match system bars with UI colors
harshad1 Jul 13, 2024
167d5e9
Rounded widget corners, hide text actions bar
harshad1 Jul 16, 2024
686ab20
Reformat code
gsantner Jul 16, 2024
066330d
make plaintext last check in hierachy again
gsantner Jul 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.view.MotionEvent;
import android.widget.TextView;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentManager;
Expand All @@ -44,7 +45,6 @@ public class DocumentActivity extends MarkorBaseActivity {
public static final String EXTRA_DO_PREVIEW = "EXTRA_DO_PREVIEW";

private Toolbar _toolbar;
private TextView _toolbarTitleText;
gsantner marked this conversation as resolved.
Show resolved Hide resolved

private FragmentManager _fragManager;

Expand Down Expand Up @@ -153,7 +153,6 @@ protected void onCreate(Bundle savedInstanceState) {
}
setContentView(R.layout.document__activity);
_toolbar = findViewById(R.id.toolbar);
_toolbarTitleText = findViewById(R.id.note__activity__text_note_title);
gsantner marked this conversation as resolved.
Show resolved Hide resolved

if (_appSettings.isHideSystemStatusbar()) {
AndroidBug5497Workaround.assistActivity(this);
Expand Down Expand Up @@ -281,8 +280,15 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
_cu.extractResultFromActivityResult(this, requestCode, resultCode, data);
}

public void setTitle(final CharSequence title) {
final ActionBar bar = getSupportActionBar();
if (bar != null) {
bar.setTitle(title);
gsantner marked this conversation as resolved.
Show resolved Hide resolved
}
}

public void setDocumentTitle(final String title) {
_toolbarTitleText.setText(title);
setTitle(title);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && _appSettings.isMultiWindowEnabled()) {
setTaskDescription(new ActivityManager.TaskDescription(title));
}
Expand All @@ -301,8 +307,7 @@ public void showTextEditor(final Document document, final Integer lineNumber, fi
}

public void showShareInto(Intent intent) {
// Disable edittext when going to shareinto
_toolbarTitleText.setText(R.string.share_into);
setTitle(getString(R.string.share_into));
showFragment(DocumentShareIntoFragment.newInstance(intent));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,27 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Patterns;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.widget.CompoundButtonCompat;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.CheckBoxPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
import androidx.appcompat.widget.Toolbar;

import net.gsantner.markor.ApplicationObject;
import net.gsantner.markor.R;
Expand All @@ -36,7 +42,6 @@
import net.gsantner.markor.frontend.NewFileDialog;
import net.gsantner.markor.frontend.filebrowser.MarkorFileBrowserFactory;
import net.gsantner.markor.frontend.textview.HighlightingEditor;
import net.gsantner.markor.frontend.textview.TextViewUtils;
import net.gsantner.markor.model.AppSettings;
import net.gsantner.markor.model.Document;
import net.gsantner.markor.util.MarkorContextUtils;
Expand Down Expand Up @@ -88,7 +93,7 @@ protected int getLayoutResId() {
@Override
public void onViewCreated(final @NonNull View view, final Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
HighlightingEditor _hlEditor = view.findViewById(R.id.document__fragment__share_into__highlighting_editor);
final HighlightingEditor _hlEditor = view.findViewById(R.id.document__fragment__share_into__highlighting_editor);

final String sharedText = (getArguments() != null ? getArguments().getString(EXTRA_SHARED_TEXT, "") : "").trim();
final ShareIntoImportOptionsFragment _shareIntoImportOptionsFragment;
Expand All @@ -102,7 +107,8 @@ public void onViewCreated(final @NonNull View view, final Bundle savedInstanceSt
}

if (_shareIntoImportOptionsFragment != null) {
_shareIntoImportOptionsFragment.setEditor(_hlEditor);
_shareIntoImportOptionsFragment._editor = _hlEditor;
_shareIntoImportOptionsFragment._linkCheckBox = addCheckBoxToToolbar();
}

_hlEditor.setTextSize(TypedValue.COMPLEX_UNIT_SP, _appSettings.getFontSize());
Expand All @@ -116,22 +122,58 @@ public void onViewCreated(final @NonNull View view, final Bundle savedInstanceSt
}
}

@Override
public String getFragmentTag() {
return FRAGMENT_TAG;
private CheckBox addCheckBoxToToolbar() {
gsantner marked this conversation as resolved.
Show resolved Hide resolved
final String CHECKBOX_TAG = "insert_link_checkbox";

final Activity activity = getActivity();
if (activity == null) {
return null;
}

final Toolbar toolbar = activity.findViewById(R.id.toolbar);
if (toolbar == null) {
return null;
}

CheckBox checkBox = toolbar.findViewWithTag(CHECKBOX_TAG);
if (checkBox == null) {

checkBox = new CheckBox(activity);
checkBox.setText(R.string.format_link);
checkBox.setTag(CHECKBOX_TAG);
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(Color.WHITE));
checkBox.setTextColor(Color.WHITE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
checkBox.setLayoutDirection(CheckBox.LAYOUT_DIRECTION_RTL);
gsantner marked this conversation as resolved.
Show resolved Hide resolved
}

final Toolbar.LayoutParams layoutParams = new Toolbar.LayoutParams(
Toolbar.LayoutParams.WRAP_CONTENT,
Toolbar.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL | Gravity.END
);

final int margin = _cu.convertDpToPx(activity, 10);
layoutParams.setMargins(0, 0, margin, 0);

toolbar.addView(checkBox, layoutParams);
}

return checkBox;
}

@Override
public boolean onBackPressed() {
return false;
public String getFragmentTag() {
return FRAGMENT_TAG;
}


public static class ShareIntoImportOptionsFragment extends GsPreferenceFragmentBase<AppSettings> {
public static final String TAG = "ShareIntoImportOptionsFragment";
private File workingDir;

private EditText _editor = null;
private CheckBox _linkCheckBox = null;

@Override
public boolean isDividerVisible() {
Expand All @@ -142,10 +184,6 @@ public void setWorkingDir(File dir) {
workingDir = dir;
}

public void setEditor(final EditText editor) {
_editor = editor;
}

@Override
public int getPreferenceResourceForInflation() {
return R.xml.prefactions_share_into;
Expand All @@ -166,20 +204,16 @@ protected void afterOnCreate(Bundle savedInstances, Context context) {
super.afterOnCreate(savedInstances, context);
doUpdatePreferences();

if (_editor != null) {
final CheckBoxPreference asLinkPref = (CheckBoxPreference) findPreference(R.string.pref_key__attach_as_link);
if (asLinkPref != null) {
asLinkPref.setVisible(hasLinks(_editor.getText()));
asLinkPref.setChecked(true);
_editor.addTextChangedListener(GsTextWatcherAdapter.on((ctext, arg2, arg3, arg4) ->
asLinkPref.setVisible(hasLinks(ctext))));
}
if (_editor != null && _linkCheckBox != null) {
_linkCheckBox.setVisibility(hasLinks(_editor.getText()) ? View.VISIBLE : View.GONE);
_linkCheckBox.setChecked(true);
_editor.addTextChangedListener(GsTextWatcherAdapter.on((ctext, arg2, arg3, arg4) ->
_linkCheckBox.setVisibility(hasLinks(_editor.getText()) ? View.VISIBLE : View.GONE)));
}
}

private boolean shareAsLink() {
final CheckBoxPreference asLinkPref = (CheckBoxPreference) findPreference(R.string.pref_key__attach_as_link);
return asLinkPref != null && asLinkPref.isVisible() && asLinkPref.isEnabled() && asLinkPref.isChecked();
return _linkCheckBox != null && _linkCheckBox.getVisibility() == View.VISIBLE && _linkCheckBox.isChecked();
}

private void appendToExistingDocumentAndClose(final File file, final boolean showEditor) {
Expand Down Expand Up @@ -244,50 +278,6 @@ private static boolean hasLinks(final CharSequence text) {
return hasLinks[0];
}

/**
* Iterates over each line of the text and checks if it is a path or link
* The whole line has to be a path or the line must end with a link to match.
*
* @param text Text to parse
* @return List of pairs.
* The first element of the pair is the start and end index of the link/path.
* Second element is true if it is a path, false if it is a link.
*/
public static List<Pair<int[], Boolean>> findLinksAndPaths(final CharSequence text) {
final List<Pair<int[], Boolean>> links = new ArrayList<>();

GsTextUtils.forEachline(text, (line, start, end) -> {

start = TextViewUtils.getNextNonWhitespace(text, start);
end = TextViewUtils.getLastNonWhitespace(text, end - 1) + 1;

if (start != -1 && end != -1 && start <= end) {

final String trimmed = text.subSequence(start, end).toString();
final boolean hasSpaces = trimmed.contains(" ") || trimmed.contains("\\t");

// Test for web links
if (!hasSpaces && Patterns.WEB_URL.matcher(trimmed).matches()) {
links.add(Pair.create(new int[]{start, end}, false));
return true;
}

// Test for file links
try {
if (new File(trimmed.replace("%20", " ")).exists()) {
links.add(Pair.create(new int[]{start, end}, true));
return true;
}
} catch (NullPointerException ignored) {
}
}

return true;
});

return links;
}

public static String getLinkTitle(final String link) {
final Matcher m = Patterns.WEB_URL.matcher(link);
if (m.matches()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@
import com.vladsch.flexmark.ext.yaml.front.matter.AbstractYamlFrontMatterVisitor;
import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.html.renderer.HeaderIdGenerator;
import com.vladsch.flexmark.html.renderer.LinkResolverContext;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.superscript.SuperscriptExtension;
import com.vladsch.flexmark.util.ast.Document;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.builder.Extension;
import com.vladsch.flexmark.util.html.Attributes;
import com.vladsch.flexmark.util.options.MutableDataHolder;
import com.vladsch.flexmark.util.options.MutableDataSet;
import com.vladsch.flexmark.html.AttributeProvider;
import com.vladsch.flexmark.html.AttributeProviderFactory;
import com.vladsch.flexmark.html.renderer.AttributablePart;

import net.gsantner.markor.R;
import net.gsantner.markor.format.TextConverterBase;
Expand All @@ -49,6 +55,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -149,7 +156,8 @@ public class MarkdownTextConverter extends TextConverterBase {
TypographicExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Typographic-Extension
GitLabExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Extensions#gitlab-flavoured-markdown
AdmonitionExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Extensions#admonition
FootnoteExtension.create() // https://github.com/vsch/flexmark-java/wiki/Footnotes-Extension#overview
FootnoteExtension.create(), // https://github.com/vsch/flexmark-java/wiki/Footnotes-Extension#overview
LineNumberIdExtension.create()
);
public static final Parser flexmarkParser = Parser.builder().extensions(flexmarkExtensions).build();
public static final HtmlRenderer flexmarkRenderer = HtmlRenderer.builder().extensions(flexmarkExtensions).build();
Expand Down Expand Up @@ -331,17 +339,13 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b

if (enableLineNumbers) {
// For Prism line numbers plugin
onLoadJs += "enableLineNumbers();adjustLineNumbers();";
onLoadJs += "enableLineNumbers(); adjustLineNumbers();";
}

// Deliver result
return putContentIntoTemplate(context, converted, lightMode, file, onLoadJs, head);
}

public static String generateHeaderId(String headerText) {
return HeaderIdGenerator.generateId(headerText, toDashChars, false, false);
}

private String escapeSpacesInLink(final String markup) {
final Matcher matcher = linkPattern.matcher(markup);
if (!matcher.find()) {
Expand Down Expand Up @@ -440,4 +444,60 @@ private String replaceTokens(final String markup, final Map<String, List<String>

return markupReplaced;
}

// Extension to add line numbers to headings
// ---------------------------------------------------------------------------------------------

public static String getIdForLineNumber(final int num) {
return "line-" + num;
}

private static class LineNumberIdProvider implements AttributeProvider {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So much boilerplate for a small extension

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this does is sets the id of every heading node to line-. This lets us jump to any heading super easily if we just know its line number.

@Override
public void setAttributes(Node node, AttributablePart part, Attributes attributes) {
if (node instanceof com.vladsch.flexmark.ast.Heading) {
final Document document = node.getDocument();
final int lineNumber = document.getLineNumber(node.getStartOffset());
attributes.addValue("id", getIdForLineNumber(lineNumber));
}
}
}

private static class LineNumberIdProviderFactory implements AttributeProviderFactory {

@Override
public Set<Class<? extends AttributeProviderFactory>> getAfterDependents() {
return null;
}

@Override
public Set<Class<? extends AttributeProviderFactory>> getBeforeDependents() {
return null;
}

@Override
public boolean affectsGlobalScope() {
return false;
}

@Override
public AttributeProvider create(LinkResolverContext context) {
return new LineNumberIdProvider();
}
}

private static class LineNumberIdExtension implements HtmlRenderer.HtmlRendererExtension {
@Override
public void rendererOptions(MutableDataHolder options) {
}

@Override
public void extend(HtmlRenderer.Builder rendererBuilder, String rendererType) {
rendererBuilder.attributeProviderFactory(new LineNumberIdProviderFactory());
}

public static HtmlRenderer.HtmlRendererExtension create() {
return new LineNumberIdExtension();
}
}
}
Loading
Loading