- prebuild.
25 KiB
�« : ⥪áâ®¢ë© Markdown viewer ¤«ï Sprinter (examples/mdview)
Context
’¥á⮢ ï ªàã¯ ï § ¤ ç - ¯à®¢¥à¨âì èã libc ¥âਢ¨ «ì®¬ interactive-¯à¨«®¦¥¨¨ (¯®«®íªà ë© UI, ä ©«®¢ë© I/O, ¯ àá¥à). � à ««¥«ì® ¤ áâ å®à®è¨© showcase ¯« âä®à¬ë ¨ ¯®¬®¦¥â ¢ëâ é¨âì ¥¤®¤¥«ª¨ ¢ conio/io. Š®¥ç ï æ¥«ì: viewer ¤«ï .md ä ©«®¢ á ¯®¤á¢¥âª®© á¨â ªá¨á , ¢¨£ 樥© ¯® ⥪áâã ¨ ¯®áâà ¨çë¬ áªà®««¨£®¬.
Ž£à ¨ç¥¨ï v1 (§ 䨪á¨à®¢ ë ¯®«ì§®¢ ⥫¥¬):
- POSIX file API (open/read/lseek/close); FILE pointer / fread / fgets - ¥ ¨á¯®«ì§®¢ âì
- �®¤á¢¥âª ç¥à¥§ 梥â: **à §¬¥à § £®«®¢ª ** -> 梥â èà¨äâ ; bold/italic -> 梥â ä® (¬®®è¨à¨ë© ä®â ¡¥§ ¦¨à®£®/ªãàᨢ®£® ç¥àâ ¨ï)
� áè¨à¥¨ï, ॠ«¨§®¢ ë¥ ¯®á«¥ ¯« :
- ” ©«ë ¤® 128 KB (1-8 EMM-áâà ¨æ, lazy map ¢ W3 ç¥à¥§
fb()/map_page()) - ¨§ ç «ì® ¡ë«® ¢ v2 - €¨¬¨à®¢ ë© spinner ¨ ¯à¥¤¢ à¨â¥«ì ï ®âà¨á®¢ª UI ¯à¨ áâ à⥠- UX
- Inline emphasis:
_/*/**¯®¤ç¨ïîâáï XOR flanking-¯à ¢¨«ã (whitespace ஢® á ®¤®© áâ®à®ë),COLOR_YELLOW¨2 * 3®áâ îâáï «¨â¥à « ¬¨
’¥ªã騩 áâ âãá (2026-06-05)
| Phase | ‘â âãá | Š®¬¬¥â ਩ |
|---|---|---|
| 1 Plain text + nav | § £à㧪 , ¨¤¥ªá æ¨ï, status/menu, ^V/PgUp/PgDn/Home/End/F1/F10/Esc | |
| 2 Headers + HR | H1..H4, ---/***/___ (á >=3 marker'®¢) |
|
| 3 Inline emphasis | ** / * / _ / `; XOR flanking (á¬. ¢ëè¥) |
|
| 4 Lists / quote / fenced code | - / * / +, N. / N), > , ```; light nested lists |
|
| 4-tables | â ¡«¨æë ®â«®¦¥ë ¢¬¥á⥠á Phase 6 | |
| 5 Wrap / Unwrap (F2) | wrap-by-default; soft wrap; F2 ¯¥à¥ª«îç ¥â; hpan <-/-> ¢ truncate-०¨¬¥ | |
| 6 �®«ë© layout â ¡«¨æ | deferred | |
| 7 Links + search | deferred | |
| 8 F8 Raw toggle | deferred | |
| Cache ।¥à¥ëå áâப | ¥ 㦮 ¯® ᪮à®á⨠|
UX-¯®¯à ¢ª¨ (®â¤¥«ì® ®â phase-¯« , 2026-06-05):
- UI (menu + title bar) ®âà¨á®¢ë¢ ¥âáï „Ž
load_file/index_lines- ¯®«ì§®¢ ⥫ì áà §ã ¢¨¤¨â ¨â¥à䥩á, ¥ çñàë© íªà - Title bar:
MDVIEW <spinner> <filename>(3 ¯à®¡¥« ¬¥¦¤ã MDVIEW ¨ filename, slot ᯨ¥à - col 8) - Spinner ªàãâ¨âáï ¢® ¢à¥¬ï
load_file(¯® áâà ¨æ¥) ¨index_lines(à § ¢ 32 «®£¨ç¥áª¨å áâப¨), ¢ª«îç ïtoggle_wrap
€àå¨â¥ªâãà
� ᪫ ¤ª íªà (80x32, ⥪áâ mode 0x03)
Row 0: MDVIEW ³ mdview.md ³ L 1-30 / 142 ³ 21% <- status bar (BG=blue, FG=white)
³ ÀÄÄ filename @ col 10
ÀÄÄÄÄÄÄÄÄÄÄ spinner slot @ col 8 (anim. while busy)
Row 1:
... document viewport (30 rows)
Row 30:
Row 31: F1 Help F2 Wrap F10 Exit <- menu bar (BG=blue, FG=cyan)
- Viewport = 30 áâப x 80 á⮫¡æ®¢.
- Status / menu ।¥àïâáï ç¥à¥§
wrchar()(¡¥§ ¢â®-áªà®«« ), viewport - ç¥à¥§LOCATE+ ¯®á¨¬¢®«ìë©wrchar()(⮦¥ ¡¥§ ¢â®-áªà®«« , áâ ¢¨â ¨ char ¨ attr § ®¤¨ call).
� ¬ïâì
Memory mode: small - DSS ®â¢®¤¨â ¯®¤ è ®¡à § ¤¢ ¡ ª (W1 + W2) = 32 KB á㬬 à® (CODE ¢ W1, DATA + STACK + HEAP ¢ W2). �⮣® ¤®«¦® å¢ â¨âì ç⮡ë �… § ¢®¤¨âì __banked äãªæ¨¨. W3 ®áâ ñâáï ¯®«®áâìî ᢮¡®¤ë¬ ¤«ï ¬ ¯¯¨£ ¡®«ìè¨å ¡ãä¥à®¢:
W0 (0x0000-0x3FFF): ESTEX (system, untouchable)
W1 (0x4000-0x7FFF): CODE (small mode page 1)
W2 (0x8000-0xBFFF): DATA + STACK + HEAP (small mode page 2)
W3 (0xC000-0xFFFF): paged window - «¥¨¢® ¯¥à¥ª«îç ¥âáï ¬¥¦¤ã EMM-áâà ¨æ ¬¨
ä ©« (¤® 8 áâà ¨æ = 128 KB). `cur_page` ªíè¨àã¥â
⥪ãéãî mapping, `fb(p)` ¬ ¯¯¨â ã¦ãî áâà ¨æã ¯à¨
¯¥à¢®¬ ®¡à 饨¨.
�®ç¥¬ã small + W3:
- 32 KB ª®¤+¤ ë¥ á ¡®«ì訬 § ¯ ᮬ -> ¥â ¡ ª¨£
- W3 - áâ ¤ àâë© paged window, ¯®¤ ¥£® ã á 㦥 ¥áâì
bank_io_w3API - ” ©«ë ¤® 128 KB ¯®¤¤¥à¦¨¢ îâáï ⨢®:
mem_alloc_pages(pages_needed)¯®¤ ¢¥áì ä ©«;map_page()ç¥à¥§sprinter_page_w3();fb(p)- ¥¤¨ ï â®çª ¤®áâ㯠¨§ ¨¤¥ªá â®à ¨ ।¥à .
‘â ⨪¨ (¢ W2):
line_offset[MAX_LINES]- uint16_t ᬥ饨¥ ª ¦¤®© áâப¨ ¢ ä ©«®¢®© áâà ¨æ¥ (4 KB 2048 áâப)cache_tag[CACHE_N]- uint16_t ⥣ á«®â (200 ¡ ©â 100 ᫮⮢, ¯®ï¢«ï¥âáï ¢ Phase 3)filename[64],top_line,total_lines,file_size,file_blk,cache_blk- ¥¤¨¨æë ¡ ©â
FILE_BUF: ((char*)0xC000) - 䨪á¨à®¢ ï ¤à¥á æ¨ï ¢ W3 ¯®á«¥ ¬ ¯¯¨£ 㦮© áâà ¨æë.
�®â®ª ¤ ëå
main -> open() -> read() chunks 1KB -> write to W1 (mapped EMM page) -> close()
-> index_lines() (®¤® ᪠¨à®¢ ¨¥, § ¯®«ï¥â line_offset[])
-> render_viewport() + main loop { getkey(); handle(); render_status(); render_viewport() }
’®ª®áâì á read(): ESTEX READ § ¯¨áë¢ ¥â ¯® dst-㪠§ â¥«î ¢ ¤à¥á®¬ ¯à®áâà á⢥ ¢ë§ë¢ î饣®. �®áª®«ìªã ¬ë ¬ ¯¯¨¬ EMM-áâà ¨æã ¢ W3 (0xC000) „Ž ¢ë§®¢ read(), 㪠§ ⥫ì 0xC000+offset ¢ «¨¤¥. …᫨ ¢ëïá¨âáï çâ® BIOS âண ¥â W3 ¢® ¢à¥¬ï read (£à ä¨ç¥áª¨© ¢¨¤¥®¡ãä¥à ¯® 㬮«ç ¨î ¢ W3 ¯à¨ £à ä¨ç¥áª¨å ०¨¬ å, ® ¢ ⥪á⮢®¬ - ¤®«¦¥ ¡ëâì ᢮¡®¤¥) - fallback: ç¨â âì ¢ 1 KB ¡ãä¥à ¢ W2 ¨ ª®¯¨à®¢ âì ¢ W3 ç¥à¥§ bank_write_w3().
�¥ «¨§ æ¨ï - ¯®íâ ¯ ï
Phase 1 - Plain text viewer (MVP)
—â® à ¡®â ¥â:
- ‡ £à㧪 ä ©« (
open/read/close) ¢ W1-áâà ¨æã - ˆ¤¥ªá æ¨ï áâப (LF / CRLF à §¤¥«¨â¥«¨)
- Status bar: ¨¬ï ä ©« , L N-M / Total, ¯à®æ¥â áªà®««¨£
- Menu bar:
F1 Help F10 Exit - � ¢¨£ æ¨ï: ^/V (1 áâப ), PgUp/PgDn (30 áâப), Home/End ( ç «®/ª®¥æ), Esc/F10 (¢ë室), F1 (help screen)
- Ž¡à¥§ª áâப ¤«¨¥¥ 80 ᨬ¢®«®¢ (¡¥§ word-wrap)
- –¢¥â : ⥪áâ ¡¥«ë© çñ஬; status/menu - ¡¥«ë© ᨥ¬
Šà¨â¨çë¥ ä ©«ë:
examples/mdview/mdview.c- main, key loop, rendering, indexing (one-file MVP)examples/mdview/Makefileexamples/mdview/SAMPLE.MD- â¥áâ®¢ë© markdown ä ©«
Phase 2 - Headers ¨ £®à¨§®â «ì ï «¨¨ï
MD ä¨ç¨:
# H1-> ïમ-¦ñ«âë© (COLOR_YELLOW = 14) çñ஬## H2-> ïમ-£®«ã¡®© (COLOR_LBLUE = 11)### H3-> ïમ-§¥«ñë© (COLOR_LGREEN = 10)#### H4+-> á¥àë© (COLOR_GREY = 8)---/*** ®â¤¥«ì®© áâப¥ -> «¨¨ï 0xC4 (£®à¨§®â «ì ï à ¬ª ASCII) ¢® ¢áî è¨à¨ã
Phase 3 - Inline emphasis
� àá¥à inline (per-line, runs ¢ ®¤ã áâபã):
**bold**-> ATTR_TEXT_BOLD*italic*-> ATTR_TEXT_ITALIC_underscore_-> ATTR_TEXT_UNDERSORE`code`-> ATTR_TEXT_CODE- Œ થàë
**/*/_/`�… ।¥àïâáï (áꥤ îâáï)
State machine: ®¤¨ ªâ¨¢ë© áâ¨«ì ®¤®¢à¥¬¥® (¡¥§ ¢«®¦¥®áâ¨); ª®ä«¨ªâãî騩 ¬ àª¥à ¯à¨ ç㦮¬ ªâ¨¢®¬ á⨫¥ ¢áñ à ¢® ª®áìâáï (zero-width) ¤«ï á¨åந§ 樨 è¨à¨ë á index_lines. ‘®áâ®ï¨¥ á¡à áë¢ ¥âáï ª ¦¤®© áâப¥.
Flanking-¯à ¢¨«® (CommonMark intraword, ॠ«¨§®¢ ® ¯®á«¥ ¨§ ç «ì®£® ¯« ):
*/**/_áç¨â îâáï markdown-¬ થ஬ ⮫쪮 ¥á«¨ whitespace/EOL ஢® á Ž„�މ áâ®à®ë (XOR).- ‘«ãç ¨ "®¡ whitespace" (
2 * 3,2 ** 3) -> «¨â¥à «ë ( à¨ä¬¥â¨ª ). - ‘«ãç ¨ "¨ ®¤®£® whitespace" (
COLOR_YELLOW,FILE*/fread,foo*bar*baz) -> «¨â¥à «ë (intraword). - Backtick (
`) flanking �… âॡã¥â -`code`à ¡®â ¥â ¡¥§ ¯à®¡¥«®¢. - �à ¢¨«® ¯à¨¬¥¥® ᨬ¬¥âà¨ç® ¢ 4 ¬¥áâ å (
index_lines, cont-render, ®á®¢®© inline-¯ àá¥à, truncation peek), ¨ ç¥ wrap-¨¤¥ªá â®à ¨ ।¥à à §ê¥¤ãâáï ¯® è¨à¨¥.
Šíè ®âä®à¬ â¨à®¢ ëå áâப - ®â«®¦¥ ¢ á ¬ë© ª®¥æ, á¬. "Phase : ®¯â¨¬¨§ 樨". ‘ª®à®á⨠⥪ã饣® ¨¢®£® ।¥à å¢ â ¥â 80x30 = 2400 wrchar / ª ¤à; PgUp/PgDn ¢¨§ã «ì® ¬£®¢¥¥.
Phase 4 - Block elements (¡¥§ â ¡«¨æ)
- Œ ન஢ ë¥ á¯¨áª¨:
- foo,* foo,+ foo-> ¯à¥ä¨ªáo(0x07) + ¯à®¡¥«; 梥⠬ થà ïàç¥ ®á®¢®£® - �㬥஢ ë¥ á¯¨áª¨:
1. foo,2. foo-> ª ª ¥áâì (ç¨á«® ®áâ ¢«ï¥¬) - Blockquote: áâப¨ á
>-> ¯à¥ä¨ªá³(0xB3) á¥à®£® 梥â , ®á⠫쮩 ⥪áâ á«¥£ª ¯à¨£«ãèñë© - Fenced code blocks:
```®âªàë¢ ¥â/§ ªàë¢ ¥â ¡«®ª; ¢á¥ áâப¨ ¬¥¦¤ã - bg=á¥àë©, ¬®®è¨à¨® (¡¥§ inline-¯ àᨣ ) - Indented code blocks (4+ ¯à®¡¥«®¢): «®£¨ç® fenced, ® ¡¥§ £® ¬ થà
Light nested lists (v1 - ॠ«¨§®¢ ®):
classify_line()¯à®¯ã᪠¥â leading spaces ¯¥à¥¤ ulist/olist/quote ¬ થ஬, ¢®§¢à é ¥âcontent_off¯®á«¥ ¬ થà ->content_off - p_start= indent + marker ¡¨â ¢ visible col.render_line()à¨áã¥â leading-spaces ¢ATTR_TEXT, ¯®â®¬ ¬ થà ᤢ¨ã⮩ ¯®§¨æ¨¨ (col = indent). Marker ¢áñ ¥éñ 䨪á¨à®¢ ¯à¨ £®à¨§®â «ì®¬ pan'¥.- HR / header / fence delim ®áâ îâáï áâண® col-0 (CommonMark à §à¥è ¥â ¤® 3 ¢¥¤ãé¨å ¯à®¡¥«®¢ ¤«ï ¨å - ã¯à®á⨫¨).
- Tab-indent -> ¥ à ᯮ§ ñâáï ª ª nesting (⮫쪮 spaces).
Phase 4-full - ¯®« ï ¯®¤¤¥à¦ª ¢«®¦¥®á⨠(deferred):
- Tab-indent: áç¨â âì tab = 4 ¯à®¡¥« ¤«ï ®¯à¥¤¥«¥¨ï ã஢ï.
- Quote nesting (
> > foo): ª ¦¤ë©>¯®¤àï¤ = +1 ã஢¥ì, ª ¦¤ë© à¨áã¥âáï ®â¤¥«ì묳¢ATTR_QUOTE_MARKER(¢¨§ã «ì ï "«¥áâ¨æ " á«¥¢ ). - Hanging indent ¢ wrap-continuation: ª®£¤
- some very long bullet text that wraps...- continuation seg ¤®«¦¥ ç¨ âìáï ®â content-col (¯®á«¥ ¬ થà ), ¥ ®â col 0. ‘¥©ç á continuation ¨¤ñâ ®â col 0 (v1 simplification). ’ॡã¥â åà ¨âìmarker_widthper «®£¨ç¥áª ï áâப (8 ¡¨â) ¨«¨ re-classify first seg ¯à¨ ।¥à¥ continuation. - Lazy continuation: áâப¨ ¡¥§ ¬ થà , ® á ¯à ¢¨«ìë¬ indent ¯®¤ ¯à¥¤ë¤ã騬 bullet'®¬, ¤®«¦ë áç¨â âìáï ¯à®¤®«¦¥¨¥¬ ⮣® bullet' (¢¨§ã «ì® - ®¡é¨© attr).
- Strict CommonMark indent rules: ¢«®¦¥ë© ¯ãªâ ¤®«¦¥ ¡ëâì indent
= content_col த¨â¥«ï, ¨ ç¥ áç¨â ¥âáï breakout. �㦥 ¬¨¨-stack ªâ¨¢ëå ᯨ᪮¢ ¯à¨ ¨¤¥ªá 樨.
Phase 5 - Wrap / Unwrap ¤«¨ëå áâப
„¥ä®«â: wrap on. F2 ¯¥à¥ª«îç ¥â; ¢ ¬¥î-¡ ॠ¯®¤¯¨áì ®âà ¦ ¥â ¤¥©á⢨¥ ("Unwrap" ª®£¤ wrap ¢ª«îçñ, "Wrap" ª®£¤ ¢ëª«îç¥). ‚® ¢à¥¬ï २¤¥ªá 樨 ªàãâ¨âáï ᯨ¥à title bar.
v1 - ॠ«¨§®¢ ®:
- ޤ¨ ¬ áᨢ
line_offset[2048]åà ¨â ‚ˆ„ˆŒ›… ᥣ¬¥âë ( ¥ «®£¨ç¥áª¨¥ áâப¨); ¡¨âë 0..13 - ¡ ©â®¢®¥ ᬥ饨¥, ¡¨â 15 - CONT-ä« £ continuation. - Wrap-०¨¬: soft wrap ¯®á«¥¤¥¬ ¯à®¡¥«¥ <= 80; hard fallback ¥á«¨ ¯à®¡¥« ¥â.
- Œ થàë í¬ä §¨á (
**/*/_/`) ¨ header-¯à¥ä¨ªáë (#/##/...) ¥ ãç¨âë¢ îâáï ¢ visible-col ¯à¨ ¯®¨áª¥ â®çª¨ ¯¥à¥®á . - "‘¯¥æ¨ «ìë¥" «®£¨ç¥áª¨¥ áâப¨ ¥ wrap' îâáï ¢®®¡é¥ (®¤ seg-§ ¯¨áì «®£¨ç¥áªãî áâபã): fence delim, table row (header/separator/body), HR.
- F2 toggle á®åà ï¥â ¢¨§ã «ìãî ¯®§¨æ¨î ç¥à¥§
top_offset¢ FILE_BUF. - Bitmaps (
in_code/in_table/is_tab_hdr) ¯¥à¥áâà ¨¢ îâáï ¢¬¥á⥠á ᥣ¬¥â ¬¨, ¨¤¥ªá¨àãîâáï seg-¨¤¥ªá®¬, ¡¨âë áâ ¢ïâáï ⮫쪮 ¯¥à¢®¬ seg'¥ «®£¨ç¥áª®© áâப¨. - Continuation-ᥣ¬¥âë ।¥àïâáï ¢ á⨫¥ "v1: ¯«®áª®" - plain text,
¨ª ª¨å markdown-ª« áá¨ä¨ª 権; padding ¤® ª®æ áâப¨
ATTR_TEXT.
v1.5 - ®â«®¦¥® ¤«ï ¯®«®© ª àâ¨ë wrap:
- Hanging indent: continuation ®â ulist/olist/quote ¤®«¦¥ ¢ëà ¢¨¢ âìáï ¯®¤ content, ¥ ®â col 0. ’ॡã¥â åà ¨âì marker_width per «®£¨ç¥áª ï áâப ˆ‹ˆ re-classify ¯¥à¢®£® seg' ¯à¨ ।¥à¥ continuation.
- � á«¥¤®¢ ¨¥ base_attr: continuation ®â header' ¤®«¦¥ á®åà ïâì
梥â; continuation ®â code body - ä® ATTR_TEXT_CODE. ’ॡã¥â åà ¨âì
1 ¡ ©â
base_attrper seg ˆ‹ˆ lookup ¯¥à¢®£® seg' . - Inline emphasis ç¥à¥§ £à ¨æã: í¬ä §¨á, ®âªàëâë© ¢ ¯¥à¢®¬ seg'¥ ¨ ¥ § ªàëâë©, ¤®«¦¥ ¯à®¤®«¦ âìáï ¢® ¢â®à®¬. ’ॡã¥â åà ¨âì emph state per seg (3 ¡¨â ).
- Compact way: ¤®¡ ¢¨âì ¯ à ««¥«ìë© ¬ áᨢ
seg_meta[MAX_SEGS]¯® 1 ¡ ©âã- ¯ ªã¥â marker_width (4 ¡¨â ) + emph_state (3 ¡¨â ) + base_attr_idx (4 ¡¨â ¨§ â ¡«¨æë -> 㦥 2-¡ ©â®¢ë© seg_meta).
- Hpan ¤«ï ¤«¨ëå áâப: ¥á«¨ wrap ¢ëª«îç¥, ¤®¡ ¢¨âì <-/-> ¤«ï
£®à¨§®â «ì®£® áªà®«« >80 cols. ޡ鍩 ¬¥å ¨§¬ á tables (Phase 6).
�…€‹ˆ‡Ž‚€�Ž (light) -
viewport_x+ ¯®«ë© re-render ª ¦¤®¥ <-/->. - “᪮२¥ hpan ç¥à¥§ ESTEX WINCOPY/WINREST (deferred): ᥩç á pan
¤¥« ¥â ¯®«ë©
render_viewport()= 30 áâப x 80 wrchar. Œ®¦® ᪮¯¨à®¢ âì áãé¥áâ¢ãî饥 ᮤ¥à¦¨¬®¥ viewport' N cols ¢«¥¢®/¢¯à ¢® ç¥à¥§ win-copy, ¯®â®¬ ।¥à¨âì ⮫쪮 㧪ãî ¯®«®áã á¯à ¢ /á«¥¢ (HPAN_STEP cols x 30 rows 240 wrchar ¢¬¥áâ® 2400). ESTEX SCROLL £®à¨§®â «ì ¥ ¯®¤¤¥à¦¨¢ ¥â - 㦠¨¬¥® WINCOPY-®¯¥à æ¨ï ¨«¨ rdchar/wrchar loop. €ªâ¨¢¨à®¢ âì ª®£¤ ®éãâ¨âáï â®à¬®§; ᥩç á ⨯®¢®¬ markdown'¥ ¥ § ¬¥â®.
v2 - ®â¤¥«ì ï ä¨ç , ¬¨¬® wrap:
- Toggle ¯®¤á¢¥âª¨ 楫¨ª®¬ (F3?)
- Search ¯® ⥪áâã (Ctrl+F / F4)
- Links
[text](url)-> ᨨ© ¯®¤çñàªãâë© text, url ¯àïç¥âáï - Images
->[IMG: alt]
Phase 7 - Links ¨ ¯®¨áª (post-v1)
[text](url)-> ®âà¨á®¢ âì ⮫쪮textá ïમ-ᨨ¬ FG (¢¨§ã «ì® ¯®¤çñàªã⮥)->[IMG: alt]¢ ᪮¡ª å- Search ¯® ⥪áâã (F3 / Ctrl+F): ¨ªà¥¬¥â «ìë©, ¯®¤á¢¥âª ᮢ¯ ¤¥¨©
Phase 8 - F8 Raw / Render toggle
�¥à¥ª«îç ⥫ì ०¨¬ ®â®¡à ¦¥¨ï: ¯à¨ ¢ª«îçñ®¬ Raw ¯®ª §ë¢ ¥âáï ¨á室ë©
⥪áâ ä ©« ª ª ¥áâì - ¢á¥ markdown-¬ થàë (#, **, _, `, |,
>, -, etc.) ।¥àïâáï «¨â¥à « ¬¨ á ATTR_TEXT, ¡¥§ ª« áá¨ä¨ª 樨.
�®«¥§® ª®£¤ :
- 㦮 㢨¤¥âì â®çãî à §¬¥âªã (®â« ¦¨¢ ¨¥ .md, áªà¨è®âë, ª®¯¨à®¢ ¨¥)
- markdown-ª« áá¨ä¨ª â®à ®è¨¡áï ¨ å®ç¥âáï 㢨¤¥âì ®à¨£¨ «
- å®ç¥âáï ¡ëáâà® áà ¢¨âì "¤®/¯®á«¥" ।¥à
�®¢¥¤¥¨¥:
- F8 ¯¥à¥ª«îç ¥â
render_mode(1=render, 0=raw); ¬¥î ¯®ª §ë¢ ¥â ®¡à ⮥ ¤¥©á⢨¥ ("Raw" ª®£¤ ᥩç á render, "Render" ª®£¤ ᥩç á raw) - ⮩ ¦¥ «®£¨ª®© çâ® F2/Wrap/Unwrap. - ‚ Raw ०¨¬¥:
render_line()¨¤ñâ ¯® ª®à®âª®¬ã ¯ã⨠- ¨ª ª®£®classify_line,is_fence_delim,is_code_body, inline-í¬ä §¨á ; ¯à®áâ® ¡ ©â®¢ë© ¤ ¬¯ FILE_BUF ®â seg-offset ¤® next-seg/EOL á tab-expansion ¨ ATTR_TEXT. - � §¤¥«ì® ®â F2: ®¡ ०¨¬ ¥§ ¢¨á¨¬ë (¬®¦® Raw+Wrap, Raw+Truncate,
Render+Wrap, Render+Truncate). Wrap-«®£¨ª ¢
index_linesà ¡®â ¥â ¢ ®¡®¨å á«ãç ïå ®¤¨ ª®¢® (®¯¨à ¥âáï ¢¨§ã «ìë¥ ª®«®ª¨ ¥§ ¢¨á¨¬® ®â à áªà ᪨). - ‘â âãá-¡ à: ¤®¡ ¢¨âì ¨¤¨ª â®à
[R]/[V](Raw / View) ¨«¨ ⥪á⮬RAWà冷¬ á ¨¬¥¥¬ ä ©« .
Œ¨¨¬ «ì ï ॠ«¨§ æ¨ï:
- ޤ¨ ®¢ë© static
uint8_t render_mode = 1; - ‚
render_line(): á ¬®¬ ¢¥àåãif (!render_mode) { ... raw render ... return; } - ‚
render_menu(): ¤®¡ ¢¨âì ïà«ëª F8 à冷¬ á F2. - ‚ £« ¢®¬ 横«¥:
case KEY_F8: toggle_render(); break; toggle_render()®â«¨ç ¥âáï ®âtoggle_wrap()⥬, çâ® �… ¯¥à¥áâà ¨¢ ¥âline_offset[](wrap-ᥣ¬¥â æ¨ï ¥ ¬¥ï¥âáï), ⮫쪮 ¯¥à¥à¥¤¥à¨â íªà .
API-®¢¨ª¨ ¢ libc (¬¨¨¬ «ìë¥)
getkey() - extended key reader (¢ libc)
’¥ªã騩 getch() â¥àï¥â scan code à áè¨à¥ëå ª« ¢¨è (¢®§¢à é ¥â ⮫쪮 E=ASCII). „®¡ ¢«ï¥¬ áà §ã ¢ libc/conio/conio.c ®¢ãî äãªæ¨î à冷¬ á getch():
// Returns scan in high byte, ASCII in low byte.
// Extended keys (arrows, F-keys, PgUp/PgDn, Home/End): ASCII=0, scan code ¢ high byte.
// Plain keys: ASCII ¢ low byte; high byte ᮤ¥à¦¨â positional scan (¡¨â 7 = Ctrl/Alt/Shift modifier).
uint16_t getkey(void) __naked {
__asm
ld c, #0x30 ; ESTEX WAITKEY
rst #0x10 ; A=ASCII, D=scan, E=ASCII
ld e, a ; ensure E=ASCII even if E clobbered
ret ; SDCC __sdcccall(1): ¢®§¢à â uint16_t ¢ DE (D=scan, E=ASCII)
__endasm;
}
„®¯®«¨â¥«ì® - ¢ libc/include/conio.h ¯à®¯¨á âì ¯à®â®â¨¯ ¨ ª®áâ âë scan-ª®¤®¢:
uint16_t getkey(void);
/* Scan codes for getkey() high byte when ASCII=0 (extended keys). */
#define KEY_F1 0x0E
#define KEY_F2 0x0F
#define KEY_F3 0x10
#define KEY_F4 0x11
#define KEY_F5 0x12
#define KEY_F6 0x13
#define KEY_F7 0x14
#define KEY_F8 0x15
#define KEY_F9 0x16
#define KEY_F10 0x17
#define KEY_F11 0x18
#define KEY_F12 0x19
#define KEY_END 0x24
#define KEY_DOWN 0x25
#define KEY_PGDN 0x26
#define KEY_LEFT 0x27
#define KEY_RIGHT 0x29
#define KEY_HOME 0x2A
#define KEY_UP 0x2B
#define KEY_PGUP 0x2C
#define KEY_INS 0x23
#define KEY_DEL 0x22
‘ª -ª®¤ë (¨§ docs/converted/ProgrammerManual.txt:2143-2323):
| Š« ¢¨è | scan | Š« ¢¨è | scan |
|---|---|---|---|
| F1 | 0x0E | Up | 0x2B |
| F10 | 0x17 | Down | 0x25 |
| F11 | 0x18 | Left | 0x27 |
| F12 | 0x19 | Right | 0x29 |
| PgUp | 0x2C | ||
| PgDn | 0x26 | ||
| Home | 0x2A | ||
| End | 0x24 |
—â® ¯¥à¥¨á¯®«ì§ã¥¬ ¨§ áãé¥áâ¢ãî饩 libc
open/read/lseek/close-libc/io/{open,read,lseek}.c(POSIX wrappers)mem_alloc_pages/mem_free_block/mem_get_page-libc/mem/mem_alloc.csprinter_page_w3()- inline__sfrwrite ¢libc/include/sprinter.h:113bank_read_w3/bank_write_w3-libc/mem/bank_io_w3.c(¤«ï fallback ¨«¨ v2 multi-page)wrchar(x, y, ch, attr)-libc/conio/conio.c:476(¡¥§ auto-scroll, ¨¤¥ «ì® ¤«ï viewport)clrscr_attr(attr)-libc/conio/conio.c:395gotoxy/wherex/wherey-libc/conio/conio.c:412-462(¥á«¨ 㦮)kbhit()-libc/conio/conio.c:22(¤«ï non-blocking ®¯à®á , ®¯æ¨® «ì®)dec16/dec8-libc/stdio/dec_print.c(¤«ï status bar: ⥪ãé ï áâப / total / %)COLOR(fg, bg)¬ ªà®á -libc/include/conio.h:152- –¢¥â®¢ë¥ ª®áâ âë
COLOR_*-libc/include/conio.h:145 strlen/memcpy/memset- z80.lib (�… ¯¥à¥¯¨áë¢ âì)
‘âàãªâãà ¨á室¨ª®¢
examples/mdview/
ÃÄÄ Makefile # áâ ¤ àâë© pattern (á¬. examples/cat/Makefile)
ÃÄÄ mdview.c # Phase 1: ¢áñ ¢ ®¤®¬ ä ©«¥ (main, keys, indexing, render)
ÃÄÄ SAMPLE.MD # â¥áâ®¢ë© markdown
ÀÄÄ README.md # ®¯¨á ¨¥ ¨ controls
�®á«¥ Phase 3 à ᪨¤ âì ¯® ¬®¤ã«ï¬ (¥á«¨ á㬬 àë© à §¬¥à > ~6KB):
mdview.c - main loop, status/menu bars, key dispatch
mdrender.c - line rendering with MD inline parser
mdindex.c - file load + line indexing
‘¡®àª
PROJ ?= ../..
SPRINTER_CC := $(PROJ)/bin/sprinter-cc
mdview.exe: mdview.c
$(SPRINTER_CC) --memory small -o $@ mdview.c
--memory small: ª®¤+¤ ë¥ ¢ W2 (DSS ¤ ñâ 㦮¥ ç¨á«® áâà ¨æ); ä ©« - ®â¤¥«ì ï EMM-áâà ¨æ ¢ W3.
‘âàãªâãà mdview.c (Phase 1, í᪨§)
#include <stdint.h>
#include <stdio.h>
#include <conio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sprinter.h>
#include <sprinter_mem.h>
#define VIEW_TOP 1
#define VIEW_BOT 30 // inclusive
#define VIEW_H 30
#define SCREEN_W 80
#define MAX_LINES 2048
#define FILE_BUF ((char*)0xC000) /* W3 - EMM page mapped here */
#define TAB_STOP 4
#define ATTR_TEXT COLOR(COLOR_WHITE, COLOR_BLACK)
#define ATTR_BAR COLOR(COLOR_WHITE, COLOR_BLUE)
#define ATTR_MENU_K COLOR(COLOR_YELLOW, COLOR_BLUE)
#define ATTR_MENU_T COLOR(COLOR_WHITE, COLOR_BLUE)
static uint16_t line_off[MAX_LINES];
static uint16_t n_lines;
static uint16_t top_line;
static uint16_t file_size;
static uint8_t file_blk;
static char filename[64];
static int load_file(const char *path); // open, alloc EMM page, map W3, read, close
static void index_lines(void); // scan FILE_BUF, fill line_off[]
static void render_status(void); // row 0
static void render_menu(void); // row 31
static void render_line(uint16_t idx, uint8_t row); // one line @ row
static void render_viewport(void); // VIEW_H lines starting from top_line
static void scroll_up(uint16_t n);
static void scroll_down(uint16_t n);
static void help_screen(void); // F1
int main(int argc, char **argv) {
if (argc < 2) { puts("Usage: mdview <file.md>"); return 1; }
if (load_file(argv[1]) < 0) { puts("load error"); return 1; }
index_lines();
clrscr_attr(ATTR_TEXT);
render_menu();
render_status();
render_viewport();
for (;;) {
uint16_t k = getkey();
uint8_t ascii = k & 0xFF;
uint8_t scan = (k >> 8) & 0x7F; // strip mod bit
if (ascii) {
if (ascii == 0x1B) break; // Esc -> exit
continue;
}
switch (scan) {
case KEY_F10: goto exit;
case KEY_F1: help_screen(); break;
case KEY_UP: scroll_up(1); break;
case KEY_DOWN: scroll_down(1); break;
case KEY_PGUP: scroll_up(VIEW_H); break;
case KEY_PGDN: scroll_down(VIEW_H); break;
case KEY_HOME: top_line = 0;
render_viewport(); break;
case KEY_END: /* clamp to last viewport */ break;
}
render_status();
}
exit:
mem_free_block(file_blk);
clrscr_attr(ATTR_TEXT);
return 0;
}
Verification
Phase 1
- �®¤£®â®¢¨âì
SAMPLE.MD~5 KB (§ £®«®¢ª¨, ¡§ æë, ᯨ᪨) - ।¥à¨âìáï ¡ã¤¥â plain. cd examples/mdview && makepython make_disk.py mdview.exe SAMPLE.MD -> mc.img && ./run_mame.sh- �஢¥à¨âì:
- Status bar ¯®ª §ë¢ ¥â
SAMPLE.MD L 1-30 / N X% - Menu bar ¢¨§ã
- ^/V: 1 áâப
- PgUp/PgDn: 30 áâப, ª®à४⮥ clamp £à ¨æ å
- Home: top_line=0
- End: top_line = total_lines - VIEW_H
- F1: ¯®ª §ë¢ ¥â help, «î¡ ï ª« ¢¨è ¢®§¢à é ¥â
- F10 / Esc: ¢ë室, íªà ®ç¨é¥
- Status bar ¯®ª §ë¢ ¥â
- Edge cases: ¯ãá⮩ ä ©«, ä ©« ¨§ ®¤®© áâப¨, ä ©« á ®ç¥ì ¤«¨®© áâப®© (>80), CRLF ¨ LF mixed.
Phase 2-4
� áè¨àïâì SAMPLE.MD á ä¨ç ¬¨ ¯® ¬¥à¥ ¤®¡ ¢«¥¨ï, ¢¨§ã «ì® ¢¥à¨ä¨æ¨à®¢ âì ¢ MAME. ‘ªà¨è®â-áà ¢¥¨¥ ®¯æ¨® «ì®.
�¥£à¥áᨨ
- �¨ª ª¨å ¨§¬¥¥¨© ¢ libc Phase 1 ªà®¬¥ (¯®â¥æ¨ «ì®) ¤®¡ ¢«¥¨ï
getkey()¢libc/conio/conio.c- ¥á«¨ â ª, ¯à®£ âìexamples/conio2¨examples/filetestç⮡ë ã¡¥¤¨âìáï çâ® ¨ç¥£® ¥ á«®¬ «®áì.
�¥è¥¨ï ¯® ¥®¤®§ ç®áâï¬
- Word-wrap vs truncate: v1 = truncate (¯à®áâ®). v2 - F2 toggle wrap.
- ƒ®à¨§®â «ìë© áªà®««¨£: v1 - ¥â; v2 -
<-/->ᤢ¨£ viewport ¯® á⮫¡æ ¬. - Tab handling: ¯à¥®¡à §®¢ ¨¥ ¯à¨ ।¥à¥, tabstop = 4 (áâ ¤ àâ MD). Žà¨£¨ « ¢ W3 ¥ âண ¥¬.
- UTF-8: ।¥à¨¬ ¡ ©âë ª ª ¥áâì. …᫨ ä ©« ¢ CP866 - ®âà¨áã¥âáï ª¨à¨««¨æ¥© ç¥à¥§ á¨áâ¥¬ë© ä®â. UTF-8 - ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥¬ (¢¨§ã «ì® ¡ã¤¥â ª è ¥-ASCII ᨬ¢®« å; ¤¥â¥ªâ ¨ ¯à¥¤ã¯à¥¦¤¥¨¥ - ¢ v2).
Phase 6 - �®«ë© layout â ¡«¨æ (deferred)
‘¥©ç á (Phase 4-tables) â ¡«¨æë à¨áãîâáï "¤¥ª®à ⨢®" - ¯ ©¯ë ¨ â¨à¥ § ¬¥ïîâáï box-drawing chars, ® è¨à¨ë ª®«®®ª ¡¥àãâáï ª ª ¥áâì ¨§ ¨á室¨ª . –¥«ì Phase 6 - ¯¥à¥áç¨â âì â ¡«¨æã ¢ ®à¬ «¨§®¢ ë© ¢¨¤:
- Pre-scan â ¡«¨æë: ¯à®©â¨ ¢á¥ áâப¨ ®¤®£® table-¡«®ª , ©â¨ ¬ ªá¨¬ «ìãî è¨à¨ã ª ¦¤®© ª®«®ª¨ (á ãçñ⮬ áꥤ¥ëå inline-¬ થ஢ - ¢¨§ã «ìë© à §¬¥à, ¥ ¡ ©â®¢ë©).
- Re-emit ¢ ¡ãä¥à¥: ¯à¨ § £à㧪¥ ä ©« (¨«¨ ¯à¨ ¯¥à¢®© ¢áâà¥ç¥ â ¡«¨æë)
¯¥à¥¯¨á âì áâப¨ ¢ FILE_BUF â ª, çâ®¡ë ¢á¥ ï祩ª¨ ®¤®© ª®«®ª¨ ¨¬¥«¨
®¤¨ ª®¢ãî è¨à¨ã; ¤®¡ ¢¨âì top/bottom à ¬ª¨ (
ÚÄÂÄ¿/ÀÄÁÄÙ) ª ª á¨â¥â¨ç¥áª¨¥ áâப¨. �â® ¯®§¢®«¨â á®åà ¨âì 1:1 ᮮ⢥âá⢨¥ "«®£¨ç¥áª ï áâப -> ®¤ viewport row" ¡¥§ á¯¥æ¨ «ì®© «®£¨ª¨ ¯à¨ ।¥à¥. - � ¬ïâì: re-emit ¬®¦¥â “‚…‹ˆ—ˆ’œ ä ©« § áçñâ padding ¨ ¤®¯.à ¬®ª. …᫨ ¡ãä¥à ¡«¨§®ª ª 16KB - ®â१ âì â ¡«¨æã ¨ ¯®¬¥â¨âì ¥ñ overflow'®¬.
- ƒ®à¨§®â «ìë© áªà®««¨£: ¥á«¨ ¨â®£®¢ ï è¨à¨ â ¡«¨æë (¨«¨ «î¡®© áâப¨) > SCREEN_W = 80 - ¤®¡ ¢¨âì <-/-> ¤«ï horizontal pan. �â® ¡ã¤¥â ®¡é¨© ¬¥å ¨§¬ ¤«ï ¤«¨ëå áâப (á¬. â ª¦¥ wrap mode), ¥ ⮫쪮 â ¡«¨æ.
- ‚ëà ¢¨¢ ¨¥ ¨§ separator-row:
:--> left,-:-> right,:-:-> center; ãç¨âë¢ âì ¯à¨ padding'¥ ᮤ¥à¦¨¬®£® ï祩ª¨. - ˜ £¨ ॠ«¨§ 樨:
- Walking pass ¯® ä¥á ¬/â ¡«¨æ ¬ ¯àאַ ¢
index_lines()- ᮡà âì extents ¢á¥å â ¡«¨æ. - „«ï ª ¦¤®© â ¡«¨æë - ®¯à¥¤¥«¨âì è¨à¨ë ª®«®®ª.
- �¥è¥¨¥: rewrite-in-buffer (¯à®é¥ ¤«ï ।¥à , ® ¬ãâ¨àã¥â ¨á室¨ª) vs render-time layout (cleaner, ® âॡã¥â ®â¤¥«ì®© áâàãªâãàë ®¯¨á ¨ï layout' ª ¦¤ãî â ¡«¨æã).
- Hpan: ®¡é¨©
viewport_x_offset¤«ï ¢á¥£® íªà , ¨«¨ ®â¤¥«ìë© "è¨à®ª¨© ०¨¬" ⮫쪮 ¢ãâਠ⠡«¨æ.
- Walking pass ¯® ä¥á ¬/â ¡«¨æ ¬ ¯àאַ ¢
�¥ ¡«®ª¨àãîé ï ä¨ç . ‡ ¯ã᪠âì ª®£¤ á⠥⠯®ï⥠⨯®¢®© ¨áâ®ç¨ª markdown-ä ©«®¢ (㧪¨¥ ç¨â «ª¨ -> ¤®áâ â®ç® ⥪ã饣® ¤¥ª®à â®à ; è¨à®ª¨¥ README á ¡®«ì訬¨ â ¡«¨æ ¬¨ -> 㦥 ¯®«ë© layout).
Phase - Šíè ।¥à¥ëå áâப (low priority)
Žâ«®¦¥®: ⥪ãé ï ᪮à®áâì ¡®«¥¥ 祬 ¤®áâ â®ç . €ªâ¨¢¨à®¢ âì ¥á«¨ ¯®ï¢¨âáï áæ¥ ਩, £¤¥ ¢¨¤ § ¤¥à¦ª PgUp/PgDn ( ¯à¨¬¥à, ¯à¨ âï¦ñ«®¬ inline-¯ àá¥à¥ v2 á UTF-8 / linkifier / â ¡«¨æ ¬¨).
Šíè ®âä®à¬ â¨à®¢ ëå áâப (W3, ®â¤¥«ì ï EMM-áâà ¨æ ):
Cache layout (16 KB EMM page, ¢á¥£® 16000 ¡ ©â ¨á¯®«ì§ã¥âáï):
slot 0: 80 chars + 80 attrs = 160 bytes @ offset 0
...
slot 99: 80 chars + 80 attrs = 160 bytes @ offset 15840
Cache tags (W2 static): uint16_t cache_tag[100] = 200 bytes
cache_tag[i] = line_id, ¨«¨ 0xFFFF = invalid
‘âà ⥣¨ï - direct map (no LRU): slot = line_id % 100. Š®««¨§¨ï -> ¢ëâ¥á¥¨¥.
Batched viewport render: 2 page-swap' ‚…‘œ viewport (cache -> file -> cache), ¥ 60 ª ª ¯à¨ ¨¢®© ॠ«¨§ 樨.
�ਠᡮથ: cache_blk = mem_alloc_pages(1) ¯®á«¥ file_blk; mem_free_block exit.
—â® ®â«®¦¥® ¢ v2
” ©«ë >16 KB- ᤥ« ® ¢ v1.5 (¤® 128 KB ç¥à¥§ 1-8 EMM-áâà ¨æ + lazy map ¢ W3).Word wrap- ᤥ« ® (Phase 5, F2 toggle).- Search (Find / Find next) - F3 / F4.
- F8 Raw / Render toggle - ᯥæ¨ä¨ª æ¨ï ¢ Phase 8.
- Links
[text](url)+ image alt - Phase 7. - Tables - Phase 6 (¯®«ë© layout).
- Toggle highlight on/off - ç áâë© á«ãç © F8 Raw.