Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ _site/
# counterproductive to check this file into the repository.
# Details at https://github.com/github/pages-gem/issues/768
Gemfile.lock

# Node.js dependencies
node_modules/
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
# small-apps
small apps for various use cases

## Apps

### Markdown Renderer Chrome Extension

A Chrome browser extension that automatically renders local and remote markdown files (`.md`) with beautiful GitHub-flavored styling.

**Location:** `markdown-renderer-extension/`

**Features:**
- 🎨 Automatic rendering of `.md` files
- 📁 Works with local files (`file://`) and remote URLs
- ✨ GitHub-inspired markdown styling
- 🚀 Lightweight and fast
- 📝 Full markdown support (headers, lists, code blocks, tables, etc.)

**Installation:**
1. Open Chrome and navigate to `chrome://extensions/`
2. Enable "Developer mode"
3. Click "Load unpacked" and select the `markdown-renderer-extension` directory
4. Enable "Allow access to file URLs" in the extension settings

See the [extension README](markdown-renderer-extension/README.md) for full documentation.

### Math Practice Apps

Simple HTML-based math practice applications:
- `add-subtract.html` - Addition and subtraction practice
- `add-subtract-mission.html` - Mission-based math practice
101 changes: 101 additions & 0 deletions markdown-renderer-extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Markdown Renderer Chrome Extension

A Chrome browser extension that automatically renders local and remote markdown files (`.md`) in a beautiful, readable format.

## Features

- 🎨 Automatically renders `.md` files with GitHub-flavored styling
- 📁 Works with both local files (`file://`) and remote URLs (`http://`, `https://`)
- 🚀 Lightweight and fast
- ✨ Clean, readable interface inspired by GitHub's markdown styling
- 📝 Supports standard markdown features:
- Headers
- Lists (ordered and unordered)
- Code blocks with syntax preservation
- Tables
- Links and images
- Blockquotes
- Bold, italic, and strikethrough text
- Horizontal rules

## Installation

### From Source (Developer Mode)

1. Download or clone this repository
2. Open Chrome and navigate to `chrome://extensions/`
3. Enable "Developer mode" using the toggle in the top-right corner
4. Click "Load unpacked"
5. Select the `markdown-renderer-extension` directory
6. The extension is now installed and active!

## Usage

Once installed, the extension works automatically:

1. **For remote files**: Simply navigate to any URL ending with `.md`
- Example: `https://raw.githubusercontent.com/user/repo/main/README.md`

2. **For local files**: Open any local `.md` file in Chrome
- Use `File > Open File` or drag-and-drop a `.md` file into Chrome
- Make sure to allow file access in the extension settings:
- Go to `chrome://extensions/`
- Find "Markdown Renderer"
- Enable "Allow access to file URLs"

The extension will automatically detect markdown files and render them with beautiful formatting.

## Technical Details

- **Manifest Version**: 3 (latest Chrome extension format)
- **Markdown Parser**: marked.js
- **Styling**: GitHub-flavored markdown CSS
- **Permissions**:
- `<all_urls>` - To render markdown from any website
- `storage` - For future settings storage

## Supported File Types

The extension activates for:
- URLs ending with `.md` extension
- Content served with `text/plain` or `text/markdown` content type

## Styling

The rendered markdown uses a clean, GitHub-inspired theme with:
- Responsive design (mobile-friendly)
- Proper syntax highlighting preservation for code blocks
- Table formatting
- Accessible color scheme

## Development

The extension consists of:
- `manifest.json` - Extension configuration
- `content.js` - Main script that detects and renders markdown
- `markdown.css` - Styling for rendered content
- `marked.min.js` - Markdown parsing library
- Icon files (16x16, 48x48, 128x128 pixels)

## Privacy

This extension:
- Runs entirely in your browser (client-side)
- Does not collect or transmit any data
- Does not require any external API calls
- Only activates on markdown files

## License

This extension is part of the small-apps repository. See the main LICENSE file for details.

## Troubleshooting

**Issue**: Local files don't render
- **Solution**: Make sure "Allow access to file URLs" is enabled in chrome://extensions/

**Issue**: Remote files don't render
- **Solution**: Check that the URL ends with `.md` and returns plain text content

**Issue**: Markdown not rendering properly
- **Solution**: Try refreshing the page (Ctrl+R or Cmd+R)
86 changes: 86 additions & 0 deletions markdown-renderer-extension/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Check if the current page is a markdown file
function isMarkdownFile() {
const url = window.location.href;
const pathname = window.location.pathname;

// Check if URL ends with .md
if (pathname.toLowerCase().endsWith('.md')) {
return true;
}

// Check if the content type is text/plain or text/markdown
const contentType = document.contentType;
if (contentType === 'text/plain' || contentType === 'text/markdown') {
// Additional check: URL should end with .md
if (url.toLowerCase().endsWith('.md')) {
return true;
}
}

return false;
}

// Get the markdown content from the page
function getMarkdownContent() {
// For files served as plain text, the content is usually in a <pre> tag
const preElement = document.querySelector('body > pre');
if (preElement) {
return preElement.textContent;
}

// Otherwise, try to get the body text content
return document.body.textContent;
}

// Render the markdown content
function renderMarkdown() {
if (!isMarkdownFile()) {
return;
}

// Check if marked.js is available
if (typeof marked === 'undefined') {
console.error('Markdown Renderer: marked.js library not loaded');
return;
}

try {
// Get the raw markdown content
const markdownContent = getMarkdownContent();

if (!markdownContent || markdownContent.trim() === '') {
return;
}

// Configure marked options
marked.setOptions({
gfm: true, // GitHub Flavored Markdown
breaks: true // Convert \n to <br>
});

// Parse the markdown
const htmlContent = marked.parse(markdownContent);

// Create a new container for the rendered content
const container = document.createElement('div');
container.className = 'markdown-body';
container.innerHTML = htmlContent;

// Replace the body content with the rendered markdown
document.body.innerHTML = '';
document.body.appendChild(container);

// Add a class to the body for styling
document.body.classList.add('markdown-rendered');

} catch (error) {
console.error('Markdown Renderer: Error rendering markdown', error);
}
}

// Run when the DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', renderMarkdown);
} else {
renderMarkdown();
}
Binary file added markdown-renderer-extension/icon128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added markdown-renderer-extension/icon16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added markdown-renderer-extension/icon48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions markdown-renderer-extension/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"manifest_version": 3,
"name": "Markdown Renderer",
"version": "1.0.0",
"description": "Renders local and remote markdown (.md) files in the browser",
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["marked.min.js", "content.js"],
"css": ["markdown.css"],
"run_at": "document_end"
}
],
"permissions": [
"storage"
],
"host_permissions": [
"<all_urls>"
]
}
Loading