package com.avenwu.deepinandroid; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; import android.widget.EditText; import org.markdown4j.Markdown4jProcessor; import java.io.IOException; import java.util.Locale; import butterknife.ButterKnife; import butterknife.InjectView; public class MarkdownDemo extends ActionBarActivity implements ActionBar.TabListener, Content { SectionsPagerAdapter mSectionsPagerAdapter; ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_markdown_demo); // Set up the action bar. final ActionBar actionBar = getSupportActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Create the adapter that will return a fragment for each of the three // primary sections of the activity. mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mSectionsPagerAdapter); // When swiping between different sections, select the corresponding // tab. We can also use ActionBar.Tab#select() to do this if we have // a reference to the Tab. mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { actionBar.setSelectedNavigationItem(position); } }); // For each of the sections in the app, add a tab to the action bar. for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { actionBar.addTab( actionBar.newTab() .setText(mSectionsPagerAdapter.getPageTitle(i)) .setTabListener(this)); } } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } private static String makeFragmentName(int viewId, long id) { return "android:switcher:" + viewId + ":" + id; } @Override public String getContent() { Fragment fragment = getSupportFragmentManager().findFragmentByTag(makeFragmentName(mViewPager.getId(), 0)); if (fragment instanceof Content) { return ((Content) fragment).getContent(); } return ""; } /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. */ public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new EditFragment(); default: return new PreviewFragment(); } } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { Locale l = Locale.getDefault(); switch (position) { case 0: return getString(R.string.title_section1).toUpperCase(l); case 1: return getString(R.string.title_section2).toUpperCase(l); } return null; } } /** * A placeholder fragment containing a simple view. */ public static class EditFragment extends Fragment implements Content { @InjectView(R.id.edt_input) EditText mInputView; // String TEMPLATE_DATA = "#Hello\nThis is simple text in format of markdown.\n- li\n- li"; String TEMPLATE_DATA = "# Mou\n" + "\n" + "![Mou icon](http://25.io/mou/Mou_128.png)\n" + "\n" + "## Overview\n" + "\n" + "**Mou**, the missing Markdown editor for *web developers*.\n" + "\n" + "### Syntax\n" + "\n" + "#### Strong and Emphasize \n" + "\n" + "**strong** or __strong__ ( Cmd + B )\n" + "\n" + "*emphasize* or _emphasize_ ( Cmd + I )\n" + "\n" + "**Sometimes I want a lot of text to be bold.\n" + "Like, seriously, a _LOT_ of text**\n" + "\n" + "#### Blockquotes\n" + "\n" + "> Right angle brackets > are used for block quotes.\n" + "\n" + "#### Links and Email\n" + "\n" + "An email <example@example.com> link.\n" + "\n" + "Simple inline link <http://chenluois.com>, another inline link [Smaller](http://25.io/smaller/), one more inline link with title [Resize](http://resizesafari.com \"a Safari extension\").\n" + "\n" + "A [reference style][id] link. Input id, then anywhere in the doc, define the link with corresponding id:\n" + "\n" + "[id]: http://25.io/mou/ \"Markdown editor on Mac OS X\"\n" + "\n" + "Titles ( or called tool tips ) in the links are optional.\n" + "\n" + "#### Images\n" + "\n" + "An inline image ![Smaller icon](http://25.io/smaller/favicon.ico \"Title here\"), title is optional.\n" + "\n" + "A ![Resize icon][2] reference style image.\n" + "\n" + "[2]: http://resizesafari.com/favicon.ico \"Title\"\n" + "\n" + "#### Inline code and Block code\n" + "\n" + "Inline code are surround by `backtick` key. To create a block code:\n" + "\n" + "\tIndent each line by at least 1 tab, or 4 spaces.\n" + " var Mou = exactlyTheAppIwant; \n" + "\n" + "#### Ordered Lists\n" + "\n" + "Ordered lists are created using \"1.\" + Space:\n" + "\n" + "1. Ordered list item\n" + "2. Ordered list item\n" + "3. Ordered list item\n" + "\n" + "#### Unordered Lists\n" + "\n" + "Unordered list are created using \"*\" + Space:\n" + "\n" + "* Unordered list item\n" + "* Unordered list item\n" + "* Unordered list item \n" + "\n" + "Or using \"-\" + Space:\n" + "\n" + "- Unordered list item\n" + "- Unordered list item\n" + "- Unordered list item\n" + "\n" + "#### Hard Linebreak\n" + "\n" + "End a line with two or more spaces will create a hard linebreak, called `<br />` in HTML. ( Control + Return ) \n" + "Above line ended with 2 spaces.\n" + "\n" + "#### Horizontal Rules\n" + "\n" + "Three or more asterisks or dashes:\n" + "\n" + "***\n" + "\n" + "---\n" + "\n" + "- - - -\n" + "\n" + "#### Headers\n" + "\n" + "Setext-style:\n" + "\n" + "This is H1\n" + "==========\n" + "\n" + "This is H2\n" + "----------\n" + "\n" + "atx-style:\n" + "\n" + "# This is H1\n" + "## This is H2\n" + "### This is H3\n" + "#### This is H4\n" + "##### This is H5\n" + "###### This is H6\n" + "\n" + "\n" + "### Extra Syntax\n" + "\n" + "#### Footnotes\n" + "\n" + "Footnotes work mostly like reference-style links. A footnote is made of two things: a marker in the text that will become a superscript number; a footnote definition that will be placed in a list of footnotes at the end of the document. A footnote looks like this:\n" + "\n" + "That's some text with a footnote.[^1]\n" + "\n" + "[^1]: And that's the footnote.\n" + "\n" + "\n" + "#### Strikethrough\n" + "\n" + "Wrap with 2 tilde characters:\n" + "\n" + "~~Strikethrough~~\n" + "\n" + "\n" + "#### Fenced Code Blocks\n" + "\n" + "Start with a line containing 3 or more backticks, and ends with the first line with the same number of backticks:\n" + "\n" + "```\n" + "Fenced code blocks are like Stardard Markdown’s regular code\n" + "blocks, except that they’re not indented and instead rely on\n" + "a start and end fence lines to delimit the code block.\n" + "```\n" + "\n" + "\n" + "### Shortcuts\n" + "\n" + "#### View\n" + "\n" + "* Toggle live preview: Shift + Cmd + I\n" + "* Toggle Words Counter: Shift + Cmd + W\n" + "* Toggle Transparent: Shift + Cmd + T\n" + "* Toggle Floating: Shift + Cmd + F\n" + "* Left/Right = 1/1: Cmd + 0\n" + "* Left/Right = 3/1: Cmd + +\n" + "* Left/Right = 1/3: Cmd + -\n" + "* Toggle Writing orientation: Cmd + L\n" + "* Toggle fullscreen: Control + Cmd + F\n" + "\n" + "#### Actions\n" + "\n" + "* Copy HTML: Option + Cmd + C\n" + "* Strong: Select text, Cmd + B\n" + "* Emphasize: Select text, Cmd + I\n" + "* Inline Code: Select text, Cmd + K\n" + "* Strikethrough: Select text, Cmd + U\n" + "* Link: Select text, Control + Shift + L\n" + "* Image: Select text, Control + Shift + I\n" + "* Select Word: Control + Option + W\n" + "* Select Line: Shift + Cmd + L\n" + "* Select All: Cmd + A\n" + "* Deselect All: Cmd + D\n" + "* Convert to Uppercase: Select text, Control + U\n" + "* Convert to Lowercase: Select text, Control + Shift + U\n" + "* Convert to Titlecase: Select text, Control + Option + U\n" + "* Convert to List: Select lines, Control + L\n" + "* Convert to Blockquote: Select lines, Control + Q\n" + "* Convert to H1: Cmd + 1\n" + "* Convert to H2: Cmd + 2\n" + "* Convert to H3: Cmd + 3\n" + "* Convert to H4: Cmd + 4\n" + "* Convert to H5: Cmd + 5\n" + "* Convert to H6: Cmd + 6\n" + "* Convert Spaces to Tabs: Control + [\n" + "* Convert Tabs to Spaces: Control + ]\n" + "* Insert Current Date: Control + Shift + 1\n" + "* Insert Current Time: Control + Shift + 2\n" + "* Insert entity <: Control + Shift + ,\n" + "* Insert entity >: Control + Shift + .\n" + "* Insert entity &: Control + Shift + 7\n" + "* Insert entity Space: Control + Shift + Space\n" + "* Insert Scriptogr.am Header: Control + Shift + G\n" + "* Shift Line Left: Select lines, Cmd + [\n" + "* Shift Line Right: Select lines, Cmd + ]\n" + "* New Line: Cmd + Return\n" + "* Comment: Cmd + /\n" + "* Hard Linebreak: Control + Return\n" + "\n" + "#### Edit\n" + "\n" + "* Auto complete current word: Esc\n" + "* Find: Cmd + F\n" + "* Close find bar: Esc\n" + "\n" + "#### Post\n" + "\n" + "* Post on Scriptogr.am: Control + Shift + S\n" + "* Post on Tumblr: Control + Shift + T\n" + "\n" + "#### Export\n" + "\n" + "* Export HTML: Option + Cmd + E\n" + "* Export PDF: Option + Cmd + P\n" + "\n" + "\n" + "### And more?\n" + "\n" + "Don't forget to check Preferences, lots of useful options are there.\n" + "\n" + "Follow [@Mou](https://twitter.com/mou) on Twitter for the latest news.\n" + "\n" + "For feedback, use the menu `Help` - `Send Feedback`"; public EditFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.markdown_edit, container, false); ButterKnife.inject(this, rootView); mInputView.setText(TEMPLATE_DATA); return rootView; } @Override public String getContent() { return mInputView.getText().toString(); } } public static class PreviewFragment extends Fragment { private WebView mWebView; private boolean mIsWebViewAvailable; private Markdown4jProcessor mProcessor; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (mWebView != null) { mWebView.destroy(); } mWebView = new WebView(getActivity()); mIsWebViewAvailable = true; mProcessor = new Markdown4jProcessor(); return mWebView; } @Override public void onPause() { super.onPause(); mWebView.onPause(); } @Override public void onResume() { mWebView.onResume(); super.onResume(); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { String data = ((Content) getActivity()).getContent(); mWebView.loadData(renderMarkdownString(data), "text/html", "UTF-8"); } } String mTemplate = "<link rel=\"stylesheet\" href=\"file:///android_asset/github-markdown.css\"/><div class=\"markdown-body\">%s</div>"; String renderMarkdownString(String raw) { try { return String.format(mTemplate, mProcessor.process(raw)); } catch (IOException e) { e.printStackTrace(); return String.format(mTemplate, raw); } } @Override public void onDestroyView() { mIsWebViewAvailable = false; super.onDestroyView(); } @Override public void onDestroy() { if (mWebView != null) { mWebView.destroy(); mWebView = null; } super.onDestroy(); } } }