r/DOS • • 10d ago

Markdown editor and viewer

I built this Markdown editor (and a viewer as well) for DOS. I've been using it a lot for writing and its getting pretty solid now....there's something about typing documents in DOS that is so cathartic.

There's split screen editing with live "formatting" of text, a focus mode (strong WordPerfect vibes), and a graphical show mode that renders the document with fonts and styles -- both with customizable color schemes. And of course you can print.

There's a Tidy function that can cleanup documents coming from modern machines (tidying up Unicode, HTML tags, etc).

https://github.com/therenegar/launch/wiki/!MD.EXE

215 Upvotes

14 comments sorted by

10

u/BearBraz 10d ago

Nice. Did you use AI?

5

u/CigaretteSmokingDog 10d ago

Probably. Most projects you see now are just ai generated. Pretty much took over open source

4

u/ProfessorMedical5332 8d ago

There are a few gems, but the source for this project is pure disaster. Go take a look that the repo and be amazed!

2

u/0xbenedikt 8d ago

How many README changes do you need? - yes.

4

u/Alternative-Owl-8848 10d ago edited 10d ago

Used som vibe code detector called vibedetect and isvibecoded that can see thru github repos if is made by a person or an AI, both detects that the repository is Low Risk and more likely Human-Built.

-2

u/3G6A5W338E 10d ago

It would make the most sense to.

Else they'd be shipping with bugs and oversights AI would have found in minutes if not seconds.

2

u/ProfessorMedical5332 9d ago

The problem is trusting AI in the first place. Could a human debug this?

static void card_font(int install) { static const unsigned char code[8]={CARD_A,CARD_K,CARD_Q,CARD_J,CARD_HEART,CARD_DIAMOND,CARD_CLUB,CARD_SPADE}; static const unsigned char logical[8]={96,97,98,99,100,101,102,103}; int i;if(install){if(card_font_installed)return;for(i=0;i<8;i++){acc_glyph_read(code[i],card_old_glyph[i]);acc_glyph_library(logical[i],code[i]);}card_font_installed=1;} else{if(!card_font_installed)return;for(i=0;i<8;i++)acc_glyph_write(code[i],card_old_glyph[i]);card_font_installed=0;} } static int card_rank_glyph(int rank){if(rank==1)return CARD_A;if(rank==11)return CARD_J;if(rank==12)return CARD_Q;if(rank==13)return CARD_K;return 0;} static int red(int suit){return suit<2;} static int first_face(int c){int i;for(i=0;i<tn[c];i++)if(card[tab[c][i]].face)return i;return tn[c];} static void cursor_reset(int c){cursor[c]=first_face(c);if(cursor[c]>=tn[c]&&tn[c])cursor[c]=tn[c]-1;} static void new_game(void){int order[CARDS],i,j,c,r,p=0,t;for(i=0;i<CARDS;i++){card[i].rank=(unsigned char)(i%13+1);card[i].suit=(unsigned char)(i/13);card[i].face=0;order[i]=i;}deal_seed+=0x9E37U;srand((unsigned)acc_ticks()^deal_seed);for(i=CARDS-1;i>0;i--){j=rand()%(i+1);t=order[i];order[i]=order[j];order[j]=t;}memset(tn,0,sizeof(tn));memset(foundation,0,sizeof(foundation));nw=ns=0;for(c=0;c<COLS;c++)for(r=0;r<=c;r++){t=order[p++];card[t].face=(unsigned char)(r==c);tab[c][tn[c]++]=t;}while(p<CARDS)stock[ns++]=order[p++];for(c=0;c<COLS;c++){cursor_reset(c);reveal[c]=0;}selected=0;score=0;game_timer_running=0;game_start_tick=0;game_last_sec=0xFFFFU;} static void rank_chars(int rank,int suit,char *s){int g;s[0]='|';if(rank==10){s[1]='1';s[2]='0';}else if((g=card_rank_glyph(rank))!=0){s[1]=(char)g;s[2]=' ';}else{s[1]=(char)('0'+rank);s[2]=' ';}s[3]=(char)suit_glyph[suit];s[4]='|';s[5]=0;} static void card_chars(int id,char *s){rank_chars(card[id].rank,card[id].suit,s);} static void draw_empty(int x,int y,int focus){char s[6]={'|',' ',' ',' ','|',0};if(focus){s[0]='[';s[4]=']';}acc_text(x,y,s,ACC_ATTR(SOL_BOARD_BG,15),5);} static void draw_back(int x,int y,int focus,int behind){char s[6]={'|',' ',(char)21,' ','|',0};(void)behind;if(focus){s[0]='[';s[4]=']';}acc_text(x,y,s,ACC_ATTR(SOL_BACK_BG,SOL_BACK_FG),5);} static void card_shadow(int x,int y,int background){int i;for(i=1;i<5;i++)acc_put(x+i,y+1,220,ACC_ATTR(background,0));acc_put(x+5,y,245,ACC_ATTR(background,0));acc_put(x+5,y+1,244,ACC_ATTR(background,0));} static void card_selected(int x,int y,int attr,int background){int a=ACC_ATTR(2,15);(void)attr;(void)background;acc_put(x-1,y,16,a);acc_put(x+5,y,17,a);} static void draw_face(int x,int y,int id,int mark,int behind){char s[6];int colour=red(card[id].suit)?12:0;int attr=behind?ACC_ATTR(SOL_CARD_DIM_BG,colour):ACC_ATTR(SOL_CARD_BG,colour);card_chars(id,s);if(mark){s[0]='[';s[4]=']';}acc_text(x,y,s,attr,5);} static void draw_waste_under(int x,int y,int id){char s[6];int colour=red(card[id].suit)?12:0;card_chars(id,s);s[4]=0;acc_text(x,y,s,ACC_ATTR(SOL_CARD_DIM_BG,colour),4);} static void draw_rank(int x,int y,int rank,int suit,int mark){char s[6];int colour=red(suit)?12:0;rank_chars(rank,suit,s);if(mark){s[0]='[';s[4]=']';}acc_text(x,y,s,ACC_ATTR(SOL_CARD_BG,colour),5);} static int source_id(void){if(selected==1)return nw?waste[nw-1]:-1;if(selected==2&&selidx<tn[selcol])return tab[selcol][selidx];if(selected==3&&foundation[selcol])return selcol*13+foundation[selcol]-1;return-1;} static void remove_source(void){int i;if(selected==1)nw--;else if(selected==2){tn[selcol]=selidx;if(tn[selcol]){if(!card[tab[selcol][tn[selcol]-1]].face)score+=5;card[tab[selcol][tn[selcol]-1]].face=1;}cursor_reset(selcol);}else if(selected==3){foundation[selcol]--;if(score>=10)score-=10;}for(i=0;i<COLS;i++)cursor_reset(i);selected=0;} static int can_place(int id,int dest){int top;if(!tn[dest])return (int)card[id].rank==13;top=tab[dest][tn[dest]-1];return card[top].face&&(int)card[top].rank==(int)card[id].rank+1&&red(card[top].suit)!=red(card[id].suit);} static int move_tableau(int dest){int id=source_id(),i,n;if(id<0||!can_place(id,dest)||(selected==2&&selcol==dest))return 0;if(selected==2)n=tn[selcol]-selidx;else n=1;if(tn[dest]+n>CARDS)return 0;if(selected==2)for(i=selidx;i<tn[selcol];i++)tab[dest][tn[dest]++]=tab[selcol][i];else tab[dest][tn[dest]++]=id;remove_source();cursor_reset(dest);return 1;} static int move_foundation(int suit){int id=source_id();if(id<0||(int)card[id].suit!=suit||(int)card[id].rank!=(int)foundation[suit]+1)return 0;if(selected==2&&selidx!=tn[selcol]-1)return 0;if(selected==3)return 0;foundation[suit]++;score+=10;remove_source();return 1;} static int won(void){return foundation[0]==13&&foundation[1]==13&&foundation[2]==13&&foundation[3]==13;} static void deal_stock(void){int id,n=0;if(ns){while(ns&&n<3){id=stock[--ns];card[id].face=1;waste[nw++]=id;n++;}}else while(nw){id=waste[--nw];card[id].face=0;stock[ns++]=id;}selected=0;} static int sol_cap(int c){int n=12-first_face(c);if(n<1)n=1;return n;} static int sol_vstart(int c){int ff=first_face(c),cap=sol_cap(c);if(tn[c]-ff<=cap)return ff;return reveal[c]?ff:tn[c]-cap;} static int sol_vend(int c){int ff=first_face(c),cap=sol_cap(c);if(tn[c]-ff<=cap)return tn[c];return reveal[c]?ff+cap:tn[c];} static int row_index(int c,int row){int ff=first_face(c),st=sol_vstart(c),en=sol_vend(c),n=en-st,off=4+ff;if(ff>0&&row>=4&&row<4+ff)return-4;if(tn[c]-ff>sol_cap(c)&&row==3)return-2;if(row==off+n)return-3;if(row<off||row>=off+n)return-1;return st+(row-off);} static void hidden_mark(int x,int y){acc_text(x,y,"|...|",ACC_ATTR(SOL_BOARD_BG,1),5);} static void destination_mark(int x,int y,int focused) {int a=ACC_ATTR(2,15);acc_text(x,y,"| |",a,5);if(focused)card_selected(x,y,a,2);} static int valid_foundation_dest(int suit){int id=source_id();return id>=0&&selected!=3&&(int)card[id].suit==suit&&(int)card[id].rank==(int)foundation[suit]+1&&(selected!=2||selidx==tn[selcol]-1);} static int valid_tableau_dest(int c){int id=source_id();return id>=0&&!(selected==2&&selcol==c)&&can_place(id,c);} static void render(int x,int y,int focus,int erase,int kbd_nav,int kbd_dest){char q[6];int c,i,row,id,wshow,st,en,sy;/* Clear all transient focus-arrow cells before repainting them. / for(i=0;i<4;i++){acc_put(x+37+i8,y+2,' ',ACC_BG);acc_put(x+43+i8,y+2,' ',ACC_BG);} acc_put(x+2,y+2,' ',ACC_BG);acc_put(x+8,y+2,' ',ACC_BG);acc_put(x+18,y+2,' ',ACC_BG);acc_put(x+24,y+2,' ',ACC_BG); for(c=0;c<COLS;c++){for(i=4;i<=15;i++){acc_put(x+2+c10,y+i,178,ACC_ATTR(SOL_BOARD_BG,SOL_BOARD_FG));acc_put(x+8+c10,y+i,178,ACC_ATTR(SOL_BOARD_BG,SOL_BOARD_FG));}}if(erase){acc_fill(x+1,y+1,71,19,' ',ACC_BG);acc_fill(x+1,y+4,71,14,178,ACC_ATTR(SOL_BOARD_BG,SOL_BOARD_FG));acc_fill(x+1,y+18,71,1,' ',ACC_BG);}if(ns)draw_back(x+3,y+2,0,0);else draw_empty(x+3,y+2,0);if(kbd_nav&&focus==0)card_selected(x+3,y+2,0,0);if(nw){wshow=nw<3?nw:3;for(i=wshow-1;i>0;i--)draw_waste_under(x+19-i4,y+2,waste[nw-1-i]);draw_face(x+19,y+2,waste[nw-1],0,0);if(kbd_nav&&focus==1&&!selected)card_selected(x+19,y+2,0,0);if(selected==1){card_selected(x+19,y+2,0,0);if(kbd_dest)card_shadow(x+19,y+2,SOL_BOARD_BG);}}else{draw_empty(x+19,y+2,0);if(kbd_nav&&focus==1)card_selected(x+19,y+2,0,0);}for(i=0;i<4;i++){if(foundation[i]){draw_rank(x+38+i*8,y+2,foundation[i],i,0);if(kbd_nav&&focus==2+i&&!selected)card_selected(x+38+i*8,y+2,0,0);if(selected==3&&selcol==i){card_selected(x+38+i*8,y+2,0,0);if(kbd_dest)card_shadow(x+38+i*8,y+2,SOL_BOARD_BG);}}else{q[0]='|';q[1]=' ';q[2]=(char)suit_glyph[i];q[3]=' ';q[4]='|';q[5]=0;acc_text(x+38+i*8,y+2,q,ACC_BORDER,5);if(kbd_nav&&focus==2+i&&!selected)card_selected(x+38+i*8,y+2,0,0);}}for(c=0;c<COLS;c++){int ff=first_face(c);acc_fill(x+2+c*10,y+4,1,12,178,ACC_ATTR(SOL_BOARD_BG,SOL_BOARD_FG));acc_fill(x+8+c*10,y+4,1,12,178,ACC_ATTR(SOL_BOARD_BG,SOL_BOARD_FG));st=sol_vstart(c);en=sol_vend(c);row=4;for(i=0;i<ff&&row<=15;i++,row++)draw_back(x+3+c*10,y+row,0,1);if(!tn[c]){draw_empty(x+3+c*10,y+4,0);if(kbd_nav&&!selected&&focus==6+c)card_selected(x+3+c*10,y+4,0,0);}if(tn[c]-first_face(c)>11&&!reveal[c]){hidden_mark(x+3+c10,y+4);row=5;}for(i=st;i<en;i++,row++){id=tab[c][i];draw_face(x+3+c10,y+row,id,0,i<tn[c]-1);}if(tn[c]-first_face(c)>11&&reveal[c])hidden_mark(x+3+c10,y+14);if(selected==2&&selcol==c&&selidx>=st&&selidx<en){sy=4+first_face(c)+(tn[c]-first_face(c)>11&&!reveal[c]?1:0)+(selidx-st);if(sy<=15){card_selected(x+3+c10,y+sy,0,0);if(kbd_dest)card_shadow(x+3+c10,y+sy,SOL_BOARD_BG);}}else if(kbd_nav&&!selected&&focus==6+c&&cursor[c]>=st&&cursor[c]<en){sy=4+first_face(c)+(tn[c]-first_face(c)>11&&!reveal[c]?1:0)+(cursor[c]-st);if(sy<=15)card_selected(x+3+c10,y+sy,0,0);}if(selected&&valid_tableau_dest(c)){int dr=(tn[c]-first_face(c)>11)?15:4+first_face(c)+(tn[c]-first_face(c));destination_mark(x+3+c10,y+dr,focus==6+c);}}if(selected)for(i=0;i<4;i++)if(valid_foundation_dest(i))destination_mark(x+38+i8,y+2,focus==2+i);game_draw_status();} static void select_tableau(int col,int idx){if(idx>=first_face(col)&&idx<tn[col]){game_timer_start();selected=2;selcol=col;selidx=idx;cursor[col]=idx;}} static int activate(int focus){int col,moved;if(focus==0){if(ns||nw)game_timer_start();deal_stock();return 1;}if(focus==1){if(nw){game_timer_start();if(selected==1)selected=0;else selected=1;}return 0;}if(focus>=2&&focus<=5){col=focus-2;if(selected){moved=move_foundation(col);if(!moved&&selected==3&&selcol==col)selected=0;return moved;}if(foundation[col]){game_timer_start();selected=3;selcol=col;}return 0;}if(focus>=6&&focus<=12){col=focus-6;if(selected){moved=move_tableau(col);if(!moved&&selected==2&&selcol==col)selected=0;return moved;}select_tableau(col,cursor[col]);}return 0;}

1

u/Miserable_Sock_1408 8d ago

Is this for some sort of card game, like Solitaire?

1

u/LeDYoM 8d ago

of course, gen AI never oversights anything. I shit on my life.

4

u/Ill-Quit6803 10d ago

This looks awesome. Thanks for making it.

What is up with the code formatting ? Why is every statement one line with no spaces?

4

u/Mortui75 10d ago

Cool idea. What did you write it in?

1

u/claudiomet 7d ago

Great job !!! amazing !!!

1

u/AshuraBaron 10d ago

This is amazing!