fix(markdown): make sure code/inline-code are not messed up
+ 54
- 81
app/components/Code.tsx
@@ -25,7 +25,10 @@ export const Code: VFC<CodeProps & WithThemeSchemeProp> = ({
 }) => {
   const innerHtml = useMemo(
     () => ({
-      __html: Prism.highlight(code, Prism.languages[language], language),
+      __html:
+        language in Prism.languages
+          ? Prism.highlight(code, Prism.languages[language], language)
+          : Prism.highlight(code, Prism.languages["sh"], language),
     }),
     [code, language]
   );

...
@@ -35,9 +38,12 @@ export const Code: VFC<CodeProps & WithThemeSchemeProp> = ({
     <StylePreTag
       data-language={language}
       className={` language-${language} line-numbers`}
-      themeScheme={themeScheme}
     >
-      <StyledCodeTag {...props} dangerouslySetInnerHTML={innerHtml} />
+      <StyledCodeTag
+        {...props}
+        dangerouslySetInnerHTML={innerHtml}
+        themeScheme={themeScheme}
+      />
     </StylePreTag>
   );
 };

...
@@ -49,27 +55,28 @@ export const getThemedCodeCss = (themeScheme: AppThemeScheme): JSX.Element =>
     <style>{`code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;text-shadow:0 -.1em .2em #000;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}:not(pre)>code[class*=language-],pre[class*=language-]{background:#4c3f33}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border:.3em solid #7a6651;border-radius:.5em;box-shadow:1px 1px .5em #000 inset}:not(pre)>code[class*=language-]{padding:.15em .2em .05em;border-radius:.3em;border:.13em solid #7a6651;box-shadow:1px 1px .3em -.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`}</style>
   );
 
-const StylePreTag = styled.pre<WithThemeSchemeProp>`
+const StylePreTag = styled.pre`
   width: 100%;
+  margin: 0 !important;
+  padding: 0 !important;
 
-  border-radius: 8px !important;
   box-shadow: none !important;
   text-shadow: none !important;
-
-  ${({ themeScheme }) => css`
-    background-color: ${NamedColors.CARD[themeScheme]} !important;
-    border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]} !important;
-  `};
 `;
 
-const StyledCodeTag = styled.code`
+export const StyledCodeTag = styled.code<WithThemeSchemeProp>`
   display: block;
 
   min-height: 20px;
   width: 100%;
-  padding: 2px 4px;
+  padding: 4px 8px;
 
   font-size: 16px;
   white-space: break-spaces;
-  border: none;
+  border-radius: 4px !important;
+
+  ${({ themeScheme }) => css`
+    background-color: ${NamedColors.CARD[themeScheme]} !important;
+    border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]} !important;
+  `};
 `;

app/components/MarkdownToJsx.tsx
@@ -2,10 +2,10 @@
 import React, { useMemo, VFC } from "react";
 import { compiler as markdownToJsxCompiler } from "markdown-to-jsx";
 import styled, { css } from "styled-components";
-import Prism from "prismjs";
 // app
 import type { AppThemeScheme, WithThemeSchemeProp } from "../types";
 import { Card } from "./Card.styled";
+import { Code, getThemedCodeCss, StyledCodeTag } from "./Code";
 import { NamedColors } from "../utils/style";
 
 type MarkdownToJsxProps = {

...
@@ -49,32 +49,25 @@ export const MarkdownToJsx: VFC<MarkdownToJsxProps> = ({
               {children}
             </StyledBlockquoteCard>
           ),
-          code: ({ className, children: code, ...props }) => {
-            const language = (className || "lang-plaintext").replace(
-              "lang-",
-              ""
-            );
-            const html =
-              language in Prism.languages
-                ? Prism.highlight(code, Prism.languages[language], language)
-                : code;
-            return (
-              <pre data-language={language} className={` language-${language}`}>
-                <StyledCodeTag
-                  {...props}
+          pre: ({ children, ...props }) => {
+            if ("type" in children && children["type"] === "code") {
+              const { className, children: code } = children["props"];
+              const language = (className || "lang-plaintext").replace(
+                "lang-",
+                ""
+              );
+              return (
+                <Code
+                  code={code}
+                  language={language}
                   themeScheme={themeScheme}
-                  dangerouslySetInnerHTML={{
-                    __html: html,
-                  }}
                 />
-              </pre>
-            );
-          },
-          pre: ({ children, ...props }) => {
+              );
+            }
             return (
-              <StyledCodeBlock {...props} themeScheme={themeScheme}>
+              <StyledCodeTag {...props} themeScheme={themeScheme}>
                 {children}
-              </StyledCodeBlock>
+              </StyledCodeTag>
             );
           },
           ul: ({ children, ...props }) => (

...
@@ -130,14 +123,16 @@ export const MarkdownToJsx: VFC<MarkdownToJsxProps> = ({
   );
 
   return (
-    <StyledMarkdownContainer className={"md"}>
+    <StyledMarkdownContainer className={"md"} themeScheme={themeScheme}>
+      {getThemedCodeCss(themeScheme)}
       <MarkdownElements />
     </StyledMarkdownContainer>
   );
 };
 
-const StyledMarkdownContainer = styled.div`
+const StyledMarkdownContainer = styled.div<WithThemeSchemeProp>`
   width: 100%;
+  max-width: 100%;
 
   font-size: 18px;
   line-height: 26px;

...
@@ -158,6 +153,20 @@ const StyledMarkdownContainer = styled.div`
   & > p:first-child {
     margin-top: 0 !important;
   }
+
+  & code {
+    min-height: 20px;
+    padding: 2px 4px;
+
+    font-size: 16px;
+    white-space: break-spaces;
+    border-radius: 4px !important;
+
+    ${({ themeScheme }) => css`
+      background-color: ${NamedColors.CARD[themeScheme]} !important;
+      border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]} !important;
+    `};
+  }
 `;
 
 const StyledAnchor = styled.a<WithThemeSchemeProp>`

...
@@ -214,46 +223,3 @@ const StyledBlockquoteCard = styled(Card)<WithThemeSchemeProp>`
     margin-top: 0 !important;
   }
 `;
-
-const codeElBaseCss = css<WithThemeSchemeProp>`
-  border-radius: 4px;
-  font-size: 16px;
-  line-height: 16px;
-  white-space: break-spaces;
-`;
-
-const StyledCodeTag = styled.code<WithThemeSchemeProp>`
-  min-height: 20px;
-  padding: 2px 4px;
-
-  ${codeElBaseCss};
-
-  ${({ themeScheme }) => css`
-    background-color: ${NamedColors.CARD[themeScheme]};
-    border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
-  `};
-`;
-
-const StyledCodeBlock = styled.pre<WithThemeSchemeProp>`
-  min-width: 100%;
-  width: 100%;
-  max-width: 100%;
-
-  padding: 8px 12px;
-
-  ${codeElBaseCss};
-
-  ${({ themeScheme }) => css`
-    background-color: ${NamedColors.CARD[themeScheme]};
-    border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
-  `};
-
-  & > code {
-    width: 100%;
-    padding: 0 !important;
-    background-color: transparent !important;
-    border-radius: 0 !important;
-    border: unset !important;
-    line-height: 26px;
-  }
-`;