diff --git a/README.md b/README.md index a1e923d..ec29f3b 100644 --- a/README.md +++ b/README.md @@ -98,9 +98,9 @@ By default, `numd` provides basic stats on changes made. It is possible to set Nushell visual settings (and all the others) using the `--prepend-itermid` option. Just pass a code there to be prepended into our intermid-script.nu and executed before all parts of the code. ```nushell indent-output -let path = [z_examples 5_simple_nu_table simple_nu_table.md] | path join +let path = $nu.temp-path | path join simple_nu_table.md -# let's generate some markdown and save it to the `simple_nu_table.md` file +# let's generate some markdown and save it to the `simple_nu_table.md` file in the temp directory "```nushell\n[[a b c]; [1 2 3]]\n```\n" | save -f $path # let's run this file to see it's outputs @@ -201,11 +201,13 @@ Input/output types: │ z_examples/3_book_types_of_data │ dir │ │ z_examples/4_book_working_with_lists │ dir │ │ z_examples/5_simple_nu_table │ dir │ +│ z_examples/6_edge_cases │ dir │ +│ z_examples/999_numd_internals │ dir │ │ z_examples/99_strip_markdown │ dir │ ╰──────────────────name───────────────────┴─type─╯ > sys host | get boot_time -Fri, 24 May 2024 07:47:13 +0000 (a month ago) +Thu, 18 Jul 2024 07:06:52 +0000 (2 days ago) > 2 + 2 4 diff --git a/numd/nu-utils/numd-internals.nu b/numd/nu-utils/numd-internals.nu index fe81864..6367034 100644 --- a/numd/nu-utils/numd-internals.nu +++ b/numd/nu-utils/numd-internals.nu @@ -43,6 +43,8 @@ export def detect-code-blocks []: string -> table { } # Generates code for execution in the intermediate script within a given code fence. +# +# > 'ls | sort-by modified -r' | gen-execute-code --whole_block --fence '```nu indent-output' | save z_examples/999_numd_internals/gen-execute-code_0.nu -f export def gen-execute-code [ --fence: string # opening code fence string with options for executing current block --whole_block @@ -66,12 +68,12 @@ export def gen-execute-code [ if $whole_block { gen-fence-output-numd } else {} - | if (ends-with-definition $in) {} else { + | if (can-append-print $in) { if 'indent-output' in $fence_options { gen-indented-output } else {} | gen-print-in - } + } else {} } | $in + (char nl) } @@ -121,7 +123,7 @@ export def exec-block-lines [ each { # here we define what to do with each line of the current block one by one if $in =~ '^>' { # if it starts with `>` we execute it gen-execute-code --fence $row_type - } else if $in =~ '^\s*#' { + } else if $in =~ '^#' { gen-highlight-command } } @@ -256,6 +258,9 @@ export def code-block-options [ } # Expands short options for code block execution to their long forms. +# +# > expand-short-options 'i' +# indent-output export def expand-short-options [ $option ]: nothing -> string { @@ -301,6 +306,9 @@ export def run-intermid-script [ } # Generates an unique identifier for code blocks in markdown to distinguish their output. +# +# > numd-block 3 +# #code-block-starting-line-in-original-md-3 export def numd-block [ index?: int ]: nothing -> string { @@ -309,6 +317,8 @@ export def numd-block [ # TODO we can use NUON in numd-blocks to set display options # Generates a command to highlight code using Nushell syntax highlighting. +# > 'ls' | gen-highlight-command +# "ls" | nu-highlight | print export def gen-highlight-command [ ]: string -> string { escape-escapes | $"\"($in)\" | nu-highlight | print(char nl)(char nl)" @@ -318,17 +328,49 @@ export def gen-highlight-command [ ]: string -> string { export def trim-comments-plus []: string -> string { str replace -r '^[>\s]+' '' # trim starting `>` | str replace -r '[\s\n]+$' '' # trim newlines and spaces from the end of a line - | str replace -r '\s*#.*$' '' # remove comments from the last line. Might spoil code blocks with the # symbol, used not for commenting + | str replace -r '\s+#.*$' '' # remove comments from the last line. Might spoil code blocks with the # symbol, used not for commenting +} + +# Extract the last span from command to decide if `| print` could be appended +export def extract-last-span [ + $command: string +] { + let $command = $command | str trim -c "\n" | str trim + let $len = ast $command --json + | get block + | from json + | get pipelines + | last + | get elements.0.expr.span + | $in.start - $in.end + + $command + | str substring $len.. } # Checks if the last line of the input ends with a semicolon or certain keywords to determine if appending ` | print` is possible. -export def ends-with-definition [ - condition: string +# +# > can-append-print 'let a = ls' +# false +# +# > can-append-print 'ls' +# true +export def can-append-print [ + command: string ]: nothing -> bool { - $condition =~ '(;|null|(?>[^\r\n]*\b(let|def|use)\b.*[^\r\n;]*))$' + let $last_span = extract-last-span $command + + if $last_span ends-with ';' { + false + } else { + $last_span !~ '\b(let|mut|def|use)\b' + } } # Generates indented output for better visual formatting. +# +# > 'ls' | gen-indented-output +# ls | table | into string | lines | each {$'// ($in)' | str trim --right} | str join (char nl) export def gen-indented-output [ --indent: string = '// ' ]: string -> string { @@ -336,6 +378,9 @@ export def gen-indented-output [ } # Generates a print statement for capturing command output. +# +# > 'ls' | gen-print-in +# ls | print; print '' export def gen-print-in []: string -> string { if $env.numd?.table-width? == null {} else { $"($in) | table --width ($env.numd.table-width)" @@ -344,11 +389,17 @@ export def gen-print-in []: string -> string { } # Generates a try-catch block to handle errors in the current Nushell instance. +# +# > 'ls' | gen-catch-error-in-current-instance +# try {ls} catch {|error| $error} export def gen-catch-error-in-current-instance []: string -> string { $"try {($in)} catch {|error| $error}" } # Executes the command outside to obtain a formatted error message if any. +# +# > 'ls' | gen-catch-error-outside +# /Users/user/.cargo/bin/nu -c "ls"| complete | if ($in.exit_code != 0) {get stderr} else {get stdout} export def gen-catch-error-outside []: string -> string { escape-escapes | ($'($nu.current-exe) -c "($in)"' + @@ -356,9 +407,8 @@ export def gen-catch-error-outside []: string -> string { } # Generates a fenced code block for output with a specific format. -# -# We use a combination of "\n" and (char nl) here for itermid script formatting aesthetics export def gen-fence-output-numd []: string -> string { + # We use a combination of "\n" and (char nl) here for itermid script formatting aesthetics $"\"```\\n```output-numd\" | print(char nl)(char nl)($in)" } @@ -369,6 +419,12 @@ export def gen-print-lines []: list -> string { } # Parses options from a code fence and returns them as a list. +# +# > '```nu no-run, t' | parse-options-from-fence +# ╭───┬────────╮ +# │ 0 │ no-run │ +# │ 1 │ try │ +# ╰───┴────────╯ export def parse-options-from-fence []: string -> list { str replace -r '```nu(shell)?\s*' '' | split row ',' @@ -378,6 +434,9 @@ export def parse-options-from-fence []: string -> list { } # Modifies a path by adding a prefix, suffix, extension, or parent directory. +# +# > 'numd/capture.nu' | path-modify --extension '.md' --prefix 'pref_' --suffix '_suf' --parent_dir abc +# numd/abc/pref_capture_suf.nu.md export def path-modify [ --prefix: string --suffix: string @@ -412,7 +471,7 @@ export def backup-file [ # Generates a timestamp string in the format YYYYMMDD_HHMMSS. # # > tstamp -# 20240527_111215 +# 20240701_125253 export def tstamp []: nothing -> string { date now | format date "%Y%m%d_%H%M%S" } diff --git a/z_examples/5_simple_nu_table/simple_nu_table.md b/z_examples/5_simple_nu_table/simple_nu_table.md index b807460..8632d91 100644 --- a/z_examples/5_simple_nu_table/simple_nu_table.md +++ b/z_examples/5_simple_nu_table/simple_nu_table.md @@ -1,3 +1,11 @@ ```nushell [[a b c]; [1 2 3]] ``` + +Output: + +``` +╭─a─┬─b─┬─c─╮ +│ 1 │ 2 │ 3 │ +╰─a─┴─b─┴─c─╯ +``` diff --git a/z_examples/6_edge_cases/raw_strings_test.md b/z_examples/6_edge_cases/raw_strings_test.md new file mode 100644 index 0000000..0f7b9a9 --- /dev/null +++ b/z_examples/6_edge_cases/raw_strings_test.md @@ -0,0 +1,17 @@ +raw strings test + +```nu +let $two_single_lines_text = r#'"High up in the mountains, a Snake crawled and lay in a damp gorge, coiled + into a knot, staring out at the sea.'# +``` + +```nu +$two_single_lines_text +``` + +Output: + +``` +"High up in the mountains, a Snake crawled and lay in a damp gorge, coiled + into a knot, staring out at the sea. +``` diff --git a/z_examples/6_edge_cases/raw_strings_test.md_intermid.nu b/z_examples/6_edge_cases/raw_strings_test.md_intermid.nu new file mode 100644 index 0000000..0015646 --- /dev/null +++ b/z_examples/6_edge_cases/raw_strings_test.md_intermid.nu @@ -0,0 +1,25 @@ +# this script was generated automatically using numd +# https://github.com/nushell-prophet/numd +const init_numd_pwd_const = '/Users/user/git/numd' +"raw strings test +" | print +"```nu" | print +"let $two_single_lines_text = r#'\"High up in the mountains, a Snake crawled and lay in a damp gorge, coiled + into a knot, staring out at the sea.'#" | nu-highlight | print + +"```\n```output-numd" | print + +let $two_single_lines_text = r#'"High up in the mountains, a Snake crawled and lay in a damp gorge, coiled + into a knot, staring out at the sea.'# + +"```" | print + +"" | print +"```nu" | print +"$two_single_lines_text" | nu-highlight | print + +"```\n```output-numd" | print + +$two_single_lines_text | print; print '' + +"```" | print diff --git a/z_examples/999_numd_internals/gen-execute-code_0.nu b/z_examples/999_numd_internals/gen-execute-code_0.nu new file mode 100644 index 0000000..93506bf --- /dev/null +++ b/z_examples/999_numd_internals/gen-execute-code_0.nu @@ -0,0 +1,5 @@ +"ls | sort-by modified -r" | nu-highlight | print + +"```\n```output-numd" | print + +ls | sort-by modified -r | table | into string | lines | each {$'// ($in)' | str trim --right} | str join (char nl) | print; print '' diff --git a/z_examples/99_strip_markdown/raw_strings_test.nu b/z_examples/99_strip_markdown/raw_strings_test.nu new file mode 100644 index 0000000..c5409b5 --- /dev/null +++ b/z_examples/99_strip_markdown/raw_strings_test.nu @@ -0,0 +1,8 @@ + + # ```nu +let $two_single_lines_text = r#'"High up in the mountains, a Snake crawled and lay in a damp gorge, coiled + into a knot, staring out at the sea.'# + + + # ```nu +$two_single_lines_text