memd-cli 3.4.0 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)"
5
+ ]
6
+ }
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memd-cli",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "type": "module",
5
5
  "main": "main.js",
6
6
  "bin": {
package/render-shared.js CHANGED
@@ -3,7 +3,7 @@ import { Marked } from 'marked';
3
3
  import { renderMermaidSVG } from '@ktrysmt/beautiful-mermaid';
4
4
  import { escapeHtml, resolveThemeColors } from './render-utils.js';
5
5
 
6
- export const WIDTH_TOGGLE_SCRIPT = "(function(){var b=document.body,btn=document.querySelector('.memd-width-toggle');if(!btn)return;var sb=document.querySelector('.memd-sidebar');if(sb){sb.insertBefore(btn,sb.firstChild);btn.style.position='static';btn.style.margin='0 0 0.5rem 0';btn.style.width='100%'}function u(){btn.textContent=b.classList.contains('memd-full-width')?'Full':'Smart'}if(localStorage.getItem('memd-width')==='full')b.classList.add('memd-full-width');u();btn.onclick=function(){b.classList.toggle('memd-full-width');localStorage.setItem('memd-width',b.classList.contains('memd-full-width')?'full':'smart');u()}})();";
6
+ export const WIDTH_TOGGLE_SCRIPT = "(function(){var b=document.body,g=document.querySelector('.memd-width-toggle');if(!g)return;var sb=document.querySelector('.memd-sidebar');if(sb){sb.insertBefore(g,sb.firstChild);g.style.position='static';g.style.margin='0 0 0.5rem 0';g.style.width='auto'}var btns=g.querySelectorAll('.memd-wt-btn');function u(){var f=b.classList.contains('memd-full-width');btns.forEach(function(n){n.classList.toggle('active',n.dataset.mode===(f?'full':'smart'))})}if(localStorage.getItem('memd-width')==='full')b.classList.add('memd-full-width');u();btns.forEach(function(n){n.onclick=function(){if(n.dataset.mode==='full'){b.classList.add('memd-full-width');localStorage.setItem('memd-width','full')}else{b.classList.remove('memd-full-width');localStorage.setItem('memd-width','smart')}u()}})})();";
7
7
 
8
8
  export const MERMAID_MODAL_SCRIPT = [
9
9
  "document.addEventListener('click',function(e){var d=e.target.closest('.mermaid-diagram');if(d){var o=document.createElement('div');o.className='mermaid-modal';o.innerHTML=d.querySelector('svg').outerHTML;o.onclick=function(){o.remove()};document.body.appendChild(o)}});",
@@ -72,8 +72,12 @@ body { background: ${t.bg}; color: ${t.fg}; font-family: system-ui, -apple-syste
72
72
  @media (max-width: 1024px) { body { max-width: 85%; } }
73
73
  @media (max-width: 768px) { body { max-width: 100%; } }
74
74
  body.memd-full-width { max-width: none; margin: 0; }
75
- .memd-width-toggle { position: fixed; top: 0.5rem; left: 0.5rem; z-index: 11; background: color-mix(in srgb, ${t.fg} 8%, ${t.bg}); border: 1px solid ${t.line}; color: ${t.muted}; padding: 0.2rem 0.6rem; cursor: pointer; border-radius: 4px; font-size: 0.75rem; }
76
- .memd-width-toggle:hover { background: color-mix(in srgb, ${t.fg} 15%, ${t.bg}); }
75
+ .memd-width-toggle { position: fixed; top: 0.5rem; left: 0.5rem; z-index: 11; display: inline-flex; border-radius: 6px; overflow: hidden; border: 1px solid ${t.line}; font-size: 0; }
76
+ .memd-wt-btn { background: color-mix(in srgb, ${t.fg} 5%, ${t.bg}); border: none; color: ${t.muted}; padding: 0.25rem 0.5rem; cursor: pointer; font-size: 0.7rem; display: inline-flex; align-items: center; gap: 0.25rem; line-height: 1; }
77
+ .memd-wt-btn + .memd-wt-btn { border-left: 1px solid ${t.line}; }
78
+ .memd-wt-btn:hover { background: color-mix(in srgb, ${t.fg} 12%, ${t.bg}); }
79
+ .memd-wt-btn.active { background: color-mix(in srgb, ${t.accent} 18%, ${t.bg}); color: ${t.accent}; }
80
+ .memd-wt-btn svg { width: 12px; height: 12px; flex-shrink: 0; }
77
81
  a { color: ${t.accent}; }
78
82
  hr { border-color: ${t.line}; }
79
83
  blockquote { border-left: 3px solid ${t.line}; color: ${t.muted}; padding-left: 1rem; }
@@ -92,7 +96,7 @@ th { background: color-mix(in srgb, ${t.fg} 5%, ${t.bg}); }
92
96
  <!--memd:head-->
93
97
  </head>
94
98
  <body>
95
- <button class="memd-width-toggle" aria-label="Toggle width"></button>
99
+ <div class="memd-width-toggle" role="group" aria-label="Width toggle"><button class="memd-wt-btn" data-mode="smart"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1 8h5m4 0h5"/><path d="M4 5l3 3-3 3m8-6l-3 3 3 3"/></svg>Smart</button><button class="memd-wt-btn" data-mode="full"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M1 8h14"/><path d="M4 5L1 8l3 3m8-6l3 3-3 3"/></svg>Full</button></div>
96
100
  <!--memd:content-->
97
101
  ${body.trimEnd()}
98
102
  <!--/memd:content-->
package/test/memd.test.js CHANGED
@@ -200,6 +200,20 @@ describe('memd CLI', () => {
200
200
  expect(output).toMatch(/id="m1-/)
201
201
  })
202
202
 
203
+ it('--html contains segmented width toggle with Smart/Full buttons', () => {
204
+ const output = runSync(['--html', 'test/test1.md'])
205
+ // Segmented toggle container
206
+ expect(output).toContain('class="memd-width-toggle"')
207
+ // Two buttons with data-mode attributes
208
+ expect(output).toContain('class="memd-wt-btn" data-mode="smart"')
209
+ expect(output).toContain('class="memd-wt-btn" data-mode="full"')
210
+ // SVG icons present in each button
211
+ const btnMatches = output.match(/memd-wt-btn/g)
212
+ expect(btnMatches.length).toBeGreaterThanOrEqual(4) // 2 in HTML + 2+ in CSS
213
+ // Toggle script sets active class
214
+ expect(output).toContain("classList.toggle('active'")
215
+ })
216
+
203
217
  it('--html + multiple files -> combined single HTML', () => {
204
218
  const output = runSync(['--html', 'test/test1.md', 'test/test2.md'])
205
219
  expect(output).toContain('<!DOCTYPE html>')