TakWolf-Deprecated / CNode-Material-Design

CNode 社区第三方 Android 客户端,原生 App,Material Design 风格,支持夜间模式。
https://cnodejs.org
Apache License 2.0
1.34k stars 347 forks source link

回复中粘贴链接发送之后不解析,重新进入话题才解析 #39

Closed atjiu closed 8 years ago

atjiu commented 8 years ago

这个跟之前提到的@用户不解析好像是一样的

TakWolf commented 8 years ago

是的,本地markdown解析不支持棵体url,服务器转换支持棵体url

atjiu commented 8 years ago

看了下代码,你用的是MarkdownPapers解析的markdown,我在网站里解析markdown用的都是js解析的,不过在java里处理了下,代码:

public static String marked(String content) {
    try {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
        scriptEngine.eval(new FileReader(PathKit.getWebRootPath() + "/static/js/marked.js"));
        Invocable invocable = (Invocable) scriptEngine;
        return (String) invocable.invokeFunction("marked", content);
    } catch (ScriptException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    return "";
}

marked.js

在marked.js里有一些参数可以配置,可以很灵活的配置解析的规则(比如超链接里加上target="_blank",table加上class等!貌似这些对网站开发比较有用 ),这个js默认解析链接

marked.defaults = {
  gfm: true,
  tables: true,
  breaks: false,//是否解析换行符
  pedantic: false,
  sanitize: false,//是否解析html(设置成true,就会将html原封不动的输出,不解析),就是你之前纠结的xss攻击的解决办法
  sanitizer: null,
  mangle: true,
  smartLists: false,
  silent: false,
  highlight: null,
  langPrefix: 'lang-',
  smartypants: false,
  headerPrefix: '',
  renderer: new Renderer,
  xhtml: false
};

PS: 看到你格式化时间是自己写的一个函数

private static final long MINUTE = 60 * 1000;
private static final long HOUR = 60 * MINUTE;
private static final long DAY = 24 * HOUR;
private static final long WEEK = 7 * DAY;
private static final long MONTH = 31 * DAY;
private static final long YEAR = 12 * MONTH;

public static String getRecentlyTimeText(@NonNull DateTime dateTime) {
    long offset = new DateTime().getMillis() - dateTime.getMillis();
    if (offset > YEAR) {
        return (offset / YEAR) + "年前";
    } else if (offset > MONTH) {
        return (offset / MONTH) + "个月前";
    } else if (offset > WEEK) {
        return (offset / WEEK) + "周前";
    } else if (offset > DAY) {
        return (offset / DAY) + "天前";
    } else if (offset > HOUR) {
        return (offset / HOUR) + "小时前";
    } else if (offset > MINUTE) {
        return (offset / MINUTE) + "分钟前";
    } else {
        return "刚刚";
    }
}

推荐一个格式化时间的库(听说过就掠过吧,而且你封装的格式时间已经很简单了,没必要用这个了,不过我太懒了,就喜欢用这些现成的^_^)prettytime

TakWolf commented 8 years ago

Markdown我溜了一圈没发现好用的,MarkdownPapers这个东西问题多多,有些格式转起来都是有问题的,我就当没看着...

ScriptEngineManager 这个Android没这接口

atjiu commented 8 years ago

如果让cnodejs服务端装好输出html,是不是到android里转成实体类就尽是问题? 我之前用Gson,fastjson都没转好过

cnodejs.org貌似挂了 @alsotang

TakWolf commented 8 years ago

@liygheart 可以转成实体类,html对应的是字符串类型。json本身有转移,所以不会影响

TakWolf commented 8 years ago

连接的匹配规则:

  1. 邮件应该被匹配 takwolf@foxmail.com -> <a href="mailto:takwolf@foxmail.com">
  2. 已经生成的连接不应该被匹配,即 以href="为开头的,或者以 ](http 为开头的不匹配
  3. img 标签中的不应该匹配,即以 src="开头的,或者以 ](http 开头的不匹配
  4. 中文路径应该被匹配,即最后一空格区分,如 http://www.takwolf.com/文字/100
  5. 连接的字符串应该被匹配,即 http://takwolf.comhttp://takwolf.com 应该匹配为两个连接
TakWolf commented 8 years ago

finish by https://github.com/TakWolf/CNode-Material-Design/commit/4f5fffad118029dabcfce1b7a4bc3bbdd2518b8e

atjiu commented 8 years ago

markdown解析工具,我找到一个好用的 https://github.com/sirthias/pegdown

<dependency>
    <groupId>org.pegdown</groupId>
    <artifactId>pegdown</artifactId>
    <version>1.6.0</version>
</dependency>

支持裸体url,换行一次就可以解析成
支持table,唯一一点它貌似没法设置不解析md里的html,不过这个可以在解析好了之后用Jsoup过滤一下,pybbs 已经用上了

private final static PegDownProcessor md = new PegDownProcessor(Extensions.ALL_WITH_OPTIONALS);

    public static String pegDown(String content) {
        return md.markdownToHtml(content);
    }
public String marked(String content) {
        //处理@
        List<String> users = StrUtil.fetchUsers(content);
        for (String user : users) {
            content = content.replace("@" + user, "[@" + user + "](/user/" + user + ")");
        }
        //markdown 转 html 并返回
        return Jsoup.clean(MarkdownUtil.pegDown(content), Whitelist.relaxed());
    }
atjiu commented 8 years ago

唯一缺陷是,jar包有6-7个。。对android来说是个硬伤。。

TakWolf commented 8 years ago

@tomoya92 实测,这货不支持Android,见https://github.com/sirthias/pegdown/issues/231

他用了一个包叫做org.objectweb.asm (http://asm.ow2.org/index.html ),可以用来直接操作和生成字节码,估计是用来提升渲染效率的。

但是Android上是不支持的。

MrAugust commented 8 years ago

@TakWolf 那你后来在Android上使用哪个库来解析.md的?https://github.com/rjeschke/txtmarkhttps://github.com/falnatsheh/MarkdownView中使用的MarkdownProcessor都无法解析表格

TakWolf commented 8 years ago

@MrAugust 现在用的是这个解析的 http://markdown.tautua.org/ 支不支持表格没测试,普通样式转换也有很多问题,将就用着而已。我目前也没找到一个好用的能在Android上使用的MD解析器

atjiu commented 8 years ago

@TakWolf 为啥不让cnodejs.org解析好输出html呢?

TakWolf commented 8 years ago

@tomoya92 现在就是服务端解析的