├── .foam └── templates │ └── your-first-template.md ├── .gitignore ├── .vscode ├── extensions.json ├── foam.json ├── settings.json └── spellright.dict ├── README.md ├── components ├── AnchorTag.js ├── CodeBlock.js ├── Header.js ├── Image.js ├── Layout.js └── button.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── excalidrawn.md ├── inbox.md ├── index.md ├── jsx-component-in-mdx-example.md ├── next-image-component-example.md ├── notes │ ├── note.md │ └── syntax-highlighting.md ├── readme.md └── todo.md ├── public └── images │ ├── excalidrawn.png │ └── excalidrawn.svg ├── siteconfig.js ├── styles ├── global.css └── prism-theme-night-owl.css └── yarn.lock /.foam/templates/your-first-template.md: -------------------------------------------------------------------------------- 1 | # Foam Note Templates 2 | 3 | Foam includes note templates! 4 | This allows you to easily create notes that have similar structure without having to use copy/paste :) 5 | 6 | Templates support the [VS Code's Snippet Syntax](https://code.visualstudio.com/docs/editor/userdefinedsnippets#_snippet-syntax), which means you can: 7 | - add variables to the newly created note 8 | - add tabstop to automatically navigate to the key parts of the note, just like a form 9 | Below you can see an example showing a todo list and a timestamp. 10 | 11 | ## Todo List 12 | 13 | 1. ${1:First tabstop} 14 | 2. ${2:A second tabstop} 15 | 3. ${3:A third tabstop} 16 | 17 | Note Created: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} 18 | 19 | --- 20 | 21 | Try out the above example by running the `Foam: Create New Note From Template` command and selecting the `your-first-template` template. Notice what happens when your new note is created! 22 | 23 | To remove this template, simply delete the `.foam/templates/your-first-template.md` file. 24 | 25 | Enjoy! 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | // Foam's own extension 6 | "foam.foam-vscode", 7 | 8 | // Tons of markdown goodies (lists, tables of content, so much more) 9 | "yzhang.markdown-all-in-one", 10 | 11 | // [[wiki-links]], backlinking etc 12 | "kortina.vscode-markdown-notes", 13 | 14 | // Image-pasting for markdown 15 | "mushan.vscode-paste-image", 16 | 17 | // Spell checking for text, markdown and latex 18 | "ban.spellright", 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/foam.json: -------------------------------------------------------------------------------- 1 | { 2 | "purpose": "this file exists to tell the foam-vscode plugin that it's currently in a foam workspace", 3 | "future": "we may use this for custom configuration" 4 | } 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.minimap.enabled": false, 3 | "editor.wrappingIndent": "indent", 4 | "editor.overviewRulerBorder": false, 5 | "editor.lineHeight": 24, 6 | "[markdown]": { 7 | "editor.quickSuggestions": true 8 | }, 9 | "files.defaultLanguage": "markdown", 10 | "files.exclude": { 11 | "**/node_modules": true 12 | }, 13 | "files.watcherExclude": { 14 | "**/node_modules": true 15 | }, 16 | "foam.edit.linkReferenceDefinitions": "withoutExtensions", 17 | "foam.openDailyNote.directory": "journal", 18 | "foam.openDailyNote.titleFormat": "fullDate", 19 | "git.enableSmartCommit": true, 20 | "git.postCommitCommand": "sync", 21 | "markdown.preview.breaks": true, 22 | "pasteImage.path": "${projectRoot}/attachments", 23 | "pasteImage.showFilePathConfirmInputBox": true, 24 | "prettier.singleQuote": false, 25 | "spellright.notificationClass": "warning", 26 | "vscodeMarkdownNotes.noteCompletionConvention": "noExtension", 27 | "vscodeMarkdownNotes.slugifyMethod": "github-slugger", 28 | } 29 | -------------------------------------------------------------------------------- /.vscode/spellright.dict: -------------------------------------------------------------------------------- 1 | wikilink 2 | spellright 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Foamy NextJS Starter 2 | 3 | This starter combines [Foam](https://foambubble.github.io/foam) with [NextJS](https://nextjs.org). I built this using [NextJS with MDX example repo](https://github.com/vercel/next.js/tree/canary/examples/with-mdx) as my base repo. 4 | 5 | ## Getting Started 6 | 1. Click on **Use this template** button 7 | 2. Clone the repository locally 8 | 9 | ```bash 10 | cd your-local-repo-name 11 | npm install 12 | # or 13 | yarn install 14 | 15 | npm run dev 16 | # or 17 | yarn dev 18 | ``` 19 | 20 | Foam requires specific VS Code extensions for it to work properly. Open the repository as a folder using the File > Open... menu item. When prompted to install recommended extensions, click **Install all** (or **Show Recommendations** if you want to review and install them one by one). 21 | 22 | Open `index.md` in `/pages` directory and edit to your heart's content. All other markdown files and notes folder are examples. Before doing so, I recommend clicking around to see how things work. 23 | 24 | ## How to customize 25 | I purposefully built this starter to be bare in styling and functionality to leave plenty of room to customize and build on top. 26 | 27 | ### Basic Global styles 28 | I used Gridlover to generate a typography system with modular scale and vertical rhythm. Add your preferred fonts, [choose your own scale](https://www.gridlover.net/try), and replace all styles in `/styles/global.css` between these comments 29 | ```CSS 30 | /* begin gridlover perfect fourth scale */ 31 | // ... 32 | /* end gridlover perfect fourth scale */ 33 | ``` 34 | 35 | ### Syntax highlighting theme 36 | Add your preferred prism theme CSS file in `/styles` folder and import it to `_app.js` 37 | ```javascript 38 | import '../styles/prism-theme-night-owl.css' 39 | ``` 40 | You can convert your VS Code theme to use with this tool: 41 | [VS Code to Prism Themes](https://prism.dotenv.dev/) 42 | 43 | *Note:* This uses prism-react-renderer for syntax highlight. It's set to use styles from css so the theme is set to null in CodeBlock component. Refer to [prism-react-renderer FAQ](https://github.com/FormidableLabs/prism-react-renderer#faq) for other methods. 44 | 45 | ### CSS Styling Methods 46 | NextJS uses CSS Modules by default. [Next JS Docs: Built-In CSS Support](https://nextjs.org/docs/basic-features/built-in-css-support) on how to configure for other methods. 47 | 48 | ### Siteconfig.js 49 | `siteconfig.js` is used for populating site name in the Header and Layout components. 50 | ```javascript 51 | export default { 52 | "title": "Foamy NextJS", 53 | "description": "Digital Garden built with Foam and NextJS with MDX", 54 | "author": "Yenly Ma" 55 | } 56 | ``` 57 | 58 | ### Remark and Rehype plugins 59 | Add/remove plugins in `next.config.js` 60 | ```javascript 61 | const remarkImages = require('remark-images') 62 | const remarkExternalLinks = require('remark-external-links') 63 | const remarkFootnote = require('remark-numbered-footnote-labels') 64 | 65 | const withMDX = require('@next/mdx')({ 66 | extension: /\.mdx?$/, 67 | options: { 68 | remarkPlugins: [ 69 | remarkImages, 70 | remarkExternalLinks, 71 | [remarkFootnotes] 72 | ] 73 | }, 74 | }) 75 | ``` 76 | 77 | ### How to upgrade Foam 78 | [Fork the latest Foam template](https://github.com/foambubble/foam-template). Copy `.vscode` directory to your root level of your repo. Open your workspace and things should magically work. It's Foam's magic sauce. If not, try: 79 | - update VS Code extensions defined in `.vscode/extensions.json` 80 | - disable and enable extensions needed and restart VS Code 81 | 82 | ### How to deploy 83 | I pick this stack for its easy [deploy to Vercel](https://nextjs.org/docs/deployment). To deploy under a sub-path on your domain, [use `basePath` option](https://nextjs.org/docs/api-reference/next.config.js/basepath). 84 | 85 | ### Recommended Resources 86 | - [Foam Recipes](https://foambubble.github.io/foam/recipes) 87 | - [Learn NextJS](https://nextjs.org/learn/basics/create-nextjs-app) or dig into their [Docs](https://nextjs.org/docs/getting-started) 88 | - [MDXJS](https://mdxjs.com/) 89 | - [MDX Conf 2020](https://egghead.io/playlists/mdx-conf-3fc2) - Demystifying MDX talk is particularly helpful for me as a beginner 90 | -------------------------------------------------------------------------------- /components/AnchorTag.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | const AnchorTag = (props) => { 4 | const { href, title, target, children } = props 5 | if (target) { 6 | return {children} 7 | } 8 | return {title || children} 9 | } 10 | 11 | export default AnchorTag -------------------------------------------------------------------------------- /components/CodeBlock.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Highlight, { defaultProps } from 'prism-react-renderer' 3 | 4 | const CodeBlock = ({ children, className }) => { 5 | const language = className.replace(/language-/, '') 6 | 7 | return ( 8 | 9 | {({ className, style, tokens, getLineProps, getTokenProps }) => ( 10 |
11 |           {tokens.map((line, i) => (
12 |             
13 | {line.map((token, key) => ( 14 | 15 | ))} 16 |
17 | ))} 18 |
19 | )} 20 |
21 | ) 22 | } 23 | 24 | export default CodeBlock 25 | -------------------------------------------------------------------------------- /components/Header.js: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | 3 | export default function Header({ siteName }) { 4 | return ( 5 | <> 6 |
7 | 10 |
11 | 12 | ) 13 | } -------------------------------------------------------------------------------- /components/Image.js: -------------------------------------------------------------------------------- 1 | import NextImage from 'next/image' 2 | 3 | export default function Image(props) { 4 | let { 5 | src, 6 | alt, 7 | width = 600, 8 | height = 460, 9 | layout = 'intrinsic' } = props 10 | if(src.includes('?')) { 11 | const dimensions = src.split('?') 12 | const widthHeight = dimensions[1].split('x') 13 | width = widthHeight[0] 14 | height = widthHeight[1] 15 | } 16 | if (layout === 'fixed' || layout === 'responsive') { 17 | return ( 18 | <> 19 | 26 | 27 | ) 28 | } else { 29 | return ( 30 | <> 31 | 37 | 38 | ) 39 | } 40 | } -------------------------------------------------------------------------------- /components/Layout.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import Header from './Header' 3 | 4 | export default function Layout({ children, siteData }) { 5 | return ( 6 | <> 7 | 8 | 9 | 10 | 11 | {siteData.title} 12 | 13 |
14 |
15 | {children} 16 |
17 | 18 | ) 19 | } -------------------------------------------------------------------------------- /components/button.js: -------------------------------------------------------------------------------- 1 | export default function Button({ children }) { 2 | return ( 3 | 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const remarkImages = require('remark-images') 2 | const remarkExternalLinks = require('remark-external-links') 3 | const remarkFootnote = require('remark-numbered-footnote-labels') 4 | const remarkUnwrapImages = require('remark-unwrap-images') 5 | 6 | const withMDX = require('@next/mdx')({ 7 | extension: /\.mdx?$/, 8 | options: { 9 | remarkPlugins: [ 10 | remarkImages, 11 | remarkExternalLinks, 12 | remarkFootnote, 13 | remarkUnwrapImages 14 | ] 15 | }, 16 | }) 17 | module.exports = withMDX({ 18 | pageExtensions: ['js', 'jsx', 'mdx', 'md'], 19 | }) 20 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foamy-nextjs", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/unist": { 8 | "version": "2.0.3", 9 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", 10 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" 11 | }, 12 | "extend": { 13 | "version": "3.0.2", 14 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 15 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 16 | }, 17 | "hast-util-whitespace": { 18 | "version": "1.0.4", 19 | "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", 20 | "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==" 21 | }, 22 | "is-absolute-url": { 23 | "version": "3.0.3", 24 | "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", 25 | "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" 26 | }, 27 | "is-url": { 28 | "version": "1.2.4", 29 | "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", 30 | "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" 31 | }, 32 | "mdast-util-definitions": { 33 | "version": "3.0.1", 34 | "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-3.0.1.tgz", 35 | "integrity": "sha512-BAv2iUm/e6IK/b2/t+Fx69EL/AGcq/IG2S+HxHjDJGfLJtd6i9SZUS76aC9cig+IEucsqxKTR0ot3m933R3iuA==", 36 | "requires": { 37 | "unist-util-visit": "^2.0.0" 38 | } 39 | }, 40 | "remark-external-links": { 41 | "version": "7.0.0", 42 | "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-7.0.0.tgz", 43 | "integrity": "sha512-Iihlg28wFTWyGyTquKolM6nHLkgrRnRXp/QSwjbWGThwIFVKIMHZLAkCii26aTGDEiKr6p1QfMt4oltBIIngug==", 44 | "requires": { 45 | "extend": "^3.0.0", 46 | "is-absolute-url": "^3.0.0", 47 | "mdast-util-definitions": "^3.0.0", 48 | "space-separated-tokens": "^1.0.0", 49 | "unist-util-visit": "^2.0.0" 50 | } 51 | }, 52 | "remark-images": { 53 | "version": "2.0.0", 54 | "resolved": "https://registry.npmjs.org/remark-images/-/remark-images-2.0.0.tgz", 55 | "integrity": "sha512-1X6XTBQZW489HSwU0k+aU3xAlVe3TyPll6N2Mt1onwINTIqcTk9QTC57937Z8NQDJ8h7gKGXy9d4TJug2dm8lg==", 56 | "requires": { 57 | "is-url": "^1.2.2", 58 | "unist-util-is": "^4.0.0", 59 | "unist-util-visit-parents": "^3.0.0" 60 | } 61 | }, 62 | "remark-unwrap-images": { 63 | "version": "2.0.0", 64 | "resolved": "https://registry.npmjs.org/remark-unwrap-images/-/remark-unwrap-images-2.0.0.tgz", 65 | "integrity": "sha512-uehiJU5U1ZNQxTKUlAKOQhVyFsc+9WWvamkuoF3ILdMpASHwA1JbzTOZcRWv+annYfDWuPSuoZAWdt1r0SlrfQ==", 66 | "requires": { 67 | "hast-util-whitespace": "^1.0.0", 68 | "unist-util-visit": "^2.0.0" 69 | } 70 | }, 71 | "space-separated-tokens": { 72 | "version": "1.1.5", 73 | "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", 74 | "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" 75 | }, 76 | "unist-util-is": { 77 | "version": "4.0.2", 78 | "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", 79 | "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" 80 | }, 81 | "unist-util-visit": { 82 | "version": "2.0.3", 83 | "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", 84 | "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", 85 | "requires": { 86 | "@types/unist": "^2.0.0", 87 | "unist-util-is": "^4.0.0", 88 | "unist-util-visit-parents": "^3.0.0" 89 | } 90 | }, 91 | "unist-util-visit-parents": { 92 | "version": "3.1.0", 93 | "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.0.tgz", 94 | "integrity": "sha512-0g4wbluTF93npyPrp/ymd3tCDTMnP0yo2akFD2FIBAYXq/Sga3lwaU1D8OYKbtpioaI6CkDcQ6fsMnmtzt7htw==", 95 | "requires": { 96 | "@types/unist": "^2.0.0", 97 | "unist-util-is": "^4.0.0" 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foamy-nextjs", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "next", 6 | "build": "next build", 7 | "start": "next start" 8 | }, 9 | "dependencies": { 10 | "@mdx-js/loader": "^1.6.21", 11 | "@next/mdx": "^10.0.1", 12 | "next": "^10.0.1", 13 | "prism-react-renderer": "^1.1.1", 14 | "react": "^17.0.1", 15 | "react-dom": "^17.0.1", 16 | "remark-external-links": "^7.0.0", 17 | "remark-images": "^2.0.0", 18 | "remark-numbered-footnote-labels": "^1.1.0", 19 | "remark-unwrap-images": "^2.0.0" 20 | }, 21 | "devDependencies": {}, 22 | "license": "ISC" 23 | } 24 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/global.css' 2 | import '../styles/prism-theme-night-owl.css' 3 | import Layout from '../components/Layout' 4 | import siteData from '../siteconfig' 5 | import { MDXProvider } from '@mdx-js/react' 6 | import CodeBlock from '../components/CodeBlock' 7 | import AnchorTag from '../components/AnchorTag' 8 | import Image from '../components/Image' 9 | 10 | const mdComponents = { 11 | a: props => , 12 | code: CodeBlock, 13 | img: (props) =>
, 14 | Image: (props) =>
15 | } 16 | 17 | export default function App({ Component, pageProps }) { 18 | return ( 19 | 20 | 21 | 22 | 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /pages/excalidrawn.md: -------------------------------------------------------------------------------- 1 | # Excalidrawn 2 | 3 | ## PNG Drawing 4 | ![Excalidrawn PNG](/images/excalidrawn.png?600x460) 5 | ```markdown 6 | ![Excalidrawn PNG](/images/excalidrawn.png?600x460) 7 | ``` 8 | 9 | ## SVG Drawing 10 | ![Excalidrawn SVG](/images/excalidrawn.svg?300x230) 11 | ```markdown 12 | ![Excalidrawn SVG](/images/excalidrawn.svg?300x230) 13 | ``` 14 | 15 | Created using [Excalidraw](https://excalidraw.com/) 16 | 17 | -------------------------------------------------------------------------------- /pages/inbox.md: -------------------------------------------------------------------------------- 1 | # Inbox 2 | 3 | - Here you can write disorganised notes to be categorised later 4 | - Bullet points are useful, but it could be free form text as well 5 | - Sometimes it's better to just get things off your mind quickly, rather than stop to think where it belongs 6 | - But don't let this list get too long 7 | - Move information to more specific documents and link to them. 8 | - This helps you navigate between documents quickly 9 | - For example, you can `Cmd`+`Click` this: [[todo]] 10 | - Some notes don't end up making sense the next day 11 | - That's ok, you can just delete them! 12 | - You can always find them in your git history, if you really need it! 13 | 14 | 15 | 16 | [//begin]: # "Autogenerated link references for markdown compatibility" 17 | [todo]: todo "Todo" 18 | [//end]: # "Autogenerated link references" -------------------------------------------------------------------------------- /pages/index.md: -------------------------------------------------------------------------------- 1 | # Foamy NextJS 2 | 3 | ## Foam 4 | - [[readme]] 5 | - [[inbox]] 6 | - [[todo]] 7 | - For up-to-date tips, see [Foam Recipes](https://foambubble.github.io/foam/recipes/recipes) 8 | 9 | ## NextJS 10 | - [Learn NextJS](https://nextjs.org/learn/basics/create-nextjs-app) 11 | - [NextJS Examples](https://github.com/vercel/next.js/tree/canary/examples) 12 | 13 | ### Examples 14 | - [[syntax-highlighting]] 15 | - image in markdown [[excalidrawn]] 16 | - [[next-image-component-example]] 17 | - [[note]] in subfolder using remark footnotes 18 | - [[jsx-component-in-mdx-example]] 19 | 20 | 21 | 22 | [//begin]: # "Autogenerated link references for markdown compatibility" 23 | [readme]: readme "Foam" 24 | [inbox]: inbox "Inbox" 25 | [todo]: todo "Todo" 26 | [syntax-highlighting]: notes/syntax-highlighting "Syntax Highlighting" 27 | [excalidrawn]: excalidrawn "Excalidrawn" 28 | [next-image-component-example]: next-image-component-example "Next Image Component Example" 29 | [note]: notes/note "Note" 30 | [jsx-component-in-mdx-example]: jsx-component-in-mdx-example "JSX Component in Mdx Example" 31 | [//end]: # "Autogenerated link references" -------------------------------------------------------------------------------- /pages/jsx-component-in-mdx-example.md: -------------------------------------------------------------------------------- 1 | import Button from '../components/button.js' 2 | 3 | # JSX Component in Mdx Example 4 | 5 | Look, a button! 👇 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /pages/next-image-component-example.md: -------------------------------------------------------------------------------- 1 | # Next Image Component Example 2 | 3 | ## Markdown image syntax 4 | - Uses default options for `next/image` component. 5 | - `next/image` requires absolute paths for src 6 | - width and height is required 7 | - I set default dimensions, so `next/image` component won't throw an error, but it will distort your images if you don't provide image dimensions in the query string 8 | ```markdown 9 | ![Excalidrawn PNG](/images/excalidrawn.png?600x460) 10 | ``` 11 | **NOTE:** Markdown image syntax does not accept any other props in the query string. 12 | 13 | 14 | ## Custom JSX in MDX tag 15 | Example using `next/image` component via custom JSX in MDX tag `` 16 | 17 | Excalidrawn PNG 18 | 19 | ```jsx 20 | Excalidrawn PNG 21 | ``` 22 | Following props are accepted and its defaults in `` 23 | ```js 24 | let { 25 | src, 26 | alt, 27 | width = 600, 28 | height = 460, 29 | layout = 'intrinsic' } = props 30 | ``` 31 | 32 | **NOTE:** I decided not to support `layout='fill'` option because it's overly complicated for use in markdown content. I recommend importing `next/image` component and work with it directly since it requires wrapping a div container and tinkering with its style. 33 | 34 | If you don't want your images to be aligned center, you can change CSS styling for `.nextImageWrapper` in global.css 35 | 36 | If you want to customize your MDX components, you can find this code in `_app.js` 37 | ```js 38 | import Image from '../components/Image' 39 | 40 | const mdComponents = { 41 | a: props => , 42 | code: CodeBlock, 43 | img: (props) =>
, 44 | Image: (props) =>
45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /pages/notes/note.md: -------------------------------------------------------------------------------- 1 | # Note 2 | 3 | A note in subfolder 4 | 5 | `remark-numbered-footnote-labels` is a quality plugin[^quality]! 6 | 7 | I'm baby distillery squid cloud bread thundercats enamel pin mixtape scenester, poke raw denim. Tumblr stumptown hashtag beard. +1 vinyl master cleanse raclette shaman, hot chicken etsy pork belly forage chillwave you probably haven't heard of them salvia. Gastropub irony kickstarter PBR&B tofu salvia.[^hipsum] 8 | 9 | 10 | [^quality]: If you do not find it so, please file a GitHub issue or pull request! 11 | [^hipsum]: [Hipsum](https://hipsum.co/) 12 | -------------------------------------------------------------------------------- /pages/notes/syntax-highlighting.md: -------------------------------------------------------------------------------- 1 | # Syntax Highlighting 2 | 3 | Using the MDXProvider 4 | ```javascript 5 | // src/App.js 6 | import React from 'react' 7 | import {MDXProvider} from '@mdx-js/react' 8 | const components = { 9 | pre: props =>
, 10 | code: props =>
11 | }
12 | export default props => (
13 |   
14 |     
15 |
16 | ) 17 | ``` 18 | 19 | Source -> [MDXJS](https://mdxjs.com/guides/syntax-highlighting) -------------------------------------------------------------------------------- /pages/readme.md: -------------------------------------------------------------------------------- 1 | # Foam 2 | 3 | 👋 Welcome to your new Foam Workspace! 4 | 5 | ## Getting started 6 | 7 | This documentation assumes that you have a GitHub account and have [Visual Studio Code](https://code.visualstudio.com/) installed on your Linux/MacOS/Windows machine. 8 | 9 | 1. If you haven't yet, browse over to the main [Foam documentation workspace](https://foambubble.github.io/foam) to get an idea of what Foam is and how to use it. 10 | 2. Press "Use this template" button at [foam-template](https://github.com/foambubble/foam-template/generate) (that's this repository!) to fork it to your own GitHub account. If you want to keep your thoughts to yourself, remember to set the repository private. 11 | 3. [Clone the repository to your local machine](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository) and open it in VS Code. 12 | 13 | *Open the repository as a folder using the `File > Open...` menu item. In VS Code, "open workspace" refers to [multi-root workspaces](https://code.visualstudio.com/docs/editor/multi-root-workspaces).* 14 | 15 | 4. When prompted to install recommended extensions, click **Install all** (or **Show Recommendations** if you want to review and install them one by one) 16 | 17 | After setting up the repository, open [.vscode/settings.json](.vscode/settings.json) and edit, add or remove any settings you'd like for your Foam workspace. 18 | 19 | To learn more about how to use **Foam**, read the [Recipes](https://foambubble.github.io/foam/recipes) bubbles of the Foam documentation workspace. 20 | 21 | 22 | ## Using Foam 23 | 24 | We've created a few Bubbles (markdown documents) to get you started. 25 | 26 | - [[inbox]] - a place to write down quick notes to be categorised later 27 | - [[foam-tips]] - tips to get the most out of your Foam workspace 28 | - [[todo]] - a place to keep track of things to do 29 | 30 | ## Note on `[[wiki-links]]` 31 | 32 | ⚠️ Until [foambubble/foam#16](https://github.com/foambubble/foam/issues/16) is resolved, `[[wiki-links]]` links (like the links above) won't work in the GitHub Markdown preview (i.e. this Readme on github.com). 33 | 34 | They should work as expected in VS Code, and in rendered GitHub Pages. 35 | 36 | If GitHub preview (or general 100% support with all Markdown tools) is a requirement, for the time being you can use the standard `[description](page.md)` syntax. 37 | 38 | 39 | 40 | 41 | 42 | [//begin]: # "Autogenerated link references for markdown compatibility" 43 | [inbox]: inbox "Inbox" 44 | [todo]: todo "Todo" 45 | [//end]: # "Autogenerated link references" -------------------------------------------------------------------------------- /pages/todo.md: -------------------------------------------------------------------------------- 1 | # Todo 2 | 3 | - [x] This is an example of a todo list item that's complete 4 | - [x] Todo lists are useful for keeping organised and focused 5 | - [ ] This one is not completed yet 6 | - [ ] You can mark it completed by pressing `Option`+`C` (or `Alt`+`C`) when your cursor is on this line 7 | - [ ] You can also select multiple lines and mark them all at once! 8 | - [ ] When you press enter at the end of a line, it adds a new todo item on the next line 9 | - [ ] This, and more is provided by the [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) plugin by [Yu Zhang](https://github.com/yzhang-gh) 10 | -------------------------------------------------------------------------------- /public/images/excalidrawn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yenly/foamy-nextjs/3f6a1fc9d931a6852c26df102631a942a7c7aba9/public/images/excalidrawn.png -------------------------------------------------------------------------------- /public/images/excalidrawn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | FoamNextJSFoamy NextJS -------------------------------------------------------------------------------- /siteconfig.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "title": "Foamy NextJS", 3 | "description": "Digital Garden built with Foam and NextJS with MDX", 4 | "author": "Yenly Ma" 5 | } -------------------------------------------------------------------------------- /styles/global.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | /* begin gridlover perfect fourth scale */ 6 | html, .root { 7 | font-size: 18px; 8 | line-height: 27px; 9 | } 10 | body { 11 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, 12 | Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 13 | font-size: 1rem; 14 | line-height: 1.5rem; 15 | } 16 | h1, .h1 { 17 | font-size: 2.3888889rem; 18 | line-height: 3rem; 19 | margin-top: 1.5rem; 20 | margin-bottom: 3rem; 21 | } 22 | h2, .h2 { 23 | font-size: 1.7777778rem; 24 | line-height: 3rem; 25 | margin-top: 1.5rem; 26 | margin-bottom: 1.5rem; 27 | } 28 | h3, .h3 { 29 | font-size: 1.3333333rem; 30 | line-height: 1.5rem; 31 | margin-top: 1.5rem; 32 | margin-bottom: 0rem; 33 | } 34 | h4, .h4 { 35 | font-size: 1rem; 36 | line-height: 1.5rem; 37 | margin-top: 1.5rem; 38 | margin-bottom: 0rem; 39 | } 40 | h5, .h5 { 41 | font-size: 1rem; 42 | line-height: 1.5rem; 43 | margin-top: 1.5rem; 44 | margin-bottom: 0rem; 45 | } 46 | p, ul, ol, pre, table, blockquote { 47 | margin-top: 0rem; 48 | margin-bottom: 1.5rem; 49 | } 50 | ul ul, ol ol, ul ol, ol ul { 51 | margin-top: 0rem; 52 | margin-bottom: 0rem; 53 | } 54 | 55 | /* Let's make sure all's aligned */ 56 | hr, .hr { 57 | border: 1px solid; 58 | margin: -1px 0; 59 | } 60 | a, b, i, strong, em, small, code { 61 | line-height: 0; 62 | } 63 | sub, sup { 64 | line-height: 0; 65 | position: relative; 66 | vertical-align: baseline; 67 | } 68 | sup { 69 | top: -0.5em; 70 | } 71 | sub { 72 | bottom: -0.25em; 73 | } 74 | /* end gridlover perfect fourth scale */ 75 | 76 | .container { 77 | max-width: 680px; 78 | margin: auto; 79 | } 80 | 81 | .contains-task-list { 82 | list-style-type: none; 83 | } 84 | 85 | .task-list-item input { 86 | margin-left: -20px; 87 | } 88 | 89 | pre { 90 | font-size: 0.80rem; 91 | } 92 | 93 | a { 94 | color: #0070f3; 95 | text-decoration: none; 96 | } 97 | 98 | a:hover { 99 | text-decoration: underline; 100 | } 101 | 102 | /* img { 103 | max-width: 100%; 104 | display: block; 105 | } */ 106 | 107 | .nextImageWrapper { 108 | text-align: center; 109 | } 110 | 111 | .footnotes { 112 | font-size: 0.8rem; 113 | line-height: 1.25rem; 114 | } -------------------------------------------------------------------------------- /styles/prism-theme-night-owl.css: -------------------------------------------------------------------------------- 1 | code[class*="language-"], 2 | pre[class*="language-"] { 3 | color: #d6deeb; 4 | font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; 5 | text-align: left; 6 | white-space: pre; 7 | word-spacing: normal; 8 | word-break: normal; 9 | word-wrap: normal; 10 | line-height: 1.5; 11 | 12 | -moz-tab-size: 4; 13 | -o-tab-size: 4; 14 | tab-size: 4; 15 | 16 | -webkit-hyphens: none; 17 | -moz-hyphens: none; 18 | -ms-hyphens: none; 19 | hyphens: none; 20 | } 21 | 22 | pre[class*="language-"]::-moz-selection, 23 | pre[class*="language-"] ::-moz-selection, 24 | code[class*="language-"]::-moz-selection, 25 | code[class*="language-"] ::-moz-selection { 26 | text-shadow: none; 27 | background: rgba(29, 59, 83, 0.99); 28 | } 29 | 30 | pre[class*="language-"]::selection, 31 | pre[class*="language-"] ::selection, 32 | code[class*="language-"]::selection, 33 | code[class*="language-"] ::selection { 34 | text-shadow: none; 35 | background: rgba(29, 59, 83, 0.99); 36 | } 37 | 38 | @media print { 39 | code[class*="language-"], 40 | pre[class*="language-"] { 41 | text-shadow: none; 42 | } 43 | } 44 | 45 | /* Code blocks */ 46 | pre[class*="language-"] { 47 | padding: 1em; 48 | margin: 0.5em 0; 49 | overflow: auto; 50 | } 51 | 52 | :not(pre) > code[class*="language-"], 53 | pre[class*="language-"] { 54 | color: white; 55 | background: #011627; 56 | } 57 | 58 | :not(pre) > code[class*="language-"] { 59 | padding: 0.1em; 60 | border-radius: 0.3em; 61 | white-space: normal; 62 | } 63 | 64 | .token.comment, 65 | .token.prolog, 66 | .token.cdata { 67 | color: rgb(99, 119, 119); 68 | font-style: italic; 69 | } 70 | 71 | .token.punctuation { 72 | color: rgb(199, 146, 234); 73 | } 74 | 75 | .namespace { 76 | color: rgb(178, 204, 214); 77 | } 78 | 79 | .token.deleted { 80 | color: rgba(239, 83, 80, 0.56); 81 | font-style: italic; 82 | } 83 | 84 | .token.symbol, 85 | .token.property { 86 | color: rgb(128, 203, 196); 87 | } 88 | 89 | .token.tag, 90 | .token.operator, 91 | .token.keyword { 92 | color: rgb(127, 219, 202); 93 | } 94 | 95 | .token.boolean { 96 | color: rgb(255, 88, 116); 97 | } 98 | 99 | .token.number { 100 | color: rgb(247, 140, 108); 101 | } 102 | 103 | .token.constant, 104 | .token.function, 105 | .token.builtin, 106 | .token.char { 107 | color: rgb(130, 170, 255); 108 | } 109 | 110 | .token.selector, 111 | .token.doctype { 112 | color: rgb(199, 146, 234); 113 | font-style: italic; 114 | } 115 | 116 | .token.attr-name, 117 | .token.inserted { 118 | color: rgb(173, 219, 103); 119 | font-style: italic; 120 | } 121 | 122 | .token.string, 123 | .token.url, 124 | .token.entity, 125 | .language-css .token.string, 126 | .style .token.string { 127 | color: rgb(173, 219, 103); 128 | } 129 | 130 | .token.class-name, 131 | .token.atrule, 132 | .token.attr-value { 133 | color: rgb(255, 203, 139); 134 | } 135 | 136 | .token.regex, 137 | .token.important, 138 | .token.variable { 139 | color: rgb(214, 222, 235); 140 | } 141 | 142 | .token.important, 143 | .token.bold { 144 | font-weight: bold; 145 | } 146 | 147 | .token.italic { 148 | font-style: italic; 149 | } 150 | --------------------------------------------------------------------------------