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.


Log in to reply