diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3856660 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,56 @@ +# Auto detect text files and perform LF normalization +* text=auto + + +# Custom for Visual Studio +*.cs text diff=csharp eol=crlf +*.sln text merge=union eol=crlf +*.csproj text merge=union eol=crlf +*.vbproj text merge=union +*.fsproj text merge=union +*.dbproj text merge=union +*.ascx text eol=crlf +*.xaml text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf +*.coffee text eol=crlf +*.config text eol=crlf +*.css text eol=crlf +*.nuspec text eol=crlf +*.scss text eol=crlf +*.cshtml text eol=crlf +*.htm text eol=crlf +*.html text eol=crlf +*.js text eol=crlf +*.ts text eol=crlf +*.msbuild text eol=crlf +*.resx text merge=union +*.ruleset text +*.Stylecop text +*.targets text eol=crlf +*.tt text +*.txt text eol=crlf +*.vb text eol=crlf +*.vbhtml text eol=crlf +*.xml text eol=crlf +*.xunit text eol=crlf + +*.bmp binary +*.gif binary +*.ico binary +*.jpg binary +*.png binary + + + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f15e9b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,153 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Databases +*.sqlite3 + +# Build results + +[Dd]ebug/ +[Rr]elease/ +[Bb]in/ +[Oo]bj/ +[Bb]uild-[Aa]rtifacts/ + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +# !packages/*/build/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +# packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store diff --git a/ResourceMigrator.sln b/ResourceMigrator.sln new file mode 100644 index 0000000..2d2c0fd --- /dev/null +++ b/ResourceMigrator.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceMigrator", "ResourceMigrator\ResourceMigrator.csproj", "{2E82D15B-B11F-42D6-BC50-D28D73991047}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E82D15B-B11F-42D6-BC50-D28D73991047}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E82D15B-B11F-42D6-BC50-D28D73991047}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E82D15B-B11F-42D6-BC50-D28D73991047}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E82D15B-B11F-42D6-BC50-D28D73991047}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ResourceMigrator/App.config b/ResourceMigrator/App.config new file mode 100644 index 0000000..8e15646 --- /dev/null +++ b/ResourceMigrator/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ResourceMigrator/Droid.cs b/ResourceMigrator/Droid.cs new file mode 100644 index 0000000..402de06 --- /dev/null +++ b/ResourceMigrator/Droid.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace ResourceMigrator +{ + public static class Droid + { + public static void WriteToTarget(FileSystemInfo sourceFile, string targetDir, Dictionary strings) + { + var resourceType = sourceFile.GetResourceType(); + var builder = new StringBuilder(); + + builder.AppendLine(""); + builder.Append(@" + +"); + + builder.AppendLine(""); + + foreach (var key in strings.Keys) + { + builder.Append(" "); + builder.AppendLine(string.Format("<{0} name=\"{1}\">{2}", resourceType, key, strings[key].ToEscapedString())); + } + + builder.AppendLine(""); + + var outputFileName = Path.GetFileNameWithoutExtension(sourceFile.Name) + ".xml"; + File.WriteAllText(Path.Combine(targetDir, outputFileName), builder.ToString()); + } + } +} \ No newline at end of file diff --git a/ResourceMigrator/Extensions.cs b/ResourceMigrator/Extensions.cs new file mode 100644 index 0000000..782ef7e --- /dev/null +++ b/ResourceMigrator/Extensions.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; +using System.Xml; + +namespace ResourceMigrator +{ + public static class Extensions + { + public static string ToEscapedString(this string input) + { + var literal = new StringBuilder(input.Length + 2); + foreach (var c in input) + { + switch (c) + { + case '\'': literal.Append(@"\'"); break; + case '\"': literal.Append("\\\""); break; + case '\\': literal.Append(@"\\"); break; + case '\0': literal.Append(@"\0"); break; + case '\a': literal.Append(@"\a"); break; + case '\b': literal.Append(@"\b"); break; + case '\f': literal.Append(@"\f"); break; + case '\n': literal.Append(@"\n"); break; + case '\r': literal.Append(@"\r"); break; + case '\t': literal.Append(@"\t"); break; + case '\v': literal.Append(@"\v"); break; + default: + if (Char.GetUnicodeCategory(c) != UnicodeCategory.Control) + { + literal.Append(c); + } + else + { + literal.Append(@"\u"); + literal.Append(((ushort)c).ToString("x4")); + } + break; + } + } + return literal.ToString(); + } + + public static Dictionary LoadResources(this FileSystemInfo file) + { + if (file == null) throw new ArgumentNullException("file"); + var result = new Dictionary(); + + var doc = new XmlDocument(); + doc.Load(file.FullName); + + var nodes = doc.SelectNodes("//data"); + + if (nodes != null) + foreach (XmlNode node in nodes) + { + if (node.Attributes == null) continue; + var name = node.Attributes["name"].Value; + var value = node.ChildNodes[1].InnerText; + result.Add(name, value); + } + + return result; + } + + public static string GetResourceType(this FileSystemInfo fileName) + { + switch (fileName.Name.ToLower().Substring(0, Math.Min(3, fileName.Name.Length))) + { + case "col": + return "color"; + case "boo": + return "bool"; + case "dim": + return "dimen"; + case "ite": + return "item"; + case "int": + return "integer"; + default: + return "string"; + } + } + } +} \ No newline at end of file diff --git a/ResourceMigrator/Helpers.cs b/ResourceMigrator/Helpers.cs new file mode 100644 index 0000000..15904ce --- /dev/null +++ b/ResourceMigrator/Helpers.cs @@ -0,0 +1,12 @@ +using System.Reflection; + +namespace ResourceMigrator +{ + public class Helpers + { + public static string GetAssemblyVersion() + { + return Assembly.GetAssembly(typeof(Program)).GetName().Version.ToString(); + } + } +} \ No newline at end of file diff --git a/ResourceMigrator/Program.cs b/ResourceMigrator/Program.cs new file mode 100644 index 0000000..d51747b --- /dev/null +++ b/ResourceMigrator/Program.cs @@ -0,0 +1,23 @@ +using System.IO; + +// originally taken from http://stackoverflow.com/a/16987412/124069 + +namespace ResourceMigrator +{ + internal class Program + { + private static void Main(string[] args) + { + var sourceDirString = args[0]; + var androidTargetDir = args[1]; + + var sourceDir = new DirectoryInfo(sourceDirString); + + foreach (var sourceFile in sourceDir.GetFiles("*.resx")) + { + var resources = sourceFile.LoadResources(); + Droid.WriteToTarget(sourceFile, androidTargetDir, resources); + } + } + } +} \ No newline at end of file diff --git a/ResourceMigrator/Properties/AssemblyInfo.cs b/ResourceMigrator/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b86b3ae --- /dev/null +++ b/ResourceMigrator/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ResourceMigrator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ResourceMigrator")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("107d7341-7b7f-4ff9-a6f4-dc312b492793")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ResourceMigrator/ResourceMigrator.csproj b/ResourceMigrator/ResourceMigrator.csproj new file mode 100644 index 0000000..765fa87 --- /dev/null +++ b/ResourceMigrator/ResourceMigrator.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {2E82D15B-B11F-42D6-BC50-D28D73991047} + Exe + Properties + ResourceMigrator + ResourceMigrator + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..821b228 --- /dev/null +++ b/readme.md @@ -0,0 +1,22 @@ +Cross platform way to migrate PCL Resources over to Android Resources + +Put all of your resources in a PCL *.resx file, and run this with your build. It will automatically +generate your *.xml resource file for android + +Future Plans: to generate CustomUIColors for iOS. + +note: start your file name with the type of resource you're generating + +IE: + + bools.resx // will generate bool resources + dimensions.resx // will generate dimen resources + integers.resx // will generate int resources + colors.resx // will generate color resources + items.resx // will generate item resources + foo-bar.resx // will generate string resources + +Usage: + + ResourceMigrator.exe /path/to/pcl/resource/dir /my-android-app/resources/values/ +