Mu-Format, a MUSHCode (un)formatting library.

  • Hi gang! It's been a little while! I've been tasked to learn a couple of new technologies for work, so I've been working on a couple of tools for the MU world.

    First up is MU-Format, a javascript library that handles minifying MUSHCode with some added bonuses like file inclusion and (soon) run-time variables and functions for taking care of pesky tasks like swapping out dbref numbers, or scripting repetitive tasks. I put together a little site to play with the library: It's a development build so it may take a moment to load initially, but should be good to go after that.

    Be gentle with the Github feature, I haven't added oAuth yet to use your own quotas, so we're limited to 60 API calls an hour (for now). I have a garbage archive I've been using for testing that you can use for proof of concept: Don't try to read it as an actual system, it's random code files that I've strung together. I'll have something more substantial soon - or maybe YOU!

    Anyways, let me know what you think! Lots of feedback is very welcome. :)

  • Hmm. First update thoughts: I'm considering on a way to figure out 'blocking' in MUSHCODE. I could easily end a block when the text reaches the classic attribute/command prefixes (& @, maybe +) But what about custom commands without a prefix? Or a prefix convention that's entirely new? I wonder if I should make the delimiter '-' optional, or create a tag to designate running a softcode command (#cmd <code>, etc) so the formatter knows not to roll it up into the previous. Hmm.

  • I did a copy/paste from 

    and it mashed everything together.

    It converts leading tabs to a space. I assume it does the same to leading spaces.
    (My code style is to leave trailing spaces for space-formatting before a newline.)

    It really, really gets confused if you copy from the non-raw part of GitHub, e.g.:
    • Benefit over Muxify: It doesn't get choked up when a \* is in the middle of a line. (Muxify is fine with this in shorter chunks but not the amount of code I tend to throw at it.)

    • Drawback over Muxify: It needs - to know where a block ends.

  • @thenomain Thanks for checking it out! I can totally see the formatting fiasco in the dev client on the entry side. I also noticed that I couldn't clear the text when I copy/pasted either. I'll have to update the code to take innerHTML into account as well. :D

    I really want to get rid of the - for blocking, badly. I'm just not sure how I want to approach non-prefixed commands. I can totally block on &, @, the 'in game' prefixes, and the classic +. I suppose I could make a #tag for a non-prefixed command. $ or #cmd <stuff> so it doesn't get blocked in with the command before it. What do you think

  • @kumakun What do you mean by blocking on &, @, +? Those don’t really define blocks; they can exist in the middle of other commands.

  • @kumakun

    Muxify blocks by looking for a non-whitespace character in the first character position. The core drawback from this is forcing a certain code methodology (i.e., you cannot have non-indented code), but if it's easier than sensing for @, &, /*, #, or EOD, then I don't think it's a bad forced methodology. Python gets away with much stricter indenting rules.



    @faraday : He means in the first character position. Right now to define an end of block, you need to put - in the first character position.

    e.g., the following input:

    this is a test
    within a test
      within a test
    This is another test.
    - This is a third test
    -Fourth test--now with pretend em-dashes!

    creates this output:

    this is a test within a test within a test
    This is another test.
    This is a third test
    Fourth test--now with pretend em-dashes!
    @@ Formatted with Mu-Format
    @@ 2019 Lemuel Canady, Jr


    edit edit:

    Another suggestion: Put the output in an input pane so you can select-all and not get the whole web page.

  • This breaks the system beautifully:

    &c.aspiration [v( d.asp )]=$^\+?asp(/[^ ]+)?(.*)?$:
    	think strcat( 
    		switch entered:, %b, setr( s, trim( rest( %1, / ))), %r, 
    		switches known:, %b, 
    		setr( k, 
    				iter( lattr( %!/c.aspiration* ), rest( %i0, / ), , | ), 
    				a, |, | 
    		), %r, 
    		switch matched:, %b, 
    		setr( m, grab( |%qk, %qs*, | )), %r, 
    		content:, %b, setr( c, trim( %2 )), %r, 
    	@assert not( haspower( %#, guest ))={ 
    		@pemit %#=
    		u( .msg, asp, I'm sorry%, guest%, but this isn't *for* you. )
    	@assert cor( not( %qs ), t( %qm ))={ 
    		@pemit %#=
    		u( .msg, asp, I don't know the switch '%qs'. 
    			I know: [itemize( lcstr( trim( %qk, b, | )), | )]
    	@pemit %#=case( 1, 
    // switch
    		cand( t( %qs ), t( %qm )), 
    		u( c.aspiration/%qm, %qc ), 
    // specific: list details (yeah, probably should have its own attribute)
    		t( %qc ), 
    			if( strmatch( %qc, */* ), 
    				[setq( p, pmatch( first( %qc, / )))][setq( n, rest( %qc, / ))], 
    				[setq( p, %# )][setq( n, %qc )] 
    			case( 0, 
    				cor( isstaff( %# ), strmatch( %#, %qp )), 
    				u( .msg, asp, You cannot check someone else's aspiration. ), 
    				hastype( %qp, player ), 
    				u( .msg, asp, No such player ), 
    				isint( %qn ), 
    				u( .msg, asp, 
    					You didn't enter a number%; did you mean 'asp/list %qn'? 
    				u( display.aspiration.details, %qp, %qn )
    // general
    		u( display.aspiration.list, %#, lattr( %#/_aspiration.* ))
    @set v( d.asp )/c.aspiration=regex
    @set v( d.asp )/c.aspiration=no_parse
    &c.aspiration/fulfill [v( d.asp )]=
    		setq( f, trim( first( %0, = ))), 
    		setq( r, trim( rest( %0, = ))), 
    		case( 0, 
    			strlen( %qr ), 
    			u( f.list.aspirations, 
    				if( strlen( %qf ), %qf, %# ), 
    			strmatch( %qf, */* ), 
    			u( f.aspiration/fulfill.request, %qf, %qr ), 
    			u( f.aspiration/fulfill.approve, 
    				first( %qf, / ), 
    				rest( %qf, / ), 

    It thinks that the */* in the middle of two lines are the start/end of a comment block.

  • @faraday said in Mu-Format, a MUSHCode (un)formatting library.:

    @kumakun What do you mean by blocking on &, @, +? Those don’t really define blocks; they can exist in the middle of other commands.

    Wrong term, sorry! But yes, deciding on where to end the previous block. delimiter? Words.

    @Thenomain Interesting! I wondered how Muxify did it. Thanks for putting the system through some paces for me. I've got more to tinker with now, yay! :D

    I'm pretty sure I can build a regular expression that only looks for those characters at the beginning of a line, and ends when it runs into one again. Right now comments are a regex as well. I may have to not be lazy about it and scrub through for comments line by line manually!

  • Updates!
    You no longer have to use hyphens to separate commands! At this moment it recognizes @ and & prefixes in the first position of the line as the start of a new attribute/command.

    Copying and pasting from non-text sources don't create weird HTML artifacts in the input box anymore. I'm not sure about the cross-browser compatibility of my solution, so let me know!

    I'm still really interested in hearing about what kind of features MU-Format should have! I'm going to start writing MUX compatible library add-ons that you'll be able to try out through the options button on the website:

  • @Thenomain If you wouldn't mind trying to break it again? :D

  • @Kumakun

    Copied text from my text editor:

    &notes.merit.kybermagus [v( d.dt )]=
    	XX Brownies (Sexy!)
    	|Lore Threshold: Gramarye *****

    Pasted text:

    ¬es.merit.kybermagus [v( d.dt )]=
    	XX Brownies
    	|Lore Threshold: Gramarye *****


    Okay, let's try another one:
    Copied text:

    &notes.merit.animagus [v( d.dt )]=
    	300 Brownies (-100 for Arendi, +100 for exotic animal form)
    	|Lore Threshold: Gramarye **

    Pasted text:

    ¬es.merit.animagus [v( d.dt )]=
    	300 Brownies (-100 for Arendi, +100 for exotic animal form)
    	|Lore Threshold: Gramarye **


    That's not a control character, it's literally whatever that rotated-L is as text.

    So let's try this. Copied:

    &not &not &not &not&not&not


    ¬ ¬ ¬ ¬¬¬



    Also: Dark mode please.


  • Okay, I'm finally back in the coding hot-seat again after a few months of recovery. This project is probably my first free-time priority because I could definitely use it to continue my own project. That, and React has gotten WAAAAY easier since I wrote this originally. It's time to update and simplify.

    I also have plans for a desktop version, so you can preprocess and compile code from your desktop, before uploading the archive to Github, if you want quick personal access or to share.

Log in to reply