Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Some problems encountered in copying code LA from Linqpad
#1
Hi,

The following C# code, in linqpad, can be executed successfully, It supports the following picture formats,This is convenient
[Image: bbbb.png]

But when I copy the code into the LA, there will be a hint in the picture below, where the red box part is the wrong hint
[Image: a.png]

If I click the Yes button, I need to manually delete these erroneous items

I suggest that LA can support the format of the picture below, do not pop up the prompt (Don't put using code in top comments)

[Image: abc.png]

After I made the modification, I executed the code and still reported an error, maybe that using the main method directly is not supported
[Image: ac.png]

It seems that copying code to LA from Linqpad is not very convenient and requires a lot of modifications
 
Code:
Copy      Help
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

static void Main(string[] args)
{
    Environment.CurrentDirectory = @"C:\Users\Administrator\Desktop";

    Document doc = new Document();
    doc.LoadFromFile(@"Test2b.docx");

    foreach (Section section in doc.Sections)
    {
        foreach (Paragraph paragraph in section.Body.Paragraphs)
        {
            if (paragraph.StyleName != "Heading1")
            {
                HashSet<float> fontSize = new HashSet<float>();
                HashSet<Color> fontColor = new HashSet<Color>();
                foreach (DocumentObject paraChildObject in paragraph.ChildObjects)
                {
                    if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange)
                    {
                        TextRange textRange = paraChildObject as TextRange;
                        Font font = textRange.CharacterFormat.Font;
                        fontSize.Add(font.Size);
                        Color color = textRange.CharacterFormat.TextColor;
                        fontColor.Add(color);
                        if (font.Name == "kaiti")
                        {
                            textRange.CharacterFormat.Font = new Font("liti", font.Size);
                        }
                    }
                }
                if (fontSize.Count > 1)
                {
                    setA(paragraph);
                }
            }
        }
    }
    doc.SaveToFile(@"result.docx", FileFormat.Docx);
}

public static void setA(Paragraph para)
{
    para.Format.BeforeSpacing = 8f;
    para.Format.AfterSpacing = 16f;
    para.Format.LineSpacing = 16f;
    para.Format.LineSpacingRule = LineSpacingRule.Exactly;
    foreach (DocumentObject paraChildObject in para.ChildObjects)
    {
        if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange)
        {
            TextRange textRange = paraChildObject as TextRange;
            if (Regex.IsMatch(textRange.Text, "^([A-Za-z]){1}[^.]*."))
            {
                textRange.CharacterFormat.Font = new Font("Consolas", 14);
            }
            if (Regex.IsMatch(textRange.Text, "^[\u4e00-\u9fbb]+"))
            {
                textRange.CharacterFormat.Font = new Font("宋体", 14);
            }
        }
    }
}
#2
LA uses standard C#. It can be either class with Main, or top-level statements without Main.

In this case either:
1. Put both functions into a class.

class Program {
put code here
}

2. Or convert the code to valid top-level statements: move Main code out of Main (and delete Main), and delete the 'public' keyword (then the function will be a local function).

----------

About 'Add missing using directives': LA finds classes with same name in multiple namespaces, and cannot know which are correct. Either delete wrong usings, or click No and then add good usings.
#3
Thank you for your help
Changing code 1 to code 2 is more in line with everyone's operating habits
________________________________________________code 1

/*/ role exeProgram; outputPath %folders.Workspace%\exe\Script1; r %dll%\spire\Spire.Doc.dll; /*/ //.
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
script.setup(trayIcon: true, sleepExit: true);
//..

static void Main(string[] args)
________________________________________________code 2

/*/ role exeProgram; outputPath %folders.Workspace%\exe\Script1; r %dll%\spire\Spire.Doc.dll; /*/ //.
script.setup(trayIcon: true, sleepExit: true);
//..

using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

static void Main(string[] args)
#4
script.setup before usings is not possible, but you can prevent LA putting usings into //. //...
In script template (in Options) remove //. //... Can remove everything if don't need script.setup (it is optional).

Actually script.setup can be moved to a module initializer function in global.cs. Not tested. But then it will be executed in all scripts. Probably not a good idea.

Maybe LA should have option "put usings into /. //..".
#5
code1 can execute successfully
code2 still has the following error message

<open "<0x100000043>|16|7">Script1.cs(16,7): error CS0260: Missing partial modifier on declaration of type 'Program'; another partial declaration of this type exists
<open "<0x100000043>|17|14">Script1.cs(17,14): warning CS7022: The entry point of the program is global code; ignoring 'Program.Main(string[])' entry point.


code1
 
Code:
Copy      Help
/*/ role exeProgram; outputPath %folders.Workspace%\exe\Script1; r %dll%\spire\Spire.Doc.dll; r %dll%\spire\Spire.PDF.dll; /*/
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

class Program {
    static void Main(string[] args) {
        Environment.CurrentDirectory = @"C:\Users\Administrator\Desktop";
        
        Document doc = new Document();
        doc.LoadFromFile(@"Test2b.docx");
        
        foreach (Section section in doc.Sections) {
            foreach (Paragraph paragraph in section.Body.Paragraphs) {
                if (paragraph.StyleName != "Heading1") {
                    HashSet<float> fontSize = new HashSet<float>();
                    HashSet<Color> fontColor = new HashSet<Color>();
                    foreach (DocumentObject paraChildObject in paragraph.ChildObjects) {
                        if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange) {
                            TextRange textRange = paraChildObject as TextRange;
                            Font font = textRange.CharacterFormat.Font;
                            fontSize.Add(font.Size);
                            Color color = textRange.CharacterFormat.TextColor;
                            fontColor.Add(color);
                            if (font.Name == "kaiti") {
                                textRange.CharacterFormat.Font = new Font("liti", font.Size);
                            }
                        }
                    }
                    if (fontSize.Count > 1) {
                        setA(paragraph);
                    }
                }
            }
        }
        doc.SaveToFile(@"result.docx", FileFormat.Docx);
    }
    
    public static void setA(Paragraph para) {
        para.Format.BeforeSpacing = 8f;
        para.Format.AfterSpacing = 16f;
        para.Format.LineSpacing = 16f;
        para.Format.LineSpacingRule = LineSpacingRule.Exactly;
        foreach (DocumentObject paraChildObject in para.ChildObjects) {
            if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange) {
                TextRange textRange = paraChildObject as TextRange;
                if (Regex.IsMatch(textRange.Text, "^([A-Za-z]){1}[^.]*.")) {
                    textRange.CharacterFormat.Font = new Font("Consolas", 14);
                }
                if (Regex.IsMatch(textRange.Text, "^[\u4e00-\u9fbb]+")) {
                    textRange.CharacterFormat.Font = new Font("宋体", 14);
                }
            }
        }
    }
}

code2
 
Code:
Copy      Help
/*/ role exeProgram; outputPath %folders.Workspace%\exe\Script1; r %dll%\spire\Spire.Doc.dll; r %dll%\spire\Spire.PDF.dll;/*/
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

script.setup(trayIcon: true, sleepExit: true);
//..

class Program {
    static void Main(string[] args) {
        Environment.CurrentDirectory = @"C:\Users\Administrator\Desktop";
        
        Document doc = new Document();
        doc.LoadFromFile(@"Test2b.docx");
        
        foreach (Section section in doc.Sections) {
            foreach (Paragraph paragraph in section.Body.Paragraphs) {
                if (paragraph.StyleName != "Heading1") {
                    HashSet<float> fontSize = new HashSet<float>();
                    HashSet<Color> fontColor = new HashSet<Color>();
                    foreach (DocumentObject paraChildObject in paragraph.ChildObjects) {
                        if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange) {
                            TextRange textRange = paraChildObject as TextRange;
                            Font font = textRange.CharacterFormat.Font;
                            fontSize.Add(font.Size);
                            Color color = textRange.CharacterFormat.TextColor;
                            fontColor.Add(color);
                            if (font.Name == "kaiti") {
                                textRange.CharacterFormat.Font = new Font("liti", font.Size);
                            }
                        }
                    }
                    if (fontSize.Count > 1) {
                        setA(paragraph);
                    }
                }
            }
        }
        doc.SaveToFile(@"result.docx", FileFormat.Docx);
    }
    
    public static void setA(Paragraph para) {
        para.Format.BeforeSpacing = 8f;
        para.Format.AfterSpacing = 16f;
        para.Format.LineSpacing = 16f;
        para.Format.LineSpacingRule = LineSpacingRule.Exactly;
        foreach (DocumentObject paraChildObject in para.ChildObjects) {
            if (paraChildObject.DocumentObjectType == DocumentObjectType.TextRange) {
                TextRange textRange = paraChildObject as TextRange;
                if (Regex.IsMatch(textRange.Text, "^([A-Za-z]){1}[^.]*.")) {
                    textRange.CharacterFormat.Font = new Font("Consolas", 14);
                }
                if (Regex.IsMatch(textRange.Text, "^[\u4e00-\u9fbb]+")) {
                    textRange.CharacterFormat.Font = new Font("宋体", 14);
                }
            }
        }
    }
}

Linqpad has a big problem, it can't generate exe files, which happens to be the advantage of LA

But after the linqpad code is copied to the LA, there are still many modifications to be made, which is not very convenient
#6
Code:
Copy      Help
script.setup(trayIcon: true, sleepExit: true);

is top-level-statements. The C# compiler converts it to classic C# code like
 
Code:
Copy      Help
class Program {
static void Main() {
script.setup(trayIcon: true, sleepExit: true);
}}

Then the compilation contains 2 class Program.

Either remove
 
Code:
Copy      Help
class Program {
    static void Main(string[] args) {

and } and }

or move
 
Code:
Copy      Help
script.setup(trayIcon: true, sleepExit: true);

to Main.
#7
thank you so much
#8
If want to use script.setup but not in script code, probably the best way is this:

1. Create a class file like this:
Code:
Copy      Help
// class "script_setup_tray_icon.cs"
class _ModuleInit_ {
    [
ModuleInitializer]
    public static void Function1() {
        script.setup(trayIcon: true, sleepExit: true);
    }
}

2. Add the class file in scripts where you want to use this script.setup, like this:

Code:
Copy      Help
// script ""
/*/ c \script_setup_tray_icon.cs; /*/

dialog.showYesNo("Do you see my tray icon?");

You can create several such class files, each with different script.setup arguments or completely different code. Then some scripts can use class file 1, some scripts class file 2...

And edit the template in Options. Let it be empty or contain just the /*/ ... /*/.

Note that module initializers run before other code, therefore something may not work. But script.setup should work. Not tested much.
#9
Thanks again,

The above operation Can implemented automatically? e.g:

1.If the code in the clipboard, which contains using code, is no longer prompted for the following window (which is redundant)
[Image: a.png]
2.If the role is exeProgram, Check if the code contains class Program { }, If not, it is added automatically, and some other considerations above ...
These checks are also done when roles change(form miniProgram 2 exeProgram)

3.Put the drop-down list of role selections next to the Compile button to make it easier
[Image: c.png]

4.If the Au.dll class library is not referenced in the code, the generated exe file will not contain the files ( Au.dll , AuCpp.dll , etc )

The above automation operations for linqpad users,  It's a gospel, very libre automate  Smile
generate exe , is the most mentioned recommendation by linqpad users, but it is still not implemented
https://linqpad.uservoice.com/forums/183...uggestions
#10
1. It happens when code with using directives is pasted below script.setup. If you import many such codes, consider to remove script.setup from your script template in Options (maybe temporarily). Let it be empty.
2. exeProgram and  class Program are unrelated. Usually don't need class Program. See also menu Edit -> Document -> Add class Program.
3. No.
4. The compiled program uses these dlls even if script code does not use them directly.
#11
#4
A bit hard to understand, can't generate a separate exe?

Using the following tool, I can generate separate, very small, exe files for .linq
https://github.com/atifaziz/LinqPadless
#12
Can't create single-file .exe.

Even without Au.dll would create ScriptName.exe + ScriptName.dll. With old .NET 4.x could be single .exe file, but for .NET 6 need .exe and .dll.

Au.dll performs many auxiliary tasks, for example prints exception info when failed, allows to terminate more softly (remove tray icon etc), sets script class properties, workarounds for .NET/OS bugs, etc.
#13
thanks , I understand


Forum Jump:


Users browsing this thread: 1 Guest(s)