-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NEW-FEATURE] Create tool for generating resx file from localized str…
…ings from blazor components (#210) * Create draft PR for #209 * added ltr tool, wip on doc * added simple documentation and fix tests * add ltr to pipeline * adds required target framework for lrt --------- Co-authored-by: Specter-13 <Specter-13@users.noreply.github.com> Co-authored-by: Specter-13 <56168909+Specter-13@users.noreply.github.com> Co-authored-by: Peter <61538034+PTKu@users.noreply.github.com>
- Loading branch information
1 parent
d9e73a1
commit 5b13eec
Showing
20 changed files
with
505 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# LTR - LocalizablesToResx | ||
|
||
LocalizablesToResx is a simple tool, which is used to acquire localized strings within `.razor` files and automatically generate `.resx` file based on these strings. This tool intends to simplify creation of .resx files from .razor files. | ||
|
||
|
||
## Example | ||
|
||
Let's have following .razor file with localized strings | ||
```html | ||
|
||
<h1>@Localizer["Home"]</h1> | ||
<p>@Localizer["Welcome"]</p> | ||
<p>@Localizer["This is example app"]</span> | ||
|
||
``` | ||
|
||
We can call this script: | ||
|
||
`ltr -f test.razor -o test.resx` | ||
|
||
Following resx file will be generated: | ||
|
||
![example](../../images/example-resx.png) | ||
|
||
## Installation | ||
|
||
dotnet tool install AXSharp.ltr --prerelease --local | ||
|
||
|
||
## Parameters | ||
|
||
This cli tool can be used with following parameters: | ||
|
||
- -i (--identifier) | ||
- identifier which represent localizer, which is used to locate localized strings (default is `Localizer`) | ||
- not required | ||
- -o (--output) | ||
- output resx file | ||
- mandatory | ||
- -f (--file) | ||
- source file, where localized string are located | ||
- not required if -d is present | ||
- -d (--directory) | ||
- source directory, which files are enumerated and localized string are then located | ||
- not required if -f is present |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/AXSharp.tools/src/AXSharp.LocalizablesToResx/AXSharp.LocalizablesToResx.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
|
||
<!--NuGet Specific part--> | ||
<Description>Creates Resx files from localizables in a .NET project.</Description> | ||
<PackAsTool>True</PackAsTool> | ||
<ToolCommandName>ltr</ToolCommandName> | ||
|
||
<!-- NuGet Common part--> | ||
<PackageProjectUrl>https://github.com/ix-ax/</PackageProjectUrl> | ||
<RepositoryUrl>https://github.com/ix-ax/axsharp</RepositoryUrl> | ||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | ||
<Authors>ix-ax</Authors> | ||
<Copyright>(c) Peter Kurhajec and Contributors</Copyright> | ||
<PackageTags>simatix-ax, PLC, industrial automation, SCADA, HMI</PackageTags> | ||
<GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
<Title>AX# compiler CLI</Title> | ||
<PackageIcon>icon_128_128.png</PackageIcon> | ||
<RepositoryType>git</RepositoryType> | ||
<IncludeSymbols>True</IncludeSymbols> | ||
<SymbolPackageFormat>snupkg</SymbolPackageFormat> | ||
<PackageLicenseExpression>MIT</PackageLicenseExpression> | ||
<PackageReleaseNotes> | ||
Release notes are published here: | ||
https://github.com/ix-ax/axsharp/releases | ||
</PackageReleaseNotes> | ||
<PackageReadmeFile>NUGET-README.md</PackageReadmeFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="ResXResourceReader.NetStandard" Version="1.1.0" /> | ||
<PackageReference Include="CommandLineParser" Version="2.9.1" /> | ||
<PackageReference Include="GitVersion.MsBuild" Version="5.10.3"> | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Include="..\..\..\..\assets\icons\icon_128_128.png" Link="icon_128_128.png"> | ||
<PackagePath>\</PackagePath> | ||
<Pack>True</Pack> | ||
</None> | ||
<None Include="..\..\..\NUGET-README.md" Link="NUGET-README.md"> | ||
<PackagePath>\</PackagePath> | ||
<Pack>True</Pack> | ||
</None> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Update="tests\SimpleTests.razor"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
20 changes: 20 additions & 0 deletions
20
src/AXSharp.tools/src/AXSharp.LocalizablesToResx/Options.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using CommandLine; | ||
|
||
namespace AXSharp.LocalizablesToResx | ||
{ | ||
public class Options | ||
{ | ||
[Option('f', "file", Required = false, HelpText = "Source file, from which resx will be generated.")] | ||
public string? SourceFile { get; set; } | ||
|
||
[Option('d', "directory", Required = false, HelpText = "Source director, which contains files for resx gen.")] | ||
public string? SourceDirectory { get; set; } | ||
|
||
[Option('i', "identifier", Required = false, HelpText = "Localizable identifier, from which regex for searching is created. If empty, default value \"Localizer\" is used.")] | ||
public string? Identifier { get; set; } | ||
|
||
[Option('o', "output", Required = true, HelpText = "Required output resx file.")] | ||
public string? OutputResx { get; set; } | ||
|
||
} | ||
} |
161 changes: 161 additions & 0 deletions
161
src/AXSharp.tools/src/AXSharp.LocalizablesToResx/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
// See https://aka.ms/new-console-template for more information | ||
using AXSharp.LocalizablesToResx; | ||
using CommandLine; | ||
using CommandLine.Text; | ||
using System.Resources.NetStandard; | ||
using System.Text.RegularExpressions; | ||
|
||
|
||
Parser.Default.ParseArguments<Options>(args) | ||
.WithParsed(o => | ||
{ | ||
Main(o); | ||
}); | ||
|
||
|
||
|
||
void Main(Options o) | ||
{ | ||
Console.WriteLine("** ltr (LocalizablesToResx) **"); | ||
Console.WriteLine("Generator of resx file from source code based on localizable identifier."); | ||
Console.WriteLine("Generating..."); | ||
// Create a Regex | ||
ResXGen.CreateRegex(o.Identifier); | ||
|
||
// Create in memory dictionary with unique localizable values | ||
ResXGen.CreateResxDictionary(o); | ||
|
||
// Write dictionary into resx file | ||
ResXGen.WriteToResx(o.OutputResx); | ||
|
||
Console.WriteLine($"Returned {ResXGen.count} records."); | ||
Console.WriteLine($"Location: {o.OutputResx}"); | ||
Console.WriteLine("Done."); | ||
|
||
|
||
} | ||
|
||
/// <summary> | ||
/// Main static class containing logic of acquiring localized strings and generating resx file. | ||
/// </summary> | ||
public static class ResXGen | ||
{ | ||
public static uint count; | ||
public static Regex LocalizableRegex; | ||
public static Dictionary<string, string> ResxDictionary = new Dictionary<string, string>(); | ||
|
||
|
||
/// <summary> | ||
/// Create regex based on -i argument. If argument is empty, default regex "Localizer\[.*?\]" is used. | ||
/// </summary> | ||
/// <param name="identifier">Identifier used in regex</param> | ||
public static void CreateRegex(string identifier) | ||
{ | ||
string pattern; | ||
if (identifier == null) | ||
{ | ||
//use default identifier for regex | ||
pattern = @"Localizer\[.*?\]"; | ||
} | ||
else | ||
{ | ||
pattern = $@"{identifier}\[.*?\]"; | ||
} | ||
|
||
LocalizableRegex = new Regex(pattern); | ||
} | ||
|
||
/// <summary> | ||
/// Creates dictionary of values acquired from input files. | ||
/// </summary> | ||
/// <param name="o"></param> | ||
public static void CreateResxDictionary(Options o) | ||
{ | ||
if (o.SourceFile != null) | ||
{ | ||
if (!File.Exists(o.SourceFile)) | ||
{ | ||
Console.WriteLine("Source file does not exist!"); | ||
return; | ||
} | ||
else | ||
{ | ||
AddLocalizablesToDictionary(o.SourceFile); | ||
} | ||
} | ||
|
||
if (o.SourceDirectory != null) | ||
{ | ||
if (!Directory.Exists(o.SourceDirectory)) | ||
{ | ||
Console.WriteLine("Director does not exist!"); | ||
return; | ||
} | ||
else | ||
{ | ||
CreateResxDictionaryRecursive(o.SourceDirectory); | ||
} | ||
} | ||
|
||
} | ||
|
||
/// <summary> | ||
/// Writes created dictionary of localizable values into resx file. | ||
/// </summary> | ||
/// <param name="outputPath">Output path of resx file</param> | ||
public static void WriteToResx(string outputPath) | ||
{ | ||
using (ResXResourceWriter resx = new ResXResourceWriter(outputPath)) | ||
{ | ||
foreach (var item in ResxDictionary) | ||
{ | ||
resx.AddResource(item.Value, item.Value); | ||
} | ||
} | ||
} | ||
|
||
private static void CreateResxDictionaryRecursive(string sourceDir) | ||
{ | ||
foreach (string d in Directory.GetDirectories(sourceDir)) | ||
{ | ||
foreach (string f in Directory.GetFiles(d, "*.razor")) | ||
{ | ||
AddLocalizablesToDictionary(f); | ||
} | ||
|
||
CreateResxDictionaryRecursive(d); | ||
} | ||
} | ||
|
||
private static void AddLocalizablesToDictionary(string filePath) | ||
{ | ||
string ln; | ||
using (StreamReader file = new StreamReader(filePath)) | ||
{ | ||
while ((ln = file.ReadLine()) != null) | ||
{ | ||
MatchCollection matches = LocalizableRegex.Matches(ln); | ||
|
||
foreach (Match match in matches) | ||
{ | ||
var value = match.Value; | ||
|
||
string[] sp = value.Split('\"'); | ||
// get text inside [""] | ||
if (sp.Length > 1 && ResxDictionary.TryAdd(sp[1], sp[1])) | ||
{ | ||
count++; | ||
} | ||
} | ||
|
||
} | ||
file.Close(); | ||
} | ||
} | ||
|
||
|
||
} | ||
|
||
|
Oops, something went wrong.