sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Best way to save variabls in an ini

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 4 Posters 1.4k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D Offline
      Davidfi1
      last edited by

      Hi all.
      What is the best way to save multi line text in the ini file?

      I want to enable easy editing of the lines in a text editor
      and an easy way to read these variables to ruby.

      Gcode.ini will be the file name & for now I would like to save in it :

      1. "File header" lines
      2. "File footer" lines
      3. "Layer header" lines
      4. "Layer footer" lines
      1 Reply Last reply Reply Quote 0
      • A Offline
        Aerilius
        last edited by

        Hi,
        we do normally not often use ini files with SketchUp (SketchUp has an API method to save defaults). Another very simple way is to turn a Ruby hash ( hash = {:property => value}) into a string using inspect and save it to a file, then reading it using for example eval (assuming no evil code has been injected into the file).

        If you really want to parse files with the .ini format, maybe see in thomthom's TT_Lib/config_ini.rb or examples on stackoverflow.

        1 Reply Last reply Reply Quote 0
        • D Offline
          Davidfi1
          last edited by

          1. Is it possible to have multi line key ?
          2. Can this code read an ini file made with CR+LF by a notepad on a PC? (since the testRead.ini is only CR )
          1 Reply Last reply Reply Quote 0
          • A Offline
            Aerilius
            last edited by

            1.) I just tested and it works with multiline strings.
            2.) This is not the same format as ini files, thus I wouldn't call it ini. It is just a suggestion for a simple solution (using Ruby's capabilities), if you need the classic ini format as used on Windows, then you need to write a parser (or find one).
            Ruby reads files independent of the line endings (see test file with CR+LF, both CR+LF and LF ran fine in the Linux and Windows version of Ruby).


            hash = eval( File.read( UI.openpanel ) )

            1 Reply Last reply Reply Quote 0
            • D Offline
              driven
              last edited by

              hi Aerilius,

              why would it split like this on a mac, is it giving the different line endings an order?
              {:compression=>false, :resolution=>20, "key2"=>"This key has a very\n long value", "a Hash"=>{"one"=>1}, :resolution_by_faces=>true, :min=>20, :limit=>false, :max=>1024, :jpeg_quality=>75, "a Float"=>3.14159265358979, "The answer to all questions\n is in a third line."=>42, :key1=>"value", :percentage=>50, "an Array"=>[0, 1, 2]}

              learn from the mistakes of others, you may not live long enough to make them all yourself...

              1 Reply Last reply Reply Quote 0
              • TIGT Offline
                TIG Moderator
                last edited by

                There are may examples of writing 'values' into a 'text' file and then reading them back in later.
                Whether this file is named as a .TXT, .CSV, .TSV, .LOG, .DAT, .INI file etc is irrelevant.
                If you explain better what you'd like to do [rather than how you think you could do it!], then it might help us all get to a sensible solution...

                There are many ways of saving "data" for reuse later...
                For example...
                As attributes attached to entities, to definitions. to collections etc in a SKP.
                As attributes attached to the SKP itself.
                As 'defaults' attached to the Sketchup application itself.
                And finally into external files [e.g. INI or other file-type].
                πŸ˜•

                TIG

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Davidfi1
                  last edited by

                  @tig said:

                  If you explain better what you'd like to do [rather than how you think you could do it!], then it might help us all get to a sensible solution..

                  This is what I want to save:

                  @davidfi1 said:

                  1. "File header" lines
                  2. "File footer" lines
                  3. "Layer header" lines
                  4. "Layer footer" lines

                  1-4 are each a few lines of text that needs to be inserted before and after sections of other text instruction that are generated from the sketchup module.

                  In my G-Code exporter http://sketchucation.com/forums/viewtopic.php?f=323&t=50067
                  the code outputs a line of G-Code for each component named "filament"
                  The lines/components/filament/Gcode are grouped by layers.
                  Before and after each layer and the hole file a constant list of lines needs to be added.
                  These lines are what I want to save in the file.

                  so what I need is:

                  @davidfi1 said:

                  I want to enable easy editing of the lines in a text editor
                  and an easy way to read these variables to ruby.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    Davidfi1
                    last edited by

                    @aerilius said:

                    Ruby reads files independent of the line endings

                    Ok - If you go to simple solution of using the ruby mechanisem
                    Then - why not just use the ruby "load"?
                    to load the ini file...
                    load File.join(File.dirname(FILE),'Gcode.ini')

                    # Put Heder of the G-Code file here;
                    Gcode_Exporter_File_Heder = "
                    ;Gcode Exporter File Heder Line 1          
                    ;Gcode Exporter File Heder Line 2          
                    ;Gcode Exporter File Heder Line 3          
                    "  # End of "Gcode_Exporter_File_Heder"
                    
                    Gcode_Exporter_Layer_Heder = "
                    ; Gcode Exporter Layer %s Heder          
                    " # End of "Gcode_Exporter_Layer_Heder"
                    
                    Gcode_Exporter_Layer_Futer = "
                    ; Gcode Exporter Layer %s Futer 
                    "
                    
                    Gcode_Exporter_File_Futer  = "
                    ;Gcode Exporter File Futer
                    "
                    
                    1 Reply Last reply Reply Quote 0
                    • TIGT Offline
                      TIG Moderator
                      last edited by

                      Is this INI file 4 lines of some fixed text that is always used every time?
                      Is so, then why use an INI at all? just set them as 4 Constants in your code?

                      If the text is 'fixed', but occasionally editable by the user to customize settings, then a file named 'Gcode.ini' could be kept with the .RB file: the user edits that and your code reads its contents as it loads.

                      If this text is set dynamically during the code's operation and the 'values' of the text change, then don't bother writing the INI, but rather make the texts as four @variables, which you use as you go...

                      It's still not clear what is what.

                      If you want an INI then this a way how it could be written and parsed.
                      **File_header**==lines== **File_footer**==lines and lines== **Layer_header**==lines...== **Layer_footer**==lines more lines and more lines...==
                      Note how the ' ==' makes the demarcation of each of the line[s] for each 'header/footer' reference, placed immediately after the reference itself and at the end of its line[s], which can have several new lines if desired.
                      Then your code loads the file's text and parses it:
                      strfil=(File.join((File.dirname(__FILE__)), 'Gcode.ini')) strs=IO.read(strfil) stra=strs.split("==") strh={} 0.step(stra.length-2, 2){|i| key=stra[i].gsub(/[[:space:]]/, '') next if key.empty? || stra[i+1].empty? strh[key]=stra[i+1] }
                      The hash ' strh' now contains the references:
                      File_header File_footer Layer_header Layer_footer
                      set to all of the lines of code that each was == to; so strh['File_header'] returns lines
                      You can of course use clever pattern matching etc, but one KISS way is these demarcations to show the extent of the line[s]...

                      TIG

                      1 Reply Last reply Reply Quote 0
                      • A Offline
                        Aerilius
                        last edited by

                        @davidfi1 said:

                        Ok - If you go to simple solution of using the ruby mechanisem
                        Then - why not just use the ruby "load"?

                        That's the obviously better choice except that you don't get a reference to the hash (in my example) because load returns true. So you would embed reference names in the file (like your example), but load evals in the top level namespace, so you would have to use constants like DFI1::GCode::File_header to access you plugin's namespace (no local variables, no global variables).

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Davidfi1
                          last edited by

                          @tig said:

                          If the text is 'fixed', but occasionally editable by the user to customize settings, then a file named 'Gcode.ini' could be kept with the .RB file: the user edits that and your code reads its contents as it loads.

                          The text is 'fixed' for a single 3D printer.
                          But one user mey have more then one printer.

                          @aerilius said:

                          but load evals in the top level namespace, so you would have to use constants like DFI1::GCode::File_header to access you plugin's namespace (no local variables, no global variables).

                          Well, I put the load File.join(File.dirname(FILE),'Gcode.ini')
                          inside the class GcodeExporter - and it works - no need for "::" just use the constants.

                          That doesn't mean it is good practice nor that it will work in future versions of sketchup
                          but - 1)it works. 2) it is very simple 3) it gets the job done quickly

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement